memcached-1.4.14/0000755000175000017500000000000012005572440010507 500000000000000memcached-1.4.14/Makefile.am0000644000175000017500000000623011701635506012471 00000000000000bin_PROGRAMS = memcached pkginclude_HEADERS = protocol_binary.h noinst_PROGRAMS = memcached-debug sizes testapp timedrun BUILT_SOURCES= testapp_SOURCES = testapp.c util.c util.h timedrun_SOURCES = timedrun.c memcached_SOURCES = memcached.c memcached.h \ hash.c hash.h \ slabs.c slabs.h \ items.c items.h \ assoc.c assoc.h \ thread.c daemon.c \ stats.c stats.h \ util.c util.h \ trace.h cache.h sasl_defs.h if BUILD_CACHE memcached_SOURCES += cache.c testapp_SOURCES += cache.c endif if BUILD_SOLARIS_PRIVS memcached_SOURCES += solaris_priv.c endif if ENABLE_SASL memcached_SOURCES += sasl_defs.c endif memcached_debug_SOURCES = $(memcached_SOURCES) memcached_CPPFLAGS = -DNDEBUG memcached_debug_LDADD = @PROFILER_LDFLAGS@ memcached_debug_CFLAGS = @PROFILER_FLAGS@ memcached_LDADD = memcached_DEPENDENCIES = memcached_debug_DEPENDENCIES = CLEANFILES= if BUILD_DTRACE BUILT_SOURCES += memcached_dtrace.h CLEANFILES += memcached_dtrace.h endif if DTRACE_INSTRUMENT_OBJ memcached_LDADD += memcached_dtrace.o memcached_DEPENDENCIES += memcached_dtrace.o memcached_debug_LDADD += memcached_debug_dtrace.o memcached_debug_DEPENDENCIES += memcached_debug_dtrace.o CLEANFILES += memcached_dtrace.o memcached_debug_dtrace.o endif memcached_dtrace.h: memcached_dtrace.d ${DTRACE} -h -s memcached_dtrace.d sed -e 's,void \*,const void \*,g' memcached_dtrace.h | \ sed -e 's,char \*,const char \*,g' | tr '\t' ' ' > mmc_dtrace.tmp mv mmc_dtrace.tmp memcached_dtrace.h memcached_dtrace.o: $(memcached_OBJECTS) $(DTRACE) $(DTRACEFLAGS) -G -o memcached_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_OBJECTS) memcached_debug_dtrace.o: $(memcached_debug_OBJECTS) $(DTRACE) $(DTRACEFLAGS) -G -o memcached_debug_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_debug_OBJECTS) SUBDIRS = doc DIST_DIRS = scripts EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 MOSTLYCLEANFILES = *.gcov *.gcno *.gcda *.tcov test: memcached-debug sizes testapp $(srcdir)/sizes $(srcdir)/testapp prove $(srcdir)/t @if test `basename $(PROFILER)` = "gcov"; then \ for file in memcached_debug-*.gc??; do \ mv -f $$file `echo $$file | sed 's/memcached_debug-//'`; \ done && \ for file in *.gcda; do \ srcfile=`echo $$file | sed 's/.gcda/.c/'`; \ if test -n "`echo $(memcached_debug_SOURCES) | grep $$srcfile`"; then \ echo `$(PROFILER) $$srcfile` | sed 's/'$$srcfile':.*//'; \ fi \ done \ elif test `basename $(PROFILER)` = "tcov"; then \ files=`grep SRCFILE memcached-debug.profile/tcovd | sed 's/SRCFILE://' | sort | uniq` && \ $(PROFILER) -x memcached-debug.profile $$files 2>&1; \ for file in *.tcov; do \ srcfile=`echo $$file | sed 's/.tcov//'`; \ if test -n "`echo $(memcached_debug_SOURCES) | grep $$srcfile`"; then \ echo $$srcfile : `grep 'Percent of the file executed' $$file`; \ fi \ done \ else :; fi docs: (cat Doxyfile ; echo "PROJECT_NUMBER=`cat version.num`") | doxygen - dist-hook: rm -f $(distdir)/*/*~ $(distdir)/t/lib/*~ $(distdir)/*~ memcached-1.4.14/trace.h0000644000175000017500000000615311701635506011710 00000000000000#ifndef TRACE_H #define TRACE_H #ifdef ENABLE_DTRACE #include "memcached_dtrace.h" #else #define MEMCACHED_ASSOC_DELETE(arg0, arg1, arg2) #define MEMCACHED_ASSOC_DELETE_ENABLED() (0) #define MEMCACHED_ASSOC_FIND(arg0, arg1, arg2) #define MEMCACHED_ASSOC_FIND_ENABLED() (0) #define MEMCACHED_ASSOC_INSERT(arg0, arg1, arg2) #define MEMCACHED_ASSOC_INSERT_ENABLED() (0) #define MEMCACHED_COMMAND_ADD(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_ADD_ENABLED() (0) #define MEMCACHED_COMMAND_APPEND(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_APPEND_ENABLED() (0) #define MEMCACHED_COMMAND_CAS(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_CAS_ENABLED() (0) #define MEMCACHED_COMMAND_DECR(arg0, arg1, arg2, arg3) #define MEMCACHED_COMMAND_DECR_ENABLED() (0) #define MEMCACHED_COMMAND_DELETE(arg0, arg1, arg2) #define MEMCACHED_COMMAND_DELETE_ENABLED() (0) #define MEMCACHED_COMMAND_GET(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_GET_ENABLED() (0) #define MEMCACHED_COMMAND_TOUCH(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_TOUCH_ENABLED() (0) #define MEMCACHED_COMMAND_INCR(arg0, arg1, arg2, arg3) #define MEMCACHED_COMMAND_INCR_ENABLED() (0) #define MEMCACHED_COMMAND_PREPEND(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_PREPEND_ENABLED() (0) #define MEMCACHED_COMMAND_REPLACE(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_REPLACE_ENABLED() (0) #define MEMCACHED_COMMAND_SET(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_SET_ENABLED() (0) #define MEMCACHED_CONN_ALLOCATE(arg0) #define MEMCACHED_CONN_ALLOCATE_ENABLED() (0) #define MEMCACHED_CONN_CREATE(arg0) #define MEMCACHED_CONN_CREATE_ENABLED() (0) #define MEMCACHED_CONN_DESTROY(arg0) #define MEMCACHED_CONN_DESTROY_ENABLED() (0) #define MEMCACHED_CONN_DISPATCH(arg0, arg1) #define MEMCACHED_CONN_DISPATCH_ENABLED() (0) #define MEMCACHED_CONN_RELEASE(arg0) #define MEMCACHED_CONN_RELEASE_ENABLED() (0) #define MEMCACHED_ITEM_LINK(arg0, arg1, arg2) #define MEMCACHED_ITEM_LINK_ENABLED() (0) #define MEMCACHED_ITEM_REMOVE(arg0, arg1, arg2) #define MEMCACHED_ITEM_REMOVE_ENABLED() (0) #define MEMCACHED_ITEM_REPLACE(arg0, arg1, arg2, arg3, arg4, arg5) #define MEMCACHED_ITEM_REPLACE_ENABLED() (0) #define MEMCACHED_ITEM_UNLINK(arg0, arg1, arg2) #define MEMCACHED_ITEM_UNLINK_ENABLED() (0) #define MEMCACHED_ITEM_UPDATE(arg0, arg1, arg2) #define MEMCACHED_ITEM_UPDATE_ENABLED() (0) #define MEMCACHED_PROCESS_COMMAND_END(arg0, arg1, arg2) #define MEMCACHED_PROCESS_COMMAND_END_ENABLED() (0) #define MEMCACHED_PROCESS_COMMAND_START(arg0, arg1, arg2) #define MEMCACHED_PROCESS_COMMAND_START_ENABLED() (0) #define MEMCACHED_SLABS_ALLOCATE(arg0, arg1, arg2, arg3) #define MEMCACHED_SLABS_ALLOCATE_ENABLED() (0) #define MEMCACHED_SLABS_ALLOCATE_FAILED(arg0, arg1) #define MEMCACHED_SLABS_ALLOCATE_FAILED_ENABLED() (0) #define MEMCACHED_SLABS_FREE(arg0, arg1, arg2) #define MEMCACHED_SLABS_FREE_ENABLED() (0) #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE(arg0) #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_ENABLED() (0) #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(arg0) #define MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED_ENABLED() (0) #endif #endif memcached-1.4.14/config.guess0000755000175000017500000013105411274160642012757 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. timestamp='2009-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd | genuineintel) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: memcached-1.4.14/cache.c0000644000175000017500000000726512005345144011647 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include #include #include #ifndef NDEBUG #include #endif #include "cache.h" #ifndef NDEBUG const uint64_t redzone_pattern = 0xdeadbeefcafebabe; int cache_error = 0; #endif const int initial_pool_size = 64; cache_t* cache_create(const char *name, size_t bufsize, size_t align, cache_constructor_t* constructor, cache_destructor_t* destructor) { cache_t* ret = calloc(1, sizeof(cache_t)); char* nm = strdup(name); void** ptr = calloc(initial_pool_size, sizeof(void*)); if (ret == NULL || nm == NULL || ptr == NULL || pthread_mutex_init(&ret->mutex, NULL) == -1) { free(ret); free(nm); free(ptr); return NULL; } ret->name = nm; ret->ptr = ptr; ret->freetotal = initial_pool_size; ret->constructor = constructor; ret->destructor = destructor; #ifndef NDEBUG ret->bufsize = bufsize + 2 * sizeof(redzone_pattern); #else ret->bufsize = bufsize; #endif return ret; } static inline void* get_object(void *ptr) { #ifndef NDEBUG uint64_t *pre = ptr; return pre + 1; #else return ptr; #endif } void cache_destroy(cache_t *cache) { while (cache->freecurr > 0) { void *ptr = cache->ptr[--cache->freecurr]; if (cache->destructor) { cache->destructor(get_object(ptr), NULL); } free(ptr); } free(cache->name); free(cache->ptr); pthread_mutex_destroy(&cache->mutex); free(cache); } void* cache_alloc(cache_t *cache) { void *ret; void *object; pthread_mutex_lock(&cache->mutex); if (cache->freecurr > 0) { ret = cache->ptr[--cache->freecurr]; object = get_object(ret); } else { object = ret = malloc(cache->bufsize); if (ret != NULL) { object = get_object(ret); if (cache->constructor != NULL && cache->constructor(object, NULL, 0) != 0) { free(ret); object = NULL; } } } pthread_mutex_unlock(&cache->mutex); #ifndef NDEBUG if (object != NULL) { /* add a simple form of buffer-check */ uint64_t *pre = ret; *pre = redzone_pattern; ret = pre+1; memcpy(((char*)ret) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern, sizeof(redzone_pattern)); } #endif return object; } void cache_free(cache_t *cache, void *ptr) { pthread_mutex_lock(&cache->mutex); #ifndef NDEBUG /* validate redzone... */ if (memcmp(((char*)ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern, sizeof(redzone_pattern)) != 0) { raise(SIGABRT); cache_error = 1; pthread_mutex_unlock(&cache->mutex); return; } uint64_t *pre = ptr; --pre; if (*pre != redzone_pattern) { raise(SIGABRT); cache_error = -1; pthread_mutex_unlock(&cache->mutex); return; } ptr = pre; #endif if (cache->freecurr < cache->freetotal) { cache->ptr[cache->freecurr++] = ptr; } else { /* try to enlarge free connections array */ size_t newtotal = cache->freetotal * 2; void **new_free = realloc(cache->ptr, sizeof(char *) * newtotal); if (new_free) { cache->freetotal = newtotal; cache->ptr = new_free; cache->ptr[cache->freecurr++] = ptr; } else { if (cache->destructor) { cache->destructor(ptr, NULL); } free(ptr); } } pthread_mutex_unlock(&cache->mutex); } memcached-1.4.14/util.c0000644000175000017500000000634211701635506011562 00000000000000#include #include #include #include #include #include #include #include "memcached.h" /* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */ #define xisspace(c) isspace((unsigned char)c) bool safe_strtoull(const char *str, uint64_t *out) { assert(out != NULL); errno = 0; *out = 0; char *endptr; unsigned long long ull = strtoull(str, &endptr, 10); if ((errno == ERANGE) || (str == endptr)) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { if ((long long) ull < 0) { /* only check for negative signs in the uncommon case when * the unsigned number is so big that it's negative as a * signed number. */ if (strchr(str, '-') != NULL) { return false; } } *out = ull; return true; } return false; } bool safe_strtoll(const char *str, int64_t *out) { assert(out != NULL); errno = 0; *out = 0; char *endptr; long long ll = strtoll(str, &endptr, 10); if ((errno == ERANGE) || (str == endptr)) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { *out = ll; return true; } return false; } bool safe_strtoul(const char *str, uint32_t *out) { char *endptr = NULL; unsigned long l = 0; assert(out); assert(str); *out = 0; errno = 0; l = strtoul(str, &endptr, 10); if ((errno == ERANGE) || (str == endptr)) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { if ((long) l < 0) { /* only check for negative signs in the uncommon case when * the unsigned number is so big that it's negative as a * signed number. */ if (strchr(str, '-') != NULL) { return false; } } *out = l; return true; } return false; } bool safe_strtol(const char *str, int32_t *out) { assert(out != NULL); errno = 0; *out = 0; char *endptr; long l = strtol(str, &endptr, 10); if ((errno == ERANGE) || (str == endptr)) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { *out = l; return true; } return false; } void vperror(const char *fmt, ...) { int old_errno = errno; char buf[1024]; va_list ap; va_start(ap, fmt); if (vsnprintf(buf, sizeof(buf), fmt, ap) == -1) { buf[sizeof(buf) - 1] = '\0'; } va_end(ap); errno = old_errno; perror(buf); } #ifndef HAVE_HTONLL static uint64_t mc_swap64(uint64_t in) { #ifdef ENDIAN_LITTLE /* Little endian, flip the bytes around until someone makes a faster/better * way to do this. */ int64_t rv = 0; int i = 0; for(i = 0; i<8; i++) { rv = (rv << 8) | (in & 0xff); in >>= 8; } return rv; #else /* big-endian machines don't need byte swapping */ return in; #endif } uint64_t ntohll(uint64_t val) { return mc_swap64(val); } uint64_t htonll(uint64_t val) { return mc_swap64(val); } #endif memcached-1.4.14/assoc.c0000644000175000017500000001752112005566347011722 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Hash table * * The hash function used here is by Bob Jenkins, 1996: * * "By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. * You may use this code any way you wish, private, educational, * or commercial. It's free." * * The rest of the file is licensed under the BSD license. See LICENSE. */ #include "memcached.h" #include #include #include #include #include #include #include #include #include #include #include #include static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER; typedef unsigned long int ub4; /* unsigned 4-byte quantities */ typedef unsigned char ub1; /* unsigned 1-byte quantities */ /* how many powers of 2's worth of buckets we use */ static unsigned int hashpower = HASHPOWER_DEFAULT; #define hashsize(n) ((ub4)1<<(n)) #define hashmask(n) (hashsize(n)-1) /* Main hash table. This is where we look except during expansion. */ static item** primary_hashtable = 0; /* * Previous hash table. During expansion, we look here for keys that haven't * been moved over to the primary yet. */ static item** old_hashtable = 0; /* Number of items in the hash table. */ static unsigned int hash_items = 0; /* Flag: Are we in the middle of expanding now? */ static bool expanding = false; /* * During expansion we migrate values with bucket granularity; this is how * far we've gotten so far. Ranges from 0 .. hashsize(hashpower - 1) - 1. */ static unsigned int expand_bucket = 0; void assoc_init(const int hashtable_init) { if (hashtable_init) { hashpower = hashtable_init; } primary_hashtable = calloc(hashsize(hashpower), sizeof(void *)); if (! primary_hashtable) { fprintf(stderr, "Failed to init hashtable.\n"); exit(EXIT_FAILURE); } STATS_LOCK(); stats.hash_power_level = hashpower; stats.hash_bytes = hashsize(hashpower) * sizeof(void *); STATS_UNLOCK(); } item *assoc_find(const char *key, const size_t nkey, const uint32_t hv) { item *it; unsigned int oldbucket; if (expanding && (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket) { it = old_hashtable[oldbucket]; } else { it = primary_hashtable[hv & hashmask(hashpower)]; } item *ret = NULL; int depth = 0; while (it) { if ((nkey == it->nkey) && (memcmp(key, ITEM_key(it), nkey) == 0)) { ret = it; break; } it = it->h_next; ++depth; } MEMCACHED_ASSOC_FIND(key, nkey, depth); return ret; } /* returns the address of the item pointer before the key. if *item == 0, the item wasn't found */ static item** _hashitem_before (const char *key, const size_t nkey, const uint32_t hv) { item **pos; unsigned int oldbucket; if (expanding && (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket) { pos = &old_hashtable[oldbucket]; } else { pos = &primary_hashtable[hv & hashmask(hashpower)]; } while (*pos && ((nkey != (*pos)->nkey) || memcmp(key, ITEM_key(*pos), nkey))) { pos = &(*pos)->h_next; } return pos; } /* grows the hashtable to the next power of 2. */ static void assoc_expand(void) { old_hashtable = primary_hashtable; primary_hashtable = calloc(hashsize(hashpower + 1), sizeof(void *)); if (primary_hashtable) { if (settings.verbose > 1) fprintf(stderr, "Hash table expansion starting\n"); hashpower++; expanding = true; expand_bucket = 0; STATS_LOCK(); stats.hash_power_level = hashpower; stats.hash_bytes += hashsize(hashpower) * sizeof(void *); stats.hash_is_expanding = 1; STATS_UNLOCK(); pthread_cond_signal(&maintenance_cond); } else { primary_hashtable = old_hashtable; /* Bad news, but we can keep running. */ } } /* Note: this isn't an assoc_update. The key must not already exist to call this */ int assoc_insert(item *it, const uint32_t hv) { unsigned int oldbucket; // assert(assoc_find(ITEM_key(it), it->nkey) == 0); /* shouldn't have duplicately named things defined */ if (expanding && (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket) { it->h_next = old_hashtable[oldbucket]; old_hashtable[oldbucket] = it; } else { it->h_next = primary_hashtable[hv & hashmask(hashpower)]; primary_hashtable[hv & hashmask(hashpower)] = it; } hash_items++; if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2) { assoc_expand(); } MEMCACHED_ASSOC_INSERT(ITEM_key(it), it->nkey, hash_items); return 1; } void assoc_delete(const char *key, const size_t nkey, const uint32_t hv) { item **before = _hashitem_before(key, nkey, hv); if (*before) { item *nxt; hash_items--; /* The DTrace probe cannot be triggered as the last instruction * due to possible tail-optimization by the compiler */ MEMCACHED_ASSOC_DELETE(key, nkey, hash_items); nxt = (*before)->h_next; (*before)->h_next = 0; /* probably pointless, but whatever. */ *before = nxt; return; } /* Note: we never actually get here. the callers don't delete things they can't find. */ assert(*before != 0); } static volatile int do_run_maintenance_thread = 1; #define DEFAULT_HASH_BULK_MOVE 1 int hash_bulk_move = DEFAULT_HASH_BULK_MOVE; static void *assoc_maintenance_thread(void *arg) { while (do_run_maintenance_thread) { int ii = 0; /* Lock the cache, and bulk move multiple buckets to the new * hash table. */ mutex_lock(&cache_lock); for (ii = 0; ii < hash_bulk_move && expanding; ++ii) { item *it, *next; int bucket; for (it = old_hashtable[expand_bucket]; NULL != it; it = next) { next = it->h_next; bucket = hash(ITEM_key(it), it->nkey, 0) & hashmask(hashpower); it->h_next = primary_hashtable[bucket]; primary_hashtable[bucket] = it; } old_hashtable[expand_bucket] = NULL; expand_bucket++; if (expand_bucket == hashsize(hashpower - 1)) { expanding = false; free(old_hashtable); STATS_LOCK(); stats.hash_bytes -= hashsize(hashpower - 1) * sizeof(void *); stats.hash_is_expanding = 0; STATS_UNLOCK(); if (settings.verbose > 1) fprintf(stderr, "Hash table expansion done\n"); } } if (!expanding) { /* We are done expanding.. just wait for next invocation */ pthread_cond_wait(&maintenance_cond, &cache_lock); } mutex_unlock(&cache_lock); } return NULL; } static pthread_t maintenance_tid; int start_assoc_maintenance_thread() { int ret; char *env = getenv("MEMCACHED_HASH_BULK_MOVE"); if (env != NULL) { hash_bulk_move = atoi(env); if (hash_bulk_move == 0) { hash_bulk_move = DEFAULT_HASH_BULK_MOVE; } } if ((ret = pthread_create(&maintenance_tid, NULL, assoc_maintenance_thread, NULL)) != 0) { fprintf(stderr, "Can't create thread: %s\n", strerror(ret)); return -1; } return 0; } void stop_assoc_maintenance_thread() { mutex_lock(&cache_lock); do_run_maintenance_thread = 0; pthread_cond_signal(&maintenance_cond); mutex_unlock(&cache_lock); /* Wait for the maintenance thread to stop */ pthread_join(maintenance_tid, NULL); } memcached-1.4.14/scripts/0000755000175000017500000000000012005341254012173 500000000000000memcached-1.4.14/scripts/memcached-tool0000755000175000017500000001027411640750600014731 00000000000000#!/usr/bin/perl # # memcached-tool: # stats/management tool for memcached. # # Author: # Brad Fitzpatrick # # License: # public domain. I give up all rights to this # tool. modify and copy at will. # use strict; use IO::Socket::INET; my $addr = shift; my $mode = shift || "display"; my ($from, $to); if ($mode eq "display") { undef $mode if @ARGV; } elsif ($mode eq "move") { $from = shift; $to = shift; undef $mode if $from < 6 || $from > 17; undef $mode if $to < 6 || $to > 17; print STDERR "ERROR: parameters out of range\n\n" unless $mode; } elsif ($mode eq 'dump') { ; } elsif ($mode eq 'stats') { ; } else { undef $mode; } undef $mode if @ARGV; die "Usage: memcached-tool [mode]\n memcached-tool 10.0.0.5:11211 display # shows slabs memcached-tool 10.0.0.5:11211 # same. (default is display) memcached-tool 10.0.0.5:11211 stats # shows general stats memcached-tool 10.0.0.5:11211 dump # dumps keys and values " unless $addr && $mode; my $sock; if ($addr =~ m:/:) { $sock = IO::Socket::UNIX->new( Peer => $addr, ); } else { $addr .= ':11211' unless $addr =~ /:\d+$/; $sock = IO::Socket::INET->new( PeerAddr => $addr, Proto => 'tcp', ); } die "Couldn't connect to $addr\n" unless $sock; if ($mode eq 'dump') { my %items; my $totalitems; print $sock "stats items\r\n"; while (<$sock>) { last if /^END/; if (/^STAT items:(\d*):number (\d*)/) { $items{$1} = $2; $totalitems += $2; } } print STDERR "Dumping memcache contents\n"; print STDERR " Number of buckets: " . scalar(keys(%items)) . "\n"; print STDERR " Number of items : $totalitems\n"; foreach my $bucket (sort(keys(%items))) { print STDERR "Dumping bucket $bucket - " . $items{$bucket} . " total items\n"; print $sock "stats cachedump $bucket $items{$bucket}\r\n"; my %keyexp; while (<$sock>) { last if /^END/; # return format looks like this # ITEM foo [6 b; 1176415152 s] if (/^ITEM (\S+) \[.* (\d+) s\]/) { $keyexp{$1} = $2; } } foreach my $k (keys(%keyexp)) { print $sock "get $k\r\n"; my $response = <$sock>; if ($response =~ /VALUE (\S+) (\d+) (\d+)/) { my $flags = $2; my $len = $3; my $val; read $sock, $val, $len; print "add $k $flags $keyexp{$k} $len\r\n$val\r\n"; # get the END $_ = <$sock>; $_ = <$sock>; } } } exit; } if ($mode eq 'stats') { my %items; print $sock "stats\r\n"; while (<$sock>) { last if /^END/; chomp; if (/^STAT\s+(\S*)\s+(.*)/) { $items{$1} = $2; } } printf ("#%-17s %5s %11s\n", $addr, "Field", "Value"); foreach my $name (sort(keys(%items))) { printf ("%24s %12s\n", $name, $items{$name}); } exit; } # display mode: my %items; # class -> { number, age, chunk_size, chunks_per_page, # total_pages, total_chunks, used_chunks, # free_chunks, free_chunks_end } print $sock "stats items\r\n"; my $max = 0; while (<$sock>) { last if /^END/; if (/^STAT items:(\d+):(\w+) (\d+)/) { $items{$1}{$2} = $3; $max = $1; } } print $sock "stats slabs\r\n"; while (<$sock>) { last if /^END/; if (/^STAT (\d+):(\w+) (\d+)/) { $items{$1}{$2} = $3; } } print " # Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM\n"; foreach my $n (1..$max) { my $it = $items{$n}; next if (0 == $it->{total_pages}); my $size = $it->{chunk_size} < 1024 ? "$it->{chunk_size}B" : sprintf("%.1fK", $it->{chunk_size} / 1024.0); my $full = $it->{free_chunks_end} == 0 ? "yes" : " no"; printf("%3d %8s %9ds %7d %7d %7s %8d %8d %4d\n", $n, $size, $it->{age}, $it->{total_pages}, $it->{number}, $full, $it->{evicted}, $it->{evicted_time}, $it->{outofmemory}); } memcached-1.4.14/scripts/damemtop.yaml0000644000175000017500000000044611446413300014611 00000000000000delay: 3 mode: t top_mode: sort_column: "hostname" sort_order: "asc" columns: - hostname - all_version - all_fill_rate - hit_rate - evictions - bytes_written - "2:get_hits" servers: - 127.0.0.1:11211 - 127.0.0.2:11211 memcached-1.4.14/scripts/mc_slab_mover0000755000175000017500000001720411702467341014666 00000000000000#! /usr/bin/perl # See memcached for LICENSE # Copyright 2011 Dormando (dormando@rydia.net) =head1 NAME mc_slab_mover -- example utility for slab page reassignment for memcached =head1 SYNOPSIS $ mc_slab_mover --host="127.0.0.1:11211" --verbose $ mc_slab_mover --host="127.0.0.1:11211" --automove $ mc_slab_mover --host="127.0.0.1:11211" --sleep=60 --loops=4 --automove =head1 DESCRIPTION This utility is an example implementation of an algorithm for reassigning slab memory in a running memcached instance. If memcached's built-in automover isn't working for you, you may use this script as an example base and expand on it. We welcome modifications or alternatives on the mailing list. =head1 ALGORITHM The default algorithm is simple, and may serve for a common case: over time one slab may grow in use compare to others, and as evictions stop in one slab and start in another it will reassign memory. If a slab has the most evictions three times in a row, it will pull a page from a slab which has had zero evictions three times in a row. There are many traffic patterns where this does not work well. IE: If you never use expirations and rely on the LRU (so all slabs always evict), it will not be as likely to find source pages to move. =head1 OPTIONS =over =item --host="IP:PORT" The hostname to connect to. NOTE: If connection to the host breaks, script will stop. =item --sleep=10 How long to wait between loops for gathering stats. =item --loops=3 How many loops to run before making a decision for a move. =item --verbose Prints a formatted dump of some common statistics per loop. =item --automove Enables the automover, and will attempt to move memory around if it finds viable candidates. =back =head1 AUTHOR Dormando ELE =head1 LICENSE Licensed for use and redistribution under the same terms as Memcached itself. =cut use warnings; use strict; use IO::Socket::INET; use FindBin; use Data::Dumper qw/Dumper/; use Getopt::Long; my %opts = ('sleep' => 10, automove => 0, verbose => 0, loops => 3); GetOptions( "host=s" => \$opts{host}, "sleep=i" => \$opts{'sleep'}, "loops=i" => \$opts{loops}, "automove" => \$opts{automove}, "verbose" => \$opts{verbose}, ) or usage(); die "Must specify at least --host='127.0.0.1:11211'" unless $opts{host}; my $sock = IO::Socket::INET->new(PeerAddr => $opts{host}, Timeout => 3); die "$!\n" unless $sock; my %stats = (); my %move = (winner => 0, wins => 0); $SIG{INT} = sub { print "STATS: ", Dumper(\%stats), "\n"; exit; }; $SIG{USR1} = sub { print "STATS: ", Dumper(\%stats), "\n"; }; run(); sub usage { print qq{Usage: mc_slab_ratios --host="127.0.0.1:11211" --verbose --automove run `perldoc mc_slab_ratios` for full information }; exit 1; } sub run { my $slabs_before = grab_stats(); while (1) { sleep $opts{'sleep'}; my $slabs_after = grab_stats(); my ($totals, $sorted) = calc_results_evicted($slabs_before, $slabs_after); # my ($totals, $sorted) = calc_results_numratio($slabs_before, $slabs_after); my $pct = sub { my ($num, $divisor) = @_; return 0 unless $divisor; return ($num / $divisor); }; if ($opts{verbose}) { printf " %02s: %-8s (pct ) %-10s (pct ) %-6s (pct ) get_hits (pct ) cmd_set (pct )\n", 'sb', 'evicted', 'items', 'pages'; for my $slab (@$sorted) { printf " %02d: %-8d (%.2f%%) %-10s (%.4f%%) %-6d (%.2f%%) %-8d (%.3f%%) %-7d (%.2f%%)\n", $slab->{slab}, $slab->{evicted_d}, $pct->($slab->{evicted_d}, $totals->{evicted_d}), $slab->{number}, $pct->($slab->{number}, $totals->{number}), $slab->{total_pages}, $pct->($slab->{total_pages}, $totals->{total_pages}), $slab->{get_hits_d}, $pct->($slab->{get_hits_d}, $totals->{get_hits_d}), $slab->{cmd_set_d}, $pct->($slab->{cmd_set_d}, $totals->{cmd_set_d}); } } next unless @$sorted; my $highest = $sorted->[-1]; $stats{$highest->{slab}}++; print " (winner: ", $highest->{slab}, " wins: ", $stats{$highest->{slab}}, ")\n"; automove_basic($totals, $sorted) if ($opts{automove}); $slabs_before = $slabs_after; } } sub grab_stats { my %slabs = (); for my $stat (qw/items slabs/) { print $sock "stats $stat\r\n"; while (my $line = <$sock>) { chomp $line; last if ($line =~ m/^END/); if ($line =~ m/^STAT (?:items:)?(\d+):(\S+) (\S+)/) { my ($slab, $var, $val) = ($1, $2, $3); $slabs{$slab}->{$var} = $val; } } } return \%slabs; } # Really stupid algo, same as the initial algo built into memcached. # If a slab "wins" most evictions 3 times in a row, pick from a slab which # has had 0 evictions 3 times in a row and move it over. sub automove_basic { my ($totals, $sorted) = @_; my $source = 0; my $dest = 0; my $high = $sorted->[-1]; return unless $high->{evicted_d} > 0; if ($move{winner} == $high->{slab}) { $move{wins}++; $dest = $move{winner} if $move{wins} >= $opts{loops}; } else { $move{wins} = 1; $move{winner} = $high->{slab}; } for my $slab (@$sorted) { my $id = $slab->{slab}; if ($slab->{evicted_d} == 0 && $slab->{total_pages} > 2) { $move{zeroes}->{$id}++; $source = $id if (!$source && $move{zeroes}->{$id} >= $opts{loops}); } else { delete $move{zeroes}->{$slab->{slab}} if exists $move{zeroes}->{$slab->{slab}}; } } if ($source && $dest) { print " slabs reassign $source $dest\n"; print $sock "slabs reassign $source $dest\r\n"; my $res = <$sock>; print " RES: ", $res; } elsif ($dest && !$source) { print "FAIL: want to move memory to $dest but no valid source slab available\n"; } } # Using just the evicted stats. sub calc_results_evicted { my ($slabs, $totals) = calc_slabs(@_); my @sorted = sort { $a->{evicted_d} <=> $b->{evicted_d} } values %$slabs; return ($totals, \@sorted); } # Weighted ratios of evictions vs total stored items # Seems to fail as an experiment, but it tries to weight stats. # In this case evictions in underused classes tend to get vastly inflated sub calc_results_numratio { my ($slabs, $totals) = calc_slabs(@_, sub { my ($sb, $sa, $s) = @_; if ($s->{evicted_d}) { $s->{numratio} = $s->{evicted_d} / $s->{number}; } else { $s->{numratio} = 0; } }); my @sorted = sort { $a->{numratio} <=> $b->{numratio} } values %$slabs; return ($totals, \@sorted); } sub calc_slabs { my ($slabs_before, $slabs_after, $code) = @_; my %slabs = (); my %totals = (); for my $id (keys %$slabs_after) { my $sb = $slabs_before->{$id}; my $sa = $slabs_after->{$id}; next unless ($sb && $sa); my %slab = %$sa; for my $key (keys %slab) { # Add totals, diffs if ($slab{$key} =~ m/^\d+$/) { $totals{$key} += $slab{$key}; $slab{$key . '_d'} = $sa->{$key} - $sb->{$key}; $totals{$key . '_d'} += $sa->{$key} - $sb->{$key}; } } # External code $code->($sb, $sa, \%slab) if $code; $slab{slab} = $id; $slabs{$id} = \%slab; } return (\%slabs, \%totals); } memcached-1.4.14/scripts/README.damemtop0000644000175000017500000000117611446413300014605 00000000000000dormando's awesome memcached top A flexible 'top' like utility for viewing memcached clusters. Under development. Latest code is available at: http://github.com/dormando/damemtop See --help for full information. Requires 'AnyEvent', and 'YAML' libraries from CPAN: http://search.cpan.org/ 'AnyEvent' depends on 'common::sense' (also at CPAN). If you have a large cluster and want higher performance, find and install 'EV' from CPAN. AnyEvent will automagically use it and use epoll, kqeueue, etc, for socket handling. Pester me for questions/bugs/ideas. As of writing the util is in early release and missing many future features. memcached-1.4.14/scripts/damemtop0000755000175000017500000003702311446413300013654 00000000000000#!/usr/bin/perl # dormando's awesome memcached top utility! # # Copyright 2009 Dormando (dormando@rydia.net). All rights reserved. # # Use and distribution licensed under the BSD license. See # the COPYING file for full text. use strict; use warnings FATAL => 'all'; use AnyEvent; use AnyEvent::Socket; use AnyEvent::Handle; use Getopt::Long; use YAML qw/Dump Load LoadFile/; use Term::ReadKey qw/ReadMode ReadKey GetTerminalSize/; our $VERSION = '0.1'; my $CLEAR = `clear`; my @TERM_SIZE = (); $|++; my %opts = (); GetOptions(\%opts, 'help|h', 'config=s'); if ($opts{help}) { show_help(); exit; } $SIG{INT} = sub { ReadMode('normal'); print "\n"; exit; }; # TODO: make this load from central location, and merge in homedir changes. # then merge Getopt::Long stuff on top of that # TODO: Set a bunch of defaults and merge in. my $CONF = load_config(); my %CONS = (); my $LAST_RUN = time; # time after the last loop cycle. my $TIME_SINCE_LAST_RUN = time; # time since last loop cycle. my $loop_timer; my $main_cond; my $prev_stats_results; my %display_modes = ( 't' => \&display_top_mode, '?' => \&display_help_mode, 'h' => \&display_help_mode, ); my %column_compute = ( 'hostname' => { stats => [], code => \&compute_hostname}, 'hit_rate' => { stats => ['get_hits', 'get_misses'], code => \&compute_hit_rate }, 'fill_rate' => { stats => ['bytes', 'limit_maxbytes'], code => \&compute_fill_rate }, ); my %column_format = ( 'hit_rate' => \&format_percent, 'fill_rate' => \&format_percent, ); # This can collapse into %column_compute my %column_format_totals = ( 'hit_rate' => 0, 'fill_rate' => 0, ); ReadMode('cbreak'); my $LAST_KEY = ''; my $read_keys = AnyEvent->io ( fh => \*STDIN, poll => 'r', cb => sub { $LAST_KEY = ReadKey(-1); # If there is a running timer, cancel it. # Don't want to interrupt a main loop run. # fire_main_loop()'s iteration will pick up the keypress. if ($loop_timer) { $loop_timer = undef; $main_cond->send; } } ); # start main loop fire_main_loop(); ### AnyEvent related code. sub fire_main_loop { for (;;) { $loop_timer = undef; $main_cond = AnyEvent->condvar; my $time_taken = main_loop(); my $delay = $CONF->{delay} - $time_taken; $delay = 0 if $delay < 0; $loop_timer = AnyEvent->timer( after => $delay, cb => $main_cond, ); $main_cond->recv; } } sub main_loop { my $start = AnyEvent->now; # use ->time to find the end. maintain_connections(); my $cv = AnyEvent->condvar; # FIXME: Need to dump early if there're no connected conns # FIXME: Make this only fetch stats from cons we care to visualize? # maybe keep everything anyway to maintain averages? my %stats_results = (); while (my ($hostname, $con) = each %CONS) { $cv->begin; call_stats($con, ['', 'items', 'slabs'], sub { $stats_results{$hostname} = shift; $cv->end; }); } $cv->recv; # Short circuit since we don't have anything to compare to. unless ($prev_stats_results) { $prev_stats_results = \%stats_results; return $CONF->{delay}; } # Semi-exact global time diff for stats that want to average # themselves per-second. my $this_run = AnyEvent->time; $TIME_SINCE_LAST_RUN = $this_run - $LAST_RUN; $LAST_RUN = $this_run; # Done all our fetches. Drive the display. display_run($prev_stats_results, \%stats_results); $prev_stats_results = \%stats_results; my $end = AnyEvent->time; my $diff = $LAST_RUN - $start; print "loop took: $diff"; return $diff; } sub maintain_connections { my $cv = AnyEvent->condvar; $cv->begin (sub { shift->send }); for my $host (@{$CONF->{servers}}) { next if $CONS{$host}; $cv->begin; $CONS{$host} = connect_memcached($host, sub { if ($_[0] eq 'err') { print "Failed connecting to $host: ", $_[1], "\n"; delete $CONS{$host}; } $cv->end; }); } $cv->end; $cv->recv; } sub connect_memcached { my ($fullhost, $cb) = @_; my ($host, $port) = split /:/, $fullhost; my $con; $con = AnyEvent::Handle->new ( connect => [$host => $port], on_connect => sub { $cb->('con'); }, on_connect_error => sub { $cb->('err', $!); $con->destroy; }, on_eof => sub { $cb->('err', $!); $con->destroy; }, ); return $con; } # Function's getting a little weird since I started optimizing it. # As of my first set of production tests, this routine is where we spend # almost all of our processing time. sub call_stats { my ($con, $cmds, $cb) = @_; my $stats = {}; my $num_types = @$cmds; my $reader; $reader = sub { my ($con, $results) = @_; { my %temp = (); for my $line (split(/\n/, $results)) { my ($k, $v) = (split(/\s+/, $line))[1,2]; $temp{$k} = $v; } $stats->{$cmds->[0]} = \%temp; } shift @$cmds; unless (@$cmds) { # Out of commands to process, return goodies. $cb->($stats); return; } }; for my $cmd (@$cmds) { $con->push_write('stats ' . $cmd . "\n"); $stats->{$cmd} = {}; $con->push_read(line => "END\r\n", $reader); } } ### Compute routines sub compute_hostname { return $_[0]; } sub compute_hit_rate { my $s = $_[1]; my $total = $s->{get_hits} + $s->{get_misses}; return 'NA' unless $total; return $s->{get_hits} / $total; } sub compute_fill_rate { my $s = $_[1]; return $s->{bytes} / $s->{limit_maxbytes}; } sub format_column { my ($col, $val) = @_; my $res; $col =~ s/^all_//; if ($column_format{$col}) { if (ref($column_format{$col}) eq 'CODE') { return $column_format{$col}->($val); } else { return $val .= $column_format{$col}; } } else { return format_commas($val); } } sub column_can_total { my $col = shift; $col =~ s/^all_//; return 1 unless exists $column_format_totals{$col}; return $column_format_totals{$col}; } ### Display routines # If there isn't a specific column type computer, see if we just want to # look at the specific stat and return it. # If column is a generic type and of 'all_cmd_get' format, return the more # complete stat instead of the diffed stat. sub compute_column { my ($col, $host, $prev_stats, $curr_stats) = @_; my $diff_stats = 1; $diff_stats = 0 if ($col =~ s/^all_//); # Really should decide on whether or not to flatten the hash :/ my $find_stat = sub { for my $type (keys %{$_[0]}) { return $_[0]->{$type}->{$_[1]} if exists $_[0]->{$type}->{$_[1]}; } }; my $diff_stat = sub { my $stat = shift; return 'NA' unless defined $find_stat->($curr_stats, $stat); if ($diff_stats) { my $diff = eval { return ($find_stat->($curr_stats, $stat) - $find_stat->($prev_stats, $stat)) / $TIME_SINCE_LAST_RUN; }; return 'NA' if ($@); return $diff; } else { return $find_stat->($curr_stats, $stat); } }; if (my $comp = $column_compute{$col}) { my %s = (); for my $stat (@{$comp->{stats}}) { $s{$stat} = $diff_stat->($stat); } return $comp->{code}->($host, \%s); } else { return $diff_stat->($col); } return 'NA'; } # We have a bunch of stats from a bunch of connections. # At this point we run a particular display mode, capture the lines, then # truncate and display them. sub display_run { my $prev_stats = shift; my $curr_stats = shift; @TERM_SIZE = GetTerminalSize; die "cannot detect terminal size" unless $TERM_SIZE[0] && $TERM_SIZE[1]; if ($LAST_KEY eq 'q') { print "\n"; ReadMode('normal'); exit; } if ($LAST_KEY ne $CONF->{mode} && exists $display_modes{$LAST_KEY}) { $CONF->{prev_mode} = $CONF->{mode}; $CONF->{mode} = $LAST_KEY; } elsif ($CONF->{mode} eq 'h' || $CONF->{mode} eq '?') { # Bust out of help mode on any key. $CONF->{mode} = $CONF->{prev_mode}; } my $lines = $display_modes{$CONF->{mode}}->($prev_stats, $curr_stats); display_lines($lines) if $lines; } # Default "top" mode. # create a set of computed columns as requested by the config. # this has gotten a little out of hand... needs more cleanup/abstraction. sub display_top_mode { my $prev_stats = shift; my $curr_stats = shift; my @columns = @{$CONF->{top_mode}->{columns}}; my @rows = (); my @tot_row = (); # Round one. for my $host (sort keys %{$curr_stats}) { my @row = (); for my $colnum (0 .. @columns-1) { my $col = $columns[$colnum]; my $res = compute_column($col, $host, $prev_stats->{$host}, $curr_stats->{$host}); $tot_row[$colnum] += $res if is_numeric($res); push @row, $res; } push(@rows, \@row); } # Sort rows by sort column (ascending or descending) if (my $sort = $CONF->{top_mode}->{sort_column}) { my $order = $CONF->{top_mode}->{sort_order} || 'asc'; my $colnum = 0; for (0 .. @columns-1) { $colnum = $_ if $columns[$_] eq $sort; } my @newrows; if ($order eq 'asc') { if (is_numeric($rows[0]->[$colnum])) { @newrows = sort { $a->[$colnum] <=> $b->[$colnum] } @rows; } else { @newrows = sort { $a->[$colnum] cmp $b->[$colnum] } @rows; } } else { if (is_numeric($rows[0]->[$colnum])) { @newrows = sort { $b->[$colnum] <=> $a->[$colnum] } @rows; } else { @newrows = sort { $b->[$colnum] cmp $a->[$colnum] } @rows; } } @rows = @newrows; } # Format each column after the sort... { my @newrows = (); for my $row (@rows) { my @newrow = (); for my $colnum (0 .. @columns-1) { push @newrow, is_numeric($row->[$colnum]) ? format_column($columns[$colnum], $row->[$colnum]) : $row->[$colnum]; } push @newrows, \@newrow; } @rows = @newrows; } # Create average and total rows. my @avg_row = (); for my $col (0 .. @columns-1) { if (is_numeric($tot_row[$col])) { my $countable_rows = 0; for my $row (@rows) { next unless $row->[$col]; $countable_rows++ unless $row->[$col] eq 'NA'; } $countable_rows = 1 unless $countable_rows; push @avg_row, format_column($columns[$col], sprintf('%.2f', $tot_row[$col] / $countable_rows)); } else { push @avg_row, 'NA'; } $tot_row[$col] = 'NA' unless defined $tot_row[$col]; $tot_row[$col] = 'NA' unless (column_can_total($columns[$col])); $tot_row[$col] = format_column($columns[$col], $tot_row[$col]) unless $tot_row[$col] eq 'NA'; } unshift @rows, \@avg_row; unshift @rows, ['AVERAGE:']; unshift @rows, \@tot_row; unshift @rows, ['TOTAL:']; # Round two. Pass @rows into a function which returns an array with the # desired format spacing for each column. unshift @rows, \@columns; my $spacing = find_optimal_spacing(\@rows); my @display_lines = (); for my $row (@rows) { my $line = ''; for my $col (0 .. @$row-1) { my $space = $spacing->[$col]; $line .= sprintf("%-${space}s ", $row->[$col]); } push @display_lines, $line; } return \@display_lines; } sub display_help_mode { my $help = <<"ENDHELP"; dormando's awesome memcached top utility version v$VERSION This early version requires you to edit the ~/.damemtop/damemtop.yaml (or /etc/damemtop.yaml) file in order to change options. See --help for more info. Hit any key to exit help. ENDHELP my @lines = split /\n/, $help; display_lines(\@lines); $LAST_KEY = ReadKey(0); return; } # Takes a set of lines, clears screen, dumps header, trims lines, etc # MAYBE: mode to wrap lines instead of trim them? sub display_lines { my $lines = shift; my $width = $TERM_SIZE[0]; my $height_remain = $TERM_SIZE[1]; unshift @$lines, display_header($width); clear_screen() unless $CONF->{no_clear}; while (--$height_remain && @$lines) { # truncate too long lines. my $line = shift @$lines; $line = substr $line, 0, $width-1; print $line, "\n"; } } sub display_header { my $topbar = 'damemtop: ' . scalar localtime; if ($CONF->{mode} eq 't' && $CONF->{top_mode}->{sort_column}) { $topbar .= ' [sort: ' . $CONF->{top_mode}->{sort_column} . ']'; } $topbar .= ' [delay: ' . $CONF->{delay} . 's]'; return $topbar; } ### Utilities # find the optimal format spacing for each column, which is: # longest length of item in col + 2 (whitespace). sub find_optimal_spacing { my $rows = shift; my @maxes = (); my $num_cols = @{$rows->[0]}; for my $row (@$rows) { for my $col (0 .. $num_cols-1) { $maxes[$col] = 0 unless $maxes[$col]; next unless $row->[$col]; $maxes[$col] = length($row->[$col]) if length($row->[$col]) > $maxes[$col]; } } for my $col (0 .. $num_cols) { $maxes[$col] += 1; } return \@maxes; } # doesn't try too hard to identify numbers... sub is_numeric { return 0 unless $_[0]; return 1 if $_[0] =~ m/^\d+(\.\d*)?(\w+)?$/; return 0; } sub format_percent { return sprintf("%.2f%%", $_[0] * 100); } sub format_commas { my $num = shift; $num = int($num); $num =~ s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g; return $num; } # Can tick counters/etc here as well. sub clear_screen { print $CLEAR; } # tries minimally to find a localized config file. # TODO: Handle the YAML error and make it prettier. sub load_config { my $config = $opts{config} if $opts{config}; my $homedir = "$ENV{HOME}/.damemtop/damemtop.yaml"; if (-e $homedir) { $config = $homedir; } else { $config = '/etc/damemtop.yaml'; } return LoadFile($config); } sub show_help { print <<"ENDHELP"; dormando's awesome memcached top utility version v$VERSION This program is copyright (c) 2009 Dormando. Use and distribution licensed under the BSD license. See the COPYING file for full text. contact: dormando\@rydia.net or memcached\@googlegroups.com. This early version requires you to edit the ~/.damemtop/damemtop.yaml (or /etc/damemtop.yaml) file in order to change options. You may display any column that is in the output of 'stats', 'stats items', or 'stats slabs' from memcached's ASCII protocol. Start a column with 'all_' (ie; 'all_get_hits') to display the current stat, otherwise the stat is displayed as an average per second. Specify a "sort_column" under "top_mode" to sort the output by any column. Some special "computed" columns exist: hit_rate (get/miss hit ratio) fill_rate (% bytes used out of the maximum memory limit) ENDHELP exit; } memcached-1.4.14/scripts/start-memcached0000755000175000017500000000531111701635506015112 00000000000000#!/usr/bin/perl -w # start-memcached # 2003/2004 - Jay Bonci # This script handles the parsing of the /etc/memcached.conf file # and was originally created for the Debian distribution. # Anyone may use this little script under the same terms as # memcached itself. use POSIX qw(setsid); use strict; if($> != 0 and $< != 0) { print STDERR "Only root wants to run start-memcached.\n"; exit; } my $params; my $etchandle; my $etcfile = "/etc/memcached.conf"; # This script assumes that memcached is located at /usr/bin/memcached, and # that the pidfile is writable at /var/run/memcached.pid my $memcached = "/usr/bin/memcached"; my $pidfile = "/var/run/memcached.pid"; if (scalar(@ARGV) == 2) { $etcfile = shift(@ARGV); $pidfile = shift(@ARGV); } # If we don't get a valid logfile parameter in the /etc/memcached.conf file, # we'll just throw away all of our in-daemon output. We need to re-tie it so # that non-bash shells will not hang on logout. Thanks to Michael Renner for # the tip my $fd_reopened = "/dev/null"; sub handle_logfile { my ($logfile) = @_; $fd_reopened = $logfile; } sub reopen_logfile { my ($logfile) = @_; open *STDERR, ">>$logfile"; open *STDOUT, ">>$logfile"; open *STDIN, ">>/dev/null"; $fd_reopened = $logfile; } # This is set up in place here to support other non -[a-z] directives my $conf_directives = { "logfile" => \&handle_logfile, }; if(open $etchandle, $etcfile) { foreach my $line (<$etchandle>) { $line ||= ""; $line =~ s/\#.*//g; $line =~ s/\s+$//g; $line =~ s/^\s+//g; next unless $line; next if $line =~ /^\-[dh]/; if($line =~ /^[^\-]/) { my ($directive, $arg) = $line =~ /^(.*?)\s+(.*)/; $conf_directives->{$directive}->($arg); next; } push @$params, $line; } }else{ $params = []; } push @$params, "-u root" unless(grep "-u", @$params); $params = join " ", @$params; if(-e $pidfile) { open PIDHANDLE, "$pidfile"; my $localpid = ; close PIDHANDLE; chomp $localpid; if(-d "/proc/$localpid") { print STDERR "memcached is already running.\n"; exit; }else{ `rm -f $localpid`; } } my $pid = fork(); if($pid == 0) { # setsid makes us the session leader setsid(); reopen_logfile($fd_reopened); # must fork again now that tty is closed $pid = fork(); if ($pid) { if(open PIDHANDLE,">$pidfile") { print PIDHANDLE $pid; close PIDHANDLE; }else{ print STDERR "Can't write pidfile to $pidfile.\n"; } exit(0); } exec "$memcached $params"; exit(0); } memcached-1.4.14/scripts/memcached.service0000644000175000017500000000035511701635506015416 00000000000000[Unit] Description=memcached daemon After=network.target [Service] EnvironmentFile=/etc/sysconfig/memcached ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS [Install] WantedBy=multi-user.target memcached-1.4.14/scripts/memcached-init0000755000175000017500000000537311640750600014723 00000000000000#! /bin/bash ### BEGIN INIT INFO # Provides: memcached # Required-Start: $syslog # Required-Stop: $syslog # Should-Start: $local_fs # Should-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: memcached - Memory caching daemon # Description: memcached - Memory caching daemon ### END INIT INFO # Usage: # cp /etc/memcached.conf /etc/memcached_server1.conf # cp /etc/memcached.conf /etc/memcached_server2.conf # start all instances: # /etc/init.d/memcached start # start one instance: # /etc/init.d/memcached start server1 # stop all instances: # /etc/init.d/memcached stop # stop one instance: # /etc/init.d/memcached stop server1 # There is no "status" command. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/bin/memcached DAEMONNAME=memcached DAEMONBOOTSTRAP=/usr/share/memcached/scripts/start-memcached DESC=memcached test -x $DAEMON || exit 0 test -x $DAEMONBOOTSTRAP || exit 0 set -e FILES=(/etc/memcached_*.conf) # check for alternative config schema if [ -r "${FILES[0]}" ]; then CONFIGS=() for FILE in "${FILES[@]}"; do # remove prefix NAME=${FILE#/etc/} # remove suffix NAME=${NAME%.conf} # check optional second param if [ $# -ne 2 ]; then # add to config array CONFIGS+=($NAME) elif [ "memcached_$2" == "$NAME" ]; then # use only one memcached CONFIGS=($NAME) break; fi; done; if [ ${#CONFIGS[@]} == 0 ]; then echo "Config not exist for: $2" >&2 exit 1 fi; else CONFIGS=(memcached) fi; CONFIG_NUM=${#CONFIGS[@]} for ((i=0; i < $CONFIG_NUM; i++)); do NAME=${CONFIGS[${i}]} PIDFILE="/var/run/${NAME}.pid" case "$1" in start) echo -n "Starting $DESC: " start-stop-daemon --start --quiet --exec "$DAEMONBOOTSTRAP" -- /etc/${NAME}.conf $PIDFILE echo "$NAME." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON echo "$NAME." rm -f $PIDFILE ;; restart|force-reload) # # If the "reload" option is implemented, move the "force-reload" # option to the "reload" entry above. If not, "force-reload" is # just the same as "restart". # echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE rm -f $PIDFILE sleep 1 start-stop-daemon --start --quiet --exec "$DAEMONBOOTSTRAP" -- /etc/${NAME}.conf $PIDFILE echo "$NAME." ;; *) N=/etc/init.d/$NAME # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esac done; exit 0 memcached-1.4.14/scripts/memcached.sysv0000755000175000017500000000257411446413300014762 00000000000000#! /bin/sh # # chkconfig: - 55 45 # description: The memcached daemon is a network memory cache service. # processname: memcached # config: /etc/sysconfig/memcached # Source function library. . /etc/rc.d/init.d/functions PORT=11211 USER=nobody MAXCONN=1024 CACHESIZE=64 OPTIONS="" if [ -f /etc/sysconfig/memcached ];then . /etc/sysconfig/memcached fi # Check that networking is up. if [ "$NETWORKING" = "no" ] then exit 0 fi RETVAL=0 prog="memcached" start () { echo -n $"Starting $prog: " # insure that /var/run/memcached has proper permissions chown $USER /var/run/memcached daemon memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached/memcached.pid $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached } stop () { echo -n $"Stopping $prog: " killproc memcached RETVAL=$? echo if [ $RETVAL -eq 0 ] ; then rm -f /var/lock/subsys/memcached rm -f /var/run/memcached.pid fi } restart () { stop start } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status memcached ;; restart|reload) restart ;; condrestart) [ -f /var/lock/subsys/memcached ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" exit 1 esac exit $? memcached-1.4.14/items.h0000644000175000017500000000224511702467341011732 00000000000000/* See items.c */ uint64_t get_cas_id(void); /*@null@*/ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes); void item_free(item *it); bool item_size_ok(const size_t nkey, const int flags, const int nbytes); int do_item_link(item *it, const uint32_t hv); /** may fail if transgresses limits */ void do_item_unlink(item *it, const uint32_t hv); void do_item_unlink_nolock(item *it, const uint32_t hv); void do_item_remove(item *it); void do_item_update(item *it); /** update LRU time to current and reposition */ int do_item_replace(item *it, item *new_it, const uint32_t hv); /*@null@*/ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); void do_item_stats(ADD_STAT add_stats, void *c); /*@null@*/ void do_item_stats_sizes(ADD_STAT add_stats, void *c); void do_item_flush_expired(void); item *do_item_get(const char *key, const size_t nkey, const uint32_t hv); item *do_item_touch(const char *key, const size_t nkey, uint32_t exptime, const uint32_t hv); void item_stats_reset(void); extern pthread_mutex_t cache_lock; void item_stats_evictions(uint64_t *evicted); memcached-1.4.14/AUTHORS0000644000175000017500000000010511701635506011500 00000000000000Anatoly Vorobey Brad Fitzpatrick memcached-1.4.14/config.h.in0000644000175000017500000000645412005572440012463 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Set to nonzero if you want to include DTRACE */ #undef ENABLE_DTRACE /* Set to nonzero if you want to include SASL */ #undef ENABLE_SASL /* Set to nonzero if you want to enable a SASL pwdb */ #undef ENABLE_SASL_PWDB /* machine is bigendian */ #undef ENDIAN_BIG /* machine is littleendian */ #undef ENDIAN_LITTLE /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define this if you have an implementation of drop_privileges() */ #undef HAVE_DROP_PRIVILEGES /* GCC Atomics available */ #undef HAVE_GCC_ATOMICS /* Define to 1 if you have the `getpagesizes' function. */ #undef HAVE_GETPAGESIZES /* Have ntohll */ #undef HAVE_HTONLL /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `memcntl' function. */ #undef HAVE_MEMCNTL /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mlockall' function. */ #undef HAVE_MLOCKALL /* we have sasl_callback_ft */ #undef HAVE_SASL_CALLBACK_FT /* Set to nonzero if your SASL implementation supports SASL_CB_GETCONF */ #undef HAVE_SASL_CB_GETCONF /* Define to 1 if you have the header file. */ #undef HAVE_SASL_SASL_H /* Define to 1 if you have the `setppriv' function. */ #undef HAVE_SETPPRIV /* Define to 1 if you have the `sigignore' function. */ #undef HAVE_SIGIGNORE /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define this if you have umem.h */ #undef HAVE_UMEM_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Machine need alignment */ #undef NEED_ALIGN /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* find sigignore on Linux */ #undef _GNU_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* define to int if socklen_t not available */ #undef socklen_t #if HAVE_STDBOOL_H #include #else #define bool char #define false 0 #define true 1 #endif #ifdef HAVE_INTTYPES_H #include #endif memcached-1.4.14/timedrun.c0000644000175000017500000000456011703465716012442 00000000000000#include #include #include #include #include #include #include static int caught = 0; static void caught_signal(int which) { caught = which; } static int wait_for_process(pid_t pid) { int rv = EX_SOFTWARE; int stats = 0; int i = 0; struct sigaction sig_handler; sig_handler.sa_handler = caught_signal; sig_handler.sa_flags = 0; sigaction(SIGALRM, &sig_handler, NULL); sigaction(SIGHUP, &sig_handler, NULL); sigaction(SIGINT, &sig_handler, NULL); sigaction(SIGTERM, &sig_handler, NULL); sigaction(SIGPIPE, &sig_handler, NULL); /* Loop forever waiting for the process to quit */ for (i = 0; ;i++) { pid_t p = waitpid(pid, &stats, 0); if (p == pid) { /* child exited. Let's get out of here */ rv = WIFEXITED(stats) ? WEXITSTATUS(stats) : (0x80 | WTERMSIG(stats)); break; } else { int sig = 0; switch (i) { case 0: /* On the first iteration, pass the signal through */ sig = caught > 0 ? caught : SIGTERM; if (caught == SIGALRM) { fprintf(stderr, "Timeout.. killing the process\n"); } break; case 1: sig = SIGTERM; break; default: sig = SIGKILL; break; } if (kill(pid, sig) < 0) { /* Kill failed. Must have lost the process. :/ */ perror("lost child when trying to kill"); } /* Wait up to 5 seconds for the pid */ alarm(5); } } return rv; } static int spawn_and_wait(char **argv) { int rv = EX_SOFTWARE; pid_t pid = fork(); switch (pid) { case -1: perror("fork"); rv = EX_OSERR; break; /* NOTREACHED */ case 0: execvp(argv[0], argv); perror("exec"); rv = EX_SOFTWARE; break; /* NOTREACHED */ default: rv = wait_for_process(pid); } return rv; } int main(int argc, char **argv) { int naptime = 0; assert(argc > 2); naptime = atoi(argv[1]); assert(naptime > 0 && naptime < 1800); alarm(naptime); return spawn_and_wait(argv+2); } memcached-1.4.14/util.h0000644000175000017500000000162011701635506011561 00000000000000/* * Wrappers around strtoull/strtoll that are safer and easier to * use. For tests and assumptions, see internal_tests.c. * * str a NULL-terminated base decimal 10 unsigned integer * out out parameter, if conversion succeeded * * returns true if conversion succeeded. */ bool safe_strtoull(const char *str, uint64_t *out); bool safe_strtoll(const char *str, int64_t *out); bool safe_strtoul(const char *str, uint32_t *out); bool safe_strtol(const char *str, int32_t *out); #ifndef HAVE_HTONLL extern uint64_t htonll(uint64_t); extern uint64_t ntohll(uint64_t); #endif #ifdef __GCC # define __gcc_attribute__ __attribute__ #else # define __gcc_attribute__(x) #endif /** * Vararg variant of perror that makes for more useful error messages * when reporting with parameters. * * @param fmt a printf format */ void vperror(const char *fmt, ...) __gcc_attribute__ ((format (printf, 1, 2))); memcached-1.4.14/sasl_defs.h0000644000175000017500000000126511711074307012551 00000000000000#ifndef SASL_DEFS_H #define SASL_DEFS_H 1 // Longest one I could find was ``9798-U-RSA-SHA1-ENC'' #define MAX_SASL_MECH_LEN 32 #if defined(HAVE_SASL_SASL_H) && defined(ENABLE_SASL) #include void init_sasl(void); extern char my_sasl_hostname[1025]; #else /* End of SASL support */ typedef void* sasl_conn_t; #define init_sasl() {} #define sasl_dispose(x) {} #define sasl_server_new(a, b, c, d, e, f, g, h) 1 #define sasl_listmech(a, b, c, d, e, f, g, h) 1 #define sasl_server_start(a, b, c, d, e, f) 1 #define sasl_server_step(a, b, c, d, e) 1 #define sasl_getprop(a, b, c) {} #define SASL_OK 0 #define SASL_CONTINUE -1 #endif /* sasl compat */ #endif /* SASL_DEFS_H */ memcached-1.4.14/missing0000755000175000017500000002623311331674343012042 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: memcached-1.4.14/cache.h0000644000175000017500000001032011701635506011644 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef CACHE_H #define CACHE_H #include #ifdef HAVE_UMEM_H #include #define cache_t umem_cache_t #define cache_alloc(a) umem_cache_alloc(a, UMEM_DEFAULT) #define cache_free(a, b) umem_cache_free(a, b) #define cache_create(a,b,c,d,e) umem_cache_create((char*)a, b, c, d, e, NULL, NULL, NULL, 0) #define cache_destroy(a) umem_cache_destroy(a); #else #ifndef NDEBUG /* may be used for debug purposes */ extern int cache_error; #endif /** * Constructor used to initialize allocated objects * * @param obj pointer to the object to initialized. * @param notused1 This parameter is currently not used. * @param notused2 This parameter is currently not used. * @return you should return 0, but currently this is not checked */ typedef int cache_constructor_t(void* obj, void* notused1, int notused2); /** * Destructor used to clean up allocated objects before they are * returned to the operating system. * * @param obj pointer to the object to initialized. * @param notused1 This parameter is currently not used. * @param notused2 This parameter is currently not used. * @return you should return 0, but currently this is not checked */ typedef void cache_destructor_t(void* obj, void* notused); /** * Definition of the structure to keep track of the internal details of * the cache allocator. Touching any of these variables results in * undefined behavior. */ typedef struct { /** Mutex to protect access to the structure */ pthread_mutex_t mutex; /** Name of the cache objects in this cache (provided by the caller) */ char *name; /** List of pointers to available buffers in this cache */ void **ptr; /** The size of each element in this cache */ size_t bufsize; /** The capacity of the list of elements */ int freetotal; /** The current number of free elements */ int freecurr; /** The constructor to be called each time we allocate more memory */ cache_constructor_t* constructor; /** The destructor to be called each time before we release memory */ cache_destructor_t* destructor; } cache_t; /** * Create an object cache. * * The object cache will let you allocate objects of the same size. It is fully * MT safe, so you may allocate objects from multiple threads without having to * do any syncrhonization in the application code. * * @param name the name of the object cache. This name may be used for debug purposes * and may help you track down what kind of object you have problems with * (buffer overruns, leakage etc) * @param bufsize the size of each object in the cache * @param align the alignment requirements of the objects in the cache. * @param constructor the function to be called to initialize memory when we need * to allocate more memory from the os. * @param destructor the function to be called before we release the memory back * to the os. * @return a handle to an object cache if successful, NULL otherwise. */ cache_t* cache_create(const char* name, size_t bufsize, size_t align, cache_constructor_t* constructor, cache_destructor_t* destructor); /** * Destroy an object cache. * * Destroy and invalidate an object cache. You should return all buffers allocated * with cache_alloc by using cache_free before calling this function. Not doing * so results in undefined behavior (the buffers may or may not be invalidated) * * @param handle the handle to the object cache to destroy. */ void cache_destroy(cache_t* handle); /** * Allocate an object from the cache. * * @param handle the handle to the object cache to allocate from * @return a pointer to an initialized object from the cache, or NULL if * the allocation cannot be satisfied. */ void* cache_alloc(cache_t* handle); /** * Return an object back to the cache. * * The caller should return the object in an initialized state so that * the object may be returned in an expected state from cache_alloc. * * @param handle handle to the object cache to return the object to * @param ptr pointer to the object to return. */ void cache_free(cache_t* handle, void* ptr); #endif #endif memcached-1.4.14/memcached.h0000644000175000017500000004474512005335761012527 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /** \file * The main memcached header holding commonly used data * structures and function prototypes. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "protocol_binary.h" #include "cache.h" #include "sasl_defs.h" /** Maximum length of a key. */ #define KEY_MAX_LENGTH 250 /** Size of an incr buf. */ #define INCR_MAX_STORAGE_LEN 24 #define DATA_BUFFER_SIZE 2048 #define UDP_READ_BUFFER_SIZE 65536 #define UDP_MAX_PAYLOAD_SIZE 1400 #define UDP_HEADER_SIZE 8 #define MAX_SENDBUF_SIZE (256 * 1024 * 1024) /* I'm told the max length of a 64-bit num converted to string is 20 bytes. * Plus a few for spaces, \r\n, \0 */ #define SUFFIX_SIZE 24 /** Initial size of list of items being returned by "get". */ #define ITEM_LIST_INITIAL 200 /** Initial size of list of CAS suffixes appended to "gets" lines. */ #define SUFFIX_LIST_INITIAL 20 /** Initial size of the sendmsg() scatter/gather array. */ #define IOV_LIST_INITIAL 400 /** Initial number of sendmsg() argument structures to allocate. */ #define MSG_LIST_INITIAL 10 /** High water marks for buffer shrinking */ #define READ_BUFFER_HIGHWAT 8192 #define ITEM_LIST_HIGHWAT 400 #define IOV_LIST_HIGHWAT 600 #define MSG_LIST_HIGHWAT 100 /* Binary protocol stuff */ #define MIN_BIN_PKT_LENGTH 16 #define BIN_PKT_HDR_WORDS (MIN_BIN_PKT_LENGTH/sizeof(uint32_t)) /* Initial power multiplier for the hash table */ #define HASHPOWER_DEFAULT 16 /* unistd.h is here */ #if HAVE_UNISTD_H # include #endif /* Slab sizing definitions. */ #define POWER_SMALLEST 1 #define POWER_LARGEST 200 #define CHUNK_ALIGN_BYTES 8 #define MAX_NUMBER_OF_SLAB_CLASSES (POWER_LARGEST + 1) /** How long an object can reasonably be assumed to be locked before harvesting it on a low memory condition. */ #define TAIL_REPAIR_TIME (3 * 3600) /* warning: don't use these macros with a function, as it evals its arg twice */ #define ITEM_get_cas(i) (((i)->it_flags & ITEM_CAS) ? \ (i)->data->cas : (uint64_t)0) #define ITEM_set_cas(i,v) { \ if ((i)->it_flags & ITEM_CAS) { \ (i)->data->cas = v; \ } \ } #define ITEM_key(item) (((char*)&((item)->data)) \ + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0)) #define ITEM_suffix(item) ((char*) &((item)->data) + (item)->nkey + 1 \ + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0)) #define ITEM_data(item) ((char*) &((item)->data) + (item)->nkey + 1 \ + (item)->nsuffix \ + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0)) #define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + 1 \ + (item)->nsuffix + (item)->nbytes \ + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0)) #define STAT_KEY_LEN 128 #define STAT_VAL_LEN 128 /** Append a simple stat with a stat name, value format and value */ #define APPEND_STAT(name, fmt, val) \ append_stat(name, add_stats, c, fmt, val); /** Append an indexed stat with a stat name (with format), value format and value */ #define APPEND_NUM_FMT_STAT(name_fmt, num, name, fmt, val) \ klen = snprintf(key_str, STAT_KEY_LEN, name_fmt, num, name); \ vlen = snprintf(val_str, STAT_VAL_LEN, fmt, val); \ add_stats(key_str, klen, val_str, vlen, c); /** Common APPEND_NUM_FMT_STAT format. */ #define APPEND_NUM_STAT(num, name, fmt, val) \ APPEND_NUM_FMT_STAT("%d:%s", num, name, fmt, val) /** * Callback for any function producing stats. * * @param key the stat's key * @param klen length of the key * @param val the stat's value in an ascii form (e.g. text form of a number) * @param vlen length of the value * @parm cookie magic callback cookie */ typedef void (*ADD_STAT)(const char *key, const uint16_t klen, const char *val, const uint32_t vlen, const void *cookie); /* * NOTE: If you modify this table you _MUST_ update the function state_text */ /** * Possible states of a connection. */ enum conn_states { conn_listening, /**< the socket which listens for connections */ conn_new_cmd, /**< Prepare connection for next command */ conn_waiting, /**< waiting for a readable socket */ conn_read, /**< reading in a command line */ conn_parse_cmd, /**< try to parse a command from the input buffer */ conn_write, /**< writing out a simple response */ conn_nread, /**< reading in a fixed number of bytes */ conn_swallow, /**< swallowing unnecessary bytes w/o storing */ conn_closing, /**< closing this connection */ conn_mwrite, /**< writing out many items sequentially */ conn_max_state /**< Max state value (used for assertion) */ }; enum bin_substates { bin_no_state, bin_reading_set_header, bin_reading_cas_header, bin_read_set_value, bin_reading_get_key, bin_reading_stat, bin_reading_del_header, bin_reading_incr_header, bin_read_flush_exptime, bin_reading_sasl_auth, bin_reading_sasl_auth_data, bin_reading_touch_key, }; enum protocol { ascii_prot = 3, /* arbitrary value. */ binary_prot, negotiating_prot /* Discovering the protocol */ }; enum network_transport { local_transport, /* Unix sockets*/ tcp_transport, udp_transport }; #define IS_UDP(x) (x == udp_transport) #define NREAD_ADD 1 #define NREAD_SET 2 #define NREAD_REPLACE 3 #define NREAD_APPEND 4 #define NREAD_PREPEND 5 #define NREAD_CAS 6 enum store_item_type { NOT_STORED=0, STORED, EXISTS, NOT_FOUND }; enum delta_result_type { OK, NON_NUMERIC, EOM, DELTA_ITEM_NOT_FOUND, DELTA_ITEM_CAS_MISMATCH }; /** Time relative to server start. Smaller than time_t on 64-bit systems. */ typedef unsigned int rel_time_t; /** Stats stored per slab (and per thread). */ struct slab_stats { uint64_t set_cmds; uint64_t get_hits; uint64_t touch_hits; uint64_t delete_hits; uint64_t cas_hits; uint64_t cas_badval; uint64_t incr_hits; uint64_t decr_hits; }; /** * Stats stored per-thread. */ struct thread_stats { pthread_mutex_t mutex; uint64_t get_cmds; uint64_t get_misses; uint64_t touch_cmds; uint64_t touch_misses; uint64_t delete_misses; uint64_t incr_misses; uint64_t decr_misses; uint64_t cas_misses; uint64_t bytes_read; uint64_t bytes_written; uint64_t flush_cmds; uint64_t conn_yields; /* # of yields for connections (-R option)*/ uint64_t auth_cmds; uint64_t auth_errors; struct slab_stats slab_stats[MAX_NUMBER_OF_SLAB_CLASSES]; }; /** * Global stats. */ struct stats { pthread_mutex_t mutex; unsigned int curr_items; unsigned int total_items; uint64_t curr_bytes; unsigned int curr_conns; unsigned int total_conns; uint64_t rejected_conns; unsigned int reserved_fds; unsigned int conn_structs; uint64_t get_cmds; uint64_t set_cmds; uint64_t touch_cmds; uint64_t get_hits; uint64_t get_misses; uint64_t touch_hits; uint64_t touch_misses; uint64_t evictions; uint64_t reclaimed; time_t started; /* when the process was started */ bool accepting_conns; /* whether we are currently accepting */ uint64_t listen_disabled_num; unsigned int hash_power_level; /* Better hope it's not over 9000 */ uint64_t hash_bytes; /* size used for hash tables */ bool hash_is_expanding; /* If the hash table is being expanded */ uint64_t expired_unfetched; /* items reclaimed but never touched */ uint64_t evicted_unfetched; /* items evicted but never touched */ bool slab_reassign_running; /* slab reassign in progress */ uint64_t slabs_moved; /* times slabs were moved around */ }; #define MAX_VERBOSITY_LEVEL 2 /* When adding a setting, be sure to update process_stat_settings */ /** * Globally accessible settings as derived from the commandline. */ struct settings { size_t maxbytes; int maxconns; int port; int udpport; char *inter; int verbose; rel_time_t oldest_live; /* ignore existing items older than this */ int evict_to_free; char *socketpath; /* path to unix socket if using local socket */ int access; /* access mask (a la chmod) for unix domain socket */ double factor; /* chunk size growth factor */ int chunk_size; int num_threads; /* number of worker (without dispatcher) libevent threads to run */ int num_threads_per_udp; /* number of worker threads serving each udp socket */ char prefix_delimiter; /* character that marks a key prefix (for stats) */ int detail_enabled; /* nonzero if we're collecting detailed stats */ int reqs_per_event; /* Maximum number of io to process on each io-event. */ bool use_cas; enum protocol binding_protocol; int backlog; int item_size_max; /* Maximum item size, and upper end for slabs */ bool sasl; /* SASL on/off */ bool maxconns_fast; /* Whether or not to early close connections */ bool slab_reassign; /* Whether or not slab reassignment is allowed */ int slab_automove; /* Whether or not to automatically move slabs */ int hashpower_init; /* Starting hash power level */ }; extern struct stats stats; extern time_t process_started; extern struct settings settings; #define ITEM_LINKED 1 #define ITEM_CAS 2 /* temp */ #define ITEM_SLABBED 4 #define ITEM_FETCHED 8 /** * Structure for storing items within memcached. */ typedef struct _stritem { struct _stritem *next; struct _stritem *prev; struct _stritem *h_next; /* hash chain next */ rel_time_t time; /* least recent access */ rel_time_t exptime; /* expire time */ int nbytes; /* size of data */ unsigned short refcount; uint8_t nsuffix; /* length of flags-and-length string */ uint8_t it_flags; /* ITEM_* above */ uint8_t slabs_clsid;/* which slab class we're in */ uint8_t nkey; /* key length, w/terminating null and padding */ /* this odd type prevents type-punning issues when we do * the little shuffle to save space when not using CAS. */ union { uint64_t cas; char end; } data[]; /* if it_flags & ITEM_CAS we have 8 bytes CAS */ /* then null-terminated key */ /* then " flags length\r\n" (no terminating null) */ /* then data with terminating \r\n (no terminating null; it's binary!) */ } item; typedef struct { pthread_t thread_id; /* unique ID of this thread */ struct event_base *base; /* libevent handle this thread uses */ struct event notify_event; /* listen event for notify pipe */ int notify_receive_fd; /* receiving end of notify pipe */ int notify_send_fd; /* sending end of notify pipe */ struct thread_stats stats; /* Stats generated by this thread */ struct conn_queue *new_conn_queue; /* queue of new connections to handle */ cache_t *suffix_cache; /* suffix cache */ } LIBEVENT_THREAD; typedef struct { pthread_t thread_id; /* unique ID of this thread */ struct event_base *base; /* libevent handle this thread uses */ } LIBEVENT_DISPATCHER_THREAD; /** * The structure representing a connection into memcached. */ typedef struct conn conn; struct conn { int sfd; sasl_conn_t *sasl_conn; enum conn_states state; enum bin_substates substate; struct event event; short ev_flags; short which; /** which events were just triggered */ char *rbuf; /** buffer to read commands into */ char *rcurr; /** but if we parsed some already, this is where we stopped */ int rsize; /** total allocated size of rbuf */ int rbytes; /** how much data, starting from rcur, do we have unparsed */ char *wbuf; char *wcurr; int wsize; int wbytes; /** which state to go into after finishing current write */ enum conn_states write_and_go; void *write_and_free; /** free this memory after finishing writing */ char *ritem; /** when we read in an item's value, it goes here */ int rlbytes; /* data for the nread state */ /** * item is used to hold an item structure created after reading the command * line of set/add/replace commands, but before we finished reading the actual * data. The data is read into ITEM_data(item) to avoid extra copying. */ void *item; /* for commands set/add/replace */ /* data for the swallow state */ int sbytes; /* how many bytes to swallow */ /* data for the mwrite state */ struct iovec *iov; int iovsize; /* number of elements allocated in iov[] */ int iovused; /* number of elements used in iov[] */ struct msghdr *msglist; int msgsize; /* number of elements allocated in msglist[] */ int msgused; /* number of elements used in msglist[] */ int msgcurr; /* element in msglist[] being transmitted now */ int msgbytes; /* number of bytes in current msg */ item **ilist; /* list of items to write out */ int isize; item **icurr; int ileft; char **suffixlist; int suffixsize; char **suffixcurr; int suffixleft; enum protocol protocol; /* which protocol this connection speaks */ enum network_transport transport; /* what transport is used by this connection */ /* data for UDP clients */ int request_id; /* Incoming UDP request ID, if this is a UDP "connection" */ struct sockaddr request_addr; /* Who sent the most recent request */ socklen_t request_addr_size; unsigned char *hdrbuf; /* udp packet headers */ int hdrsize; /* number of headers' worth of space is allocated */ bool noreply; /* True if the reply should not be sent. */ /* current stats command */ struct { char *buffer; size_t size; size_t offset; } stats; /* Binary protocol stuff */ /* This is where the binary header goes */ protocol_binary_request_header binary_header; uint64_t cas; /* the cas to return */ short cmd; /* current command being processed */ int opaque; int keylen; conn *next; /* Used for generating a list of conn structures */ LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */ }; /* current time of day (updated periodically) */ extern volatile rel_time_t current_time; /* TODO: Move to slabs.h? */ extern volatile int slab_rebalance_signal; struct slab_rebalance { void *slab_start; void *slab_end; void *slab_pos; int s_clsid; int d_clsid; int busy_items; uint8_t done; }; extern struct slab_rebalance slab_rebal; /* * Functions */ void do_accept_new_conns(const bool do_accept); enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey, const bool incr, const int64_t delta, char *buf, uint64_t *cas, const uint32_t hv); enum store_item_type do_store_item(item *item, int comm, conn* c, const uint32_t hv); conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum network_transport transport, struct event_base *base); extern int daemonize(int nochdir, int noclose); static inline int mutex_lock(pthread_mutex_t *mutex) { while (pthread_mutex_trylock(mutex)); return 0; } #define mutex_unlock(x) pthread_mutex_unlock(x) #include "stats.h" #include "slabs.h" #include "assoc.h" #include "items.h" #include "trace.h" #include "hash.h" #include "util.h" /* * Functions such as the libevent-related calls that need to do cross-thread * communication in multithreaded mode (rather than actually doing the work * in the current thread) are called via "dispatch_" frontends, which are * also #define-d to directly call the underlying code in singlethreaded mode. */ void thread_init(int nthreads, struct event_base *main_base); int dispatch_event_add(int thread, conn *c); void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum network_transport transport); /* Lock wrappers for cache functions that are called from main loop. */ enum delta_result_type add_delta(conn *c, const char *key, const size_t nkey, const int incr, const int64_t delta, char *buf, uint64_t *cas); void accept_new_conns(const bool do_accept); conn *conn_from_freelist(void); bool conn_add_to_freelist(conn *c); int is_listen_thread(void); item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes); char *item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); void item_flush_expired(void); item *item_get(const char *key, const size_t nkey); item *item_touch(const char *key, const size_t nkey, uint32_t exptime); int item_link(item *it); void item_remove(item *it); int item_replace(item *it, item *new_it, const uint32_t hv); void item_stats(ADD_STAT add_stats, void *c); void item_stats_sizes(ADD_STAT add_stats, void *c); void item_unlink(item *it); void item_update(item *it); void item_lock(uint32_t hv); void item_unlock(uint32_t hv); unsigned short refcount_incr(unsigned short *refcount); unsigned short refcount_decr(unsigned short *refcount); void STATS_LOCK(void); void STATS_UNLOCK(void); void threadlocal_stats_reset(void); void threadlocal_stats_aggregate(struct thread_stats *stats); void slab_stats_aggregate(struct thread_stats *stats, struct slab_stats *out); /* Stat processing functions */ void append_stat(const char *name, ADD_STAT add_stats, conn *c, const char *fmt, ...); enum store_item_type store_item(item *item, int comm, conn *c); #if HAVE_DROP_PRIVILEGES extern void drop_privileges(void); #else #define drop_privileges() #endif /* If supported, give compiler hints for branch prediction. */ #if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) #define __builtin_expect(x, expected_value) (x) #endif #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) memcached-1.4.14/t/0000755000175000017500000000000012005413117010745 500000000000000memcached-1.4.14/t/daemonize.t0000755000175000017500000000134211246331452013037 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 7; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; use File::Temp qw(tempfile); my (undef, $tmpfn) = tempfile(); my $server = new_memcached("-d -P $tmpfn"); my $sock = $server->sock; sleep 0.5; ok(-e $tmpfn, "pid file exists"); ok(-s $tmpfn, "pid file has length"); open (my $fh, $tmpfn) or die; my $readpid = do { local $/; <$fh>; }; chomp $readpid; close ($fh); ok(kill(0, $readpid), "process is still running"); my $stats = mem_stats($sock); is($stats->{pid}, $readpid, "memcached reports same pid as file"); ok($server->new_sock, "opened new socket"); ok(kill(9, $readpid), "sent KILL signal"); sleep 0.5; ok(! $server->new_sock, "failed to open new socket"); memcached-1.4.14/t/slabs_reassign.t0000644000175000017500000000465712005172303014064 00000000000000#!/usr/bin/perl use strict; use warnings; use Test::More tests => 130; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; # Enable manual slab reassign, cap at 6 slabs my $server = new_memcached('-o slab_reassign -m 4'); my $stats = mem_stats($server->sock, ' settings'); is($stats->{slab_reassign}, "yes"); my $sock = $server->sock; # Fill a largeish slab until it evicts (honors the -m 6) my $bigdata = 'x' x 70000; # slab 31 for (1 .. 60) { print $sock "set bfoo$_ 0 0 70000\r\n", $bigdata, "\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key"); } # Fill a smaller slab until it evicts my $smalldata = 'y' x 20000; # slab 25 for (1 .. 60) { print $sock "set sfoo$_ 0 0 20000\r\n", $smalldata, "\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key"); } my $items_before = mem_stats($sock, "items"); isnt($items_before->{"items:31:evicted"}, 0, "slab 31 evicted is nonzero"); isnt($items_before->{"items:25:evicted"}, 0, "slab 25 evicted is nonzero"); my $slabs_before = mem_stats($sock, "slabs"); # Move a large slab to the smaller slab print $sock "slabs reassign 31 25\r\n"; is(scalar <$sock>, "OK\r\n", "slab rebalancer started"); # Still working out how/if to signal the thread. For now, just sleep. sleep 2; # Check that stats counters increased my $slabs_after = mem_stats($sock, "slabs"); $stats = mem_stats($sock); isnt($stats->{slabs_moved}, 0, "slabs moved is nonzero"); # Check that slab stats reflect the change ok($slabs_before->{"31:total_pages"} != $slabs_after->{"31:total_pages"}, "slab 31 pagecount changed"); ok($slabs_before->{"25:total_pages"} != $slabs_after->{"25:total_pages"}, "slab 25 pagecount changed"); # Try to move another slab, see that you can move two in a row print $sock "slabs reassign 31 25\r\n"; like(scalar <$sock>, qr/^OK/, "Cannot re-run against class with empty space"); # Try to move a page backwards. Should complain that source class isn't "safe" # to move from. # TODO: Wait until the above command completes, then try to move it back? # Seems pointless... #print $sock "slabs reassign 25 31\r\n"; #like(scalar <$sock>, qr/^UNSAFE/, "Cannot move an unsafe slab back"); # Try to insert items into both slabs print $sock "set bfoo51 0 0 70000\r\n", $bigdata, "\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key"); print $sock "set sfoo51 0 0 20000\r\n", $smalldata, "\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key"); # Do need to come up with better automated tests for this. memcached-1.4.14/t/noreply.t0000644000175000017500000000230011246331452012544 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 9; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # Test that commands can take 'noreply' parameter. print $sock "flush_all noreply\r\n"; print $sock "flush_all 0 noreply\r\n"; print $sock "verbosity 0 noreply\r\n"; print $sock "add noreply:foo 0 0 1 noreply\r\n1\r\n"; mem_get_is($sock, "noreply:foo", "1"); print $sock "set noreply:foo 0 0 1 noreply\r\n2\r\n"; mem_get_is($sock, "noreply:foo", "2"); print $sock "replace noreply:foo 0 0 1 noreply\r\n3\r\n"; mem_get_is($sock, "noreply:foo", "3"); print $sock "append noreply:foo 0 0 1 noreply\r\n4\r\n"; mem_get_is($sock, "noreply:foo", "34"); print $sock "prepend noreply:foo 0 0 1 noreply\r\n5\r\n"; my @result = mem_gets($sock, "noreply:foo"); ok($result[1] eq "534"); print $sock "cas noreply:foo 0 0 1 $result[0] noreply\r\n6\r\n"; mem_get_is($sock, "noreply:foo", "6"); print $sock "incr noreply:foo 3 noreply\r\n"; mem_get_is($sock, "noreply:foo", "9"); print $sock "decr noreply:foo 2 noreply\r\n"; mem_get_is($sock, "noreply:foo", "7"); print $sock "delete noreply:foo noreply\r\n"; mem_get_is($sock, "noreply:foo"); memcached-1.4.14/t/binary.t0000755000175000017500000005610212005357347012361 00000000000000#!/usr/bin/perl use strict; use warnings; use Test::More tests => 3549; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); ok($server, "started the server"); # Based almost 100% off testClient.py which is: # Copyright (c) 2007 Dustin Sallings # Command constants use constant CMD_GET => 0x00; use constant CMD_SET => 0x01; use constant CMD_ADD => 0x02; use constant CMD_REPLACE => 0x03; use constant CMD_DELETE => 0x04; use constant CMD_INCR => 0x05; use constant CMD_DECR => 0x06; use constant CMD_QUIT => 0x07; use constant CMD_FLUSH => 0x08; use constant CMD_GETQ => 0x09; use constant CMD_NOOP => 0x0A; use constant CMD_VERSION => 0x0B; use constant CMD_GETK => 0x0C; use constant CMD_GETKQ => 0x0D; use constant CMD_APPEND => 0x0E; use constant CMD_PREPEND => 0x0F; use constant CMD_STAT => 0x10; use constant CMD_SETQ => 0x11; use constant CMD_ADDQ => 0x12; use constant CMD_REPLACEQ => 0x13; use constant CMD_DELETEQ => 0x14; use constant CMD_INCREMENTQ => 0x15; use constant CMD_DECREMENTQ => 0x16; use constant CMD_QUITQ => 0x17; use constant CMD_FLUSHQ => 0x18; use constant CMD_APPENDQ => 0x19; use constant CMD_PREPENDQ => 0x1A; use constant CMD_TOUCH => 0x1C; use constant CMD_GAT => 0x1D; use constant CMD_GATQ => 0x1E; use constant CMD_GATK => 0x23; use constant CMD_GATKQ => 0x24; # REQ and RES formats are divided even though they currently share # the same format, since they _could_ differ in the future. use constant REQ_PKT_FMT => "CCnCCnNNNN"; use constant RES_PKT_FMT => "CCnCCnNNNN"; use constant INCRDECR_PKT_FMT => "NNNNN"; use constant MIN_RECV_BYTES => length(pack(RES_PKT_FMT)); use constant REQ_MAGIC => 0x80; use constant RES_MAGIC => 0x81; my $mc = MC::Client->new; # Let's turn on detail stats for all this stuff $mc->stats('detail on'); my $check = sub { my ($key, $orig_flags, $orig_val) = @_; my ($flags, $val, $cas) = $mc->get($key); is($flags, $orig_flags, "Flags is set properly"); ok($val eq $orig_val || $val == $orig_val, $val . " = " . $orig_val); }; my $set = sub { my ($key, $exp, $orig_flags, $orig_value) = @_; $mc->set($key, $orig_value, $orig_flags, $exp); $check->($key, $orig_flags, $orig_value); }; my $empty = sub { my $key = shift; my $rv =()= eval { $mc->get($key) }; is($rv, 0, "Didn't get a result from get"); ok($@->not_found, "We got a not found error when we expected one"); }; my $delete = sub { my ($key, $when) = @_; $mc->delete($key, $when); $empty->($key); }; # diag "Test Version"; my $v = $mc->version; ok(defined $v && length($v), "Proper version: $v"); # Bug 71 { my %stats1 = $mc->stats(''); $mc->flush; my %stats2 = $mc->stats(''); is($stats2{'cmd_flush'}, $stats1{'cmd_flush'} + 1, "Stats not updated on a binary flush"); } # diag "Flushing..."; $mc->flush; # diag "Noop"; $mc->noop; # diag "Simple set/get"; $set->('x', 5, 19, "somevalue"); # diag "Delete"; $delete->('x'); # diag "Flush"; $set->('x', 5, 19, "somevaluex"); $set->('y', 5, 17, "somevaluey"); $mc->flush; $empty->('x'); $empty->('y'); { # diag "Add"; $empty->('i'); $mc->add('i', 'ex', 5, 10); $check->('i', 5, "ex"); my $rv =()= eval { $mc->add('i', "ex2", 10, 5) }; is($rv, 0, "Add didn't return anything"); ok($@->exists, "Expected exists error received"); $check->('i', 5, "ex"); } { # diag "Too big."; $empty->('toobig'); $mc->set('toobig', 'not too big', 10, 10); eval { my $bigval = ("x" x (1024*1024)) . "x"; $mc->set('toobig', $bigval, 10, 10); }; ok($@->too_big, "Was too big"); $empty->('toobig'); } { # diag "Replace"; $empty->('j'); my $rv =()= eval { $mc->replace('j', "ex", 19, 5) }; is($rv, 0, "Replace didn't return anything"); ok($@->not_found, "Expected not_found error received"); $empty->('j'); $mc->add('j', "ex2", 14, 5); $check->('j', 14, "ex2"); $mc->replace('j', "ex3", 24, 5); $check->('j', 24, "ex3"); } { # diag "MultiGet"; $mc->add('xx', "ex", 1, 5); $mc->add('wye', "why", 2, 5); my $rv = $mc->get_multi(qw(xx wye zed)); # CAS is returned with all gets. $rv->{xx}->[2] = 0; $rv->{wye}->[2] = 0; is_deeply($rv->{xx}, [1, 'ex', 0], "X is correct"); is_deeply($rv->{wye}, [2, 'why', 0], "Y is correct"); is(keys(%$rv), 2, "Got only two answers like we expect"); } # diag "Test increment"; $mc->flush; is($mc->incr("x"), 0, "First incr call is zero"); is($mc->incr("x"), 1, "Second incr call is one"); is($mc->incr("x", 211), 212, "Adding 211 gives you 212"); is($mc->incr("x", 2**33), 8589934804, "Blast the 32bit border"); # diag "Issue 48 - incrementing plain text."; { $mc->set("issue48", "text", 0, 0); my $rv =()= eval { $mc->incr('issue48'); }; ok($@ && $@->delta_badval, "Expected invalid value when incrementing text."); $check->('issue48', 0, "text"); $rv =()= eval { $mc->decr('issue48'); }; ok($@ && $@->delta_badval, "Expected invalid value when decrementing text."); $check->('issue48', 0, "text"); } # diag "Test decrement"; $mc->flush; is($mc->incr("x", undef, 5), 5, "Initial value"); is($mc->decr("x"), 4, "Decrease by one"); is($mc->decr("x", 211), 0, "Floor is zero"); { # diag "bug220 my ($rv, $cas) = $mc->set("bug220", "100", 0, 0); my ($irv, $icas) = $mc->incr_cas("bug220", 999); ok($icas != $cas); is($irv, 1099, "Incr amount failed"); my ($flags, $val, $gcas) = $mc->get("bug220"); is($gcas, $icas, "CAS didn't match after incr/gets"); ($irv, $icas) = $mc->incr_cas("bug220", 999); ok($icas != $cas); is($irv, 2098, "Incr amount failed"); ($flags, $val, $gcas) = $mc->get("bug220"); is($gcas, $icas, "CAS didn't match after incr/gets"); } { # diag "bug21"; $mc->add("bug21", "9223372036854775807", 0, 0); is($mc->incr("bug21"), 9223372036854775808, "First incr for bug21."); is($mc->incr("bug21"), 9223372036854775809, "Second incr for bug21."); is($mc->decr("bug21"), 9223372036854775808, "Decr for bug21."); } { # diag "CAS"; $mc->flush; { my $rv =()= eval { $mc->set("x", "bad value", 19, 5, 0x7FFFFFF) }; is($rv, 0, "Empty return on expected failure"); ok($@->not_found, "Error was 'not found' as expected"); } my ($r, $rcas) = $mc->add("x", "original value", 5, 19); my ($flags, $val, $i) = $mc->get("x"); is($val, "original value", "->gets returned proper value"); is($rcas, $i, "Add CAS matched."); { my $rv =()= eval { $mc->set("x", "broken value", 19, 5, $i+1) }; is($rv, 0, "Empty return on expected failure (1)"); ok($@->exists, "Expected error state of 'exists' (1)"); } ($r, $rcas) = $mc->set("x", "new value", 19, 5, $i); my ($newflags, $newval, $newi) = $mc->get("x"); is($newval, "new value", "CAS properly overwrote value"); is($rcas, $newi, "Get CAS matched."); { my $rv =()= eval { $mc->set("x", "replay value", 19, 5, $i) }; is($rv, 0, "Empty return on expected failure (2)"); ok($@->exists, "Expected error state of 'exists' (2)"); } } # diag "Touch commands"; { $mc->flush; $mc->set("totouch", "toast", 0, 1); my $res = $mc->touch("totouch", 10); sleep 2; $check->("totouch", 0, "toast"); $mc->set("totouch", "toast2", 0, 1); my ($flags, $val, $i) = $mc->gat("totouch", 10); is($val, "toast2", "GAT returned correct value"); sleep 2; $check->("totouch", 0, "toast2"); # Test miss as well $mc->set("totouch", "toast3", 0, 1); $res = $mc->touch("totouch", 1); sleep 3; $empty->("totouch"); } # diag "Silent set."; $mc->silent_mutation(::CMD_SETQ, 'silentset', 'silentsetval'); # diag "Silent add."; $mc->silent_mutation(::CMD_ADDQ, 'silentadd', 'silentaddval'); # diag "Silent replace."; { my $key = "silentreplace"; my $extra = pack "NN", 829, 0; $empty->($key); # $mc->send_silent(::CMD_REPLACEQ, $key, 'somevalue', 7278552, $extra, 0); # $empty->($key); $mc->add($key, "xval", 831, 0); $check->($key, 831, 'xval'); $mc->send_silent(::CMD_REPLACEQ, $key, 'somevalue', 7278552, $extra, 0); $check->($key, 829, 'somevalue'); } # diag "Silent delete"; { my $key = "silentdelete"; $empty->($key); $mc->set($key, "some val", 19, 0); $mc->send_silent(::CMD_DELETEQ, $key, '', 772); $empty->($key); } # diag "Silent increment"; { my $key = "silentincr"; my $opaque = 98428747; $empty->($key); $mc->silent_incrdecr(::CMD_INCREMENTQ, $key, 0, 0, 0); is($mc->incr($key, 0), 0, "First call is 0"); $mc->silent_incrdecr(::CMD_INCREMENTQ, $key, 8, 0, 0); is($mc->incr($key, 0), 8); } # diag "Silent decrement"; { my $key = "silentdecr"; my $opaque = 98428147; $empty->($key); $mc->silent_incrdecr(::CMD_DECREMENTQ, $key, 0, 185, 0); is($mc->incr($key, 0), 185); $mc->silent_incrdecr(::CMD_DECREMENTQ, $key, 8, 0, 0); is($mc->incr($key, 0), 177); } # diag "Silent flush"; { my %stats1 = $mc->stats(''); $set->('x', 5, 19, "somevaluex"); $set->('y', 5, 17, "somevaluey"); $mc->send_silent(::CMD_FLUSHQ, '', '', 2775256); $empty->('x'); $empty->('y'); my %stats2 = $mc->stats(''); is($stats2{'cmd_flush'}, $stats1{'cmd_flush'} + 1, "Stats not updated on a binary quiet flush"); } # diag "Append"; { my $key = "appendkey"; my $value = "some value"; $set->($key, 8, 19, $value); $mc->_append_prepend(::CMD_APPEND, $key, " more"); $check->($key, 19, $value . " more"); } # diag "Prepend"; { my $key = "prependkey"; my $value = "some value"; $set->($key, 8, 19, $value); $mc->_append_prepend(::CMD_PREPEND, $key, "prefixed "); $check->($key, 19, "prefixed " . $value); } # diag "Silent append"; { my $key = "appendqkey"; my $value = "some value"; $set->($key, 8, 19, $value); $mc->send_silent(::CMD_APPENDQ, $key, " more", 7284492); $check->($key, 19, $value . " more"); } # diag "Silent prepend"; { my $key = "prependqkey"; my $value = "some value"; $set->($key, 8, 19, $value); $mc->send_silent(::CMD_PREPENDQ, $key, "prefixed ", 7284492); $check->($key, 19, "prefixed " . $value); } # diag "Leaky binary get test."; # # http://code.google.com/p/memcached/issues/detail?id=16 { # Get a new socket so we can speak text to it. my $sock = $server->new_sock; my $max = 1024 * 1024; my $big = "a big value that's > .5M and < 1M. "; while (length($big) * 2 < $max) { $big = $big . $big; } my $biglen = length($big); for(1..100) { my $key = "some_key_$_"; # print STDERR "Key is $key\n"; # print $sock "set $key 0 0 $vallen\r\n$value\r\n"; print $sock "set $key 0 0 $biglen\r\n$big\r\n"; is(scalar <$sock>, "STORED\r\n", "stored big"); my ($f, $v, $c) = $mc->get($key); } } # diag "Test stats settings." { my %stats = $mc->stats('settings'); is(1024, $stats{'maxconns'}); is('NULL', $stats{'domain_socket'}); is('on', $stats{'evictions'}); is('yes', $stats{'cas_enabled'}); } # diag "Test quit commands."; { my $s2 = new_memcached(); my $mc2 = MC::Client->new($s2); $mc2->send_command(CMD_QUITQ, '', '', 0, '', 0); # Five seconds ought to be enough to get hung up on. my $oldalarmt = alarm(5); # Verify we can't read anything. my $bytesread = -1; eval { local $SIG{'ALRM'} = sub { die "timeout" }; my $data = ""; $bytesread = sysread($mc2->{socket}, $data, 24), }; is($bytesread, 0, "Read after quit."); # Restore signal stuff. alarm($oldalarmt); } # diag "Test protocol boundary overruns"; { use List::Util qw[min]; # Attempting some protocol overruns by toying around with the edge # of the data buffer at a few different sizes. This assumes the # boundary is at or around 2048 bytes. for (my $i = 1900; $i < 2100; $i++) { my $k = "test_key_$i"; my $v = 'x' x $i; # diag "Trying $i $k"; my $extra = pack "NN", 82, 0; my $data = $mc->build_command(::CMD_SETQ, $k, $v, 0, $extra, 0); $data .= $mc->build_command(::CMD_SETQ, "alt_$k", "blah", 0, $extra, 0); if (length($data) > 2024) { for (my $j = 2024; $j < min(2096, length($data)); $j++) { $mc->{socket}->send(substr($data, 0, $j)); $mc->flush_socket; sleep(0.001); $mc->{socket}->send(substr($data, $j)); $mc->flush_socket; } } else { $mc->{socket}->send($data); } $mc->flush_socket; $check->($k, 82, $v); $check->("alt_$k", 82, "blah"); } } # Along with the assertion added to the code to verify we're staying # within bounds when we do a stats detail dump (detail turned on at # the top). my %stats = $mc->stats('detail dump'); # This test causes a disconnection. { # diag "Key too large."; my $key = "x" x 365; eval { $mc->get($key, 'should die', 10, 10); }; ok($@->einval, "Invalid key length"); } # ###################################################################### # Test ends around here. # ###################################################################### package MC::Client; use strict; use warnings; use fields qw(socket); use IO::Socket::INET; sub new { my $self = shift; my ($s) = @_; $s = $server unless defined $s; my $sock = $s->sock; $self = fields::new($self); $self->{socket} = $sock; return $self; } sub build_command { my $self = shift; die "Not enough args to send_command" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; $extra_header = '' unless defined $extra_header; my $keylen = length($key); my $vallen = length($val); my $extralen = length($extra_header); my $datatype = 0; # field for future use my $reserved = 0; # field for future use my $totallen = $keylen + $vallen + $extralen; my $ident_hi = 0; my $ident_lo = 0; if ($cas) { $ident_hi = int($cas / 2 ** 32); $ident_lo = int($cas % 2 ** 32); } my $msg = pack(::REQ_PKT_FMT, ::REQ_MAGIC, $cmd, $keylen, $extralen, $datatype, $reserved, $totallen, $opaque, $ident_hi, $ident_lo); my $full_msg = $msg . $extra_header . $key . $val; return $full_msg; } sub send_command { my $self = shift; die "Not enough args to send_command" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; my $full_msg = $self->build_command($cmd, $key, $val, $opaque, $extra_header, $cas); my $sent = $self->{socket}->send($full_msg); die("Send failed: $!") unless $sent; if($sent != length($full_msg)) { die("only sent $sent of " . length($full_msg) . " bytes"); } } sub flush_socket { my $self = shift; $self->{socket}->flush; } # Send a silent command and ensure it doesn't respond. sub send_silent { my $self = shift; die "Not enough args to send_silent" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; $self->send_command($cmd, $key, $val, $opaque, $extra_header, $cas); $self->send_command(::CMD_NOOP, '', '', $opaque + 1); my ($ropaque, $data) = $self->_handle_single_response; Test::More::is($ropaque, $opaque + 1); } sub silent_mutation { my $self = shift; my ($cmd, $key, $value) = @_; $empty->($key); my $extra = pack "NN", 82, 0; $mc->send_silent($cmd, $key, $value, 7278552, $extra, 0); $check->($key, 82, $value); } sub _handle_single_response { my $self = shift; my $myopaque = shift; my $hdr = ""; while(::MIN_RECV_BYTES - length($hdr) > 0) { $self->{socket}->recv(my $response, ::MIN_RECV_BYTES - length($hdr)); $hdr .= $response; } Test::More::is(length($hdr), ::MIN_RECV_BYTES, "Expected read length"); my ($magic, $cmd, $keylen, $extralen, $datatype, $status, $remaining, $opaque, $ident_hi, $ident_lo) = unpack(::RES_PKT_FMT, $hdr); Test::More::is($magic, ::RES_MAGIC, "Got proper response magic"); my $cas = ($ident_hi * 2 ** 32) + $ident_lo; return ($opaque, '', $cas, 0) if($remaining == 0); # fetch the value my $rv=""; while($remaining - length($rv) > 0) { $self->{socket}->recv(my $buf, $remaining - length($rv)); $rv .= $buf; } if(length($rv) != $remaining) { my $found = length($rv); die("Expected $remaining bytes, got $found"); } if (defined $myopaque) { Test::More::is($opaque, $myopaque, "Expected opaque"); } else { Test::More::pass("Implicit pass since myopaque is undefined"); } if ($status) { die MC::Error->new($status, $rv); } return ($opaque, $rv, $cas, $keylen); } sub _do_command { my $self = shift; die unless @_ >= 3; my ($cmd, $key, $val, $extra_header, $cas) = @_; $extra_header = '' unless defined $extra_header; my $opaque = int(rand(2**32)); $self->send_command($cmd, $key, $val, $opaque, $extra_header, $cas); my (undef, $rv, $rcas) = $self->_handle_single_response($opaque); return ($rv, $rcas); } sub _incrdecr_header { my $self = shift; my ($amt, $init, $exp) = @_; my $amt_hi = int($amt / 2 ** 32); my $amt_lo = int($amt % 2 ** 32); my $init_hi = int($init / 2 ** 32); my $init_lo = int($init % 2 ** 32); my $extra_header = pack(::INCRDECR_PKT_FMT, $amt_hi, $amt_lo, $init_hi, $init_lo, $exp); return $extra_header; } sub _incrdecr_cas { my $self = shift; my ($cmd, $key, $amt, $init, $exp) = @_; my ($data, $rcas) = $self->_do_command($cmd, $key, '', $self->_incrdecr_header($amt, $init, $exp)); my $header = substr $data, 0, 8, ''; my ($resp_hi, $resp_lo) = unpack "NN", $header; my $resp = ($resp_hi * 2 ** 32) + $resp_lo; return $resp, $rcas; } sub _incrdecr { my $self = shift; my ($v, $c) = $self->_incrdecr_cas(@_); return $v } sub silent_incrdecr { my $self = shift; my ($cmd, $key, $amt, $init, $exp) = @_; my $opaque = 8275753; $mc->send_silent($cmd, $key, '', $opaque, $mc->_incrdecr_header($amt, $init, $exp)); } sub stats { my $self = shift; my $key = shift; my $cas = 0; my $opaque = int(rand(2**32)); $self->send_command(::CMD_STAT, $key, '', $opaque, '', $cas); my %rv = (); my $found_key = ''; my $found_val = ''; do { my ($op, $data, $cas, $keylen) = $self->_handle_single_response($opaque); if($keylen > 0) { $found_key = substr($data, 0, $keylen); $found_val = substr($data, $keylen); $rv{$found_key} = $found_val; } else { $found_key = ''; } } while($found_key ne ''); return %rv; } sub get { my $self = shift; my $key = shift; my ($rv, $cas) = $self->_do_command(::CMD_GET, $key, '', ''); my $header = substr $rv, 0, 4, ''; my $flags = unpack("N", $header); return ($flags, $rv, $cas); } sub get_multi { my $self = shift; my @keys = @_; for (my $i = 0; $i < @keys; $i++) { $self->send_command(::CMD_GETQ, $keys[$i], '', $i, '', 0); } my $terminal = @keys + 10; $self->send_command(::CMD_NOOP, '', '', $terminal); my %return; while (1) { my ($opaque, $data) = $self->_handle_single_response; last if $opaque == $terminal; my $header = substr $data, 0, 4, ''; my $flags = unpack("N", $header); $return{$keys[$opaque]} = [$flags, $data]; } return %return if wantarray; return \%return; } sub touch { my $self = shift; my ($key, $expire) = @_; my $extra_header = pack "N", $expire; my $cas = 0; return $self->_do_command(::CMD_TOUCH, $key, '', $extra_header, $cas); } sub gat { my $self = shift; my $key = shift; my $expire = shift; my $extra_header = pack "N", $expire; my ($rv, $cas) = $self->_do_command(::CMD_GAT, $key, '', $extra_header); my $header = substr $rv, 0, 4, ''; my $flags = unpack("N", $header); return ($flags, $rv, $cas); } sub version { my $self = shift; return $self->_do_command(::CMD_VERSION, '', ''); } sub flush { my $self = shift; return $self->_do_command(::CMD_FLUSH, '', ''); } sub add { my $self = shift; my ($key, $val, $flags, $expire) = @_; my $extra_header = pack "NN", $flags, $expire; my $cas = 0; return $self->_do_command(::CMD_ADD, $key, $val, $extra_header, $cas); } sub set { my $self = shift; my ($key, $val, $flags, $expire, $cas) = @_; my $extra_header = pack "NN", $flags, $expire; return $self->_do_command(::CMD_SET, $key, $val, $extra_header, $cas); } sub _append_prepend { my $self = shift; my ($cmd, $key, $val, $cas) = @_; return $self->_do_command($cmd, $key, $val, '', $cas); } sub replace { my $self = shift; my ($key, $val, $flags, $expire) = @_; my $extra_header = pack "NN", $flags, $expire; my $cas = 0; return $self->_do_command(::CMD_REPLACE, $key, $val, $extra_header, $cas); } sub delete { my $self = shift; my ($key) = @_; return $self->_do_command(::CMD_DELETE, $key, ''); } sub incr { my $self = shift; my ($key, $amt, $init, $exp) = @_; $amt = 1 unless defined $amt; $init = 0 unless defined $init; $exp = 0 unless defined $exp; return $self->_incrdecr(::CMD_INCR, $key, $amt, $init, $exp); } sub incr_cas { my $self = shift; my ($key, $amt, $init, $exp) = @_; $amt = 1 unless defined $amt; $init = 0 unless defined $init; $exp = 0 unless defined $exp; return $self->_incrdecr_cas(::CMD_INCR, $key, $amt, $init, $exp); } sub decr { my $self = shift; my ($key, $amt, $init, $exp) = @_; $amt = 1 unless defined $amt; $init = 0 unless defined $init; $exp = 0 unless defined $exp; return $self->_incrdecr(::CMD_DECR, $key, $amt, $init, $exp); } sub noop { my $self = shift; return $self->_do_command(::CMD_NOOP, '', ''); } package MC::Error; use strict; use warnings; use constant ERR_UNKNOWN_CMD => 0x81; use constant ERR_NOT_FOUND => 0x1; use constant ERR_EXISTS => 0x2; use constant ERR_TOO_BIG => 0x3; use constant ERR_EINVAL => 0x4; use constant ERR_NOT_STORED => 0x5; use constant ERR_DELTA_BADVAL => 0x6; use overload '""' => sub { my $self = shift; return "Memcache Error ($self->[0]): $self->[1]"; }; sub new { my $class = shift; my $error = [@_]; my $self = bless $error, (ref $class || $class); return $self; } sub not_found { my $self = shift; return $self->[0] == ERR_NOT_FOUND; } sub exists { my $self = shift; return $self->[0] == ERR_EXISTS; } sub too_big { my $self = shift; return $self->[0] == ERR_TOO_BIG; } sub delta_badval { my $self = shift; return $self->[0] == ERR_DELTA_BADVAL; } sub einval { my $self = shift; return $self->[0] == ERR_EINVAL; } # vim: filetype=perl memcached-1.4.14/t/udp.t0000755000175000017500000002272711710331141011655 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 48; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; use constant IS_ASCII => 0; use constant IS_BINARY => 1; use constant ENTRY_EXISTS => 0; use constant ENTRY_MISSING => 1; use constant BIN_REQ_MAGIC => 0x80; use constant BIN_RES_MAGIC => 0x81; use constant CMD_GET => 0x00; use constant CMD_SET => 0x01; use constant CMD_ADD => 0x02; use constant CMD_REPLACE => 0x03; use constant CMD_DELETE => 0x04; use constant CMD_INCR => 0x05; use constant CMD_DECR => 0x06; use constant CMD_APPEND => 0x0E; use constant CMD_PREPEND => 0x0F; use constant REQ_PKT_FMT => "CCnCCnNNNN"; use constant RES_PKT_FMT => "CCnCCnNNNN"; use constant INCRDECR_PKT_FMT => "NNNNN"; use constant MIN_RECV_BYTES => length(pack(RES_PKT_FMT)); my $server = new_memcached(); my $sock = $server->sock; # set foo (and should get it) print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); my $usock = $server->new_udp_sock or die "Can't bind : $@\n"; # testing sequence of request ids for my $offt (1, 1, 2) { my $req = 160 + $offt; my $res = send_udp_request($usock, $req, "get foo\r\n"); ok($res, "got result"); is(keys %$res, 1, "one key (one packet)"); ok($res->{0}, "only got seq number 0"); is(substr($res->{0}, 8), "VALUE foo 0 6\r\nfooval\r\nEND\r\n"); is(hexify(substr($res->{0}, 0, 2)), hexify(pack("n", $req)), "udp request number in response ($req) is correct"); } # op tests for my $prot (::IS_ASCII,::IS_BINARY) { udp_set_test($prot,45,"aval$prot","1",0,0); udp_set_test($prot,45,"bval$prot","abcd" x 1024,0,0); udp_get_test($prot,45,"aval$prot","1",::ENTRY_EXISTS); udp_get_test($prot,45,"404$prot","1",::ENTRY_MISSING); udp_incr_decr_test($prot,45,"aval$prot","1","incr",1); udp_incr_decr_test($prot,45,"aval$prot","1","decr",2); udp_delete_test($prot,45,"aval$prot"); } sub udp_set_test { my ($protocol, $req_id, $key, $value, $flags, $exp) = @_; my $req = ""; my $val_len = length($value); if ($protocol == ::IS_ASCII) { $req = "set $key $flags $exp $val_len\r\n$value\r\n"; } elsif ($protocol == ::IS_BINARY) { my $key_len = length($key); my $extra = pack "NN",$flags,$exp; my $extra_len = length($extra); my $total_len = $val_len + $extra_len + $key_len; $req = pack(::REQ_PKT_FMT, ::BIN_REQ_MAGIC, ::CMD_SET, $key_len, $extra_len, 0, 0, $total_len, 0, 0, 0); $req .= $extra . $key . $value; } my $datagrams = send_udp_request($usock, $req_id, $req); my $resp = construct_udp_message($datagrams); if ($protocol == ::IS_ASCII) { is($resp,"STORED\r\n","Store key $key using ASCII protocol"); } elsif ($protocol == ::IS_BINARY) { my ($resp_magic, $resp_op_code, $resp_key_len, $resp_extra_len, $resp_data_type, $resp_status, $resp_total_len, $resp_opaque, $resp_ident_hi, $resp_ident_lo) = unpack(::RES_PKT_FMT, $resp); is($resp_status,"0","Store key $key using binary protocol"); } } sub udp_get_test { my ($protocol, $req_id, $key, $value, $exists) = @_; my $key_len = length($key); my $value_len = length($value); my $req = ""; if ($protocol == ::IS_ASCII) { $req = "get $key\r\n"; } elsif ($protocol == ::IS_BINARY) { $req = pack(::REQ_PKT_FMT, ::BIN_REQ_MAGIC, ::CMD_GET, $key_len, 0, 0, 0, $key_len, 0, 0, 0); $req .= $key; } my $datagrams = send_udp_request($usock, $req_id, $req); my $resp = construct_udp_message($datagrams); if ($protocol == ::IS_ASCII) { if ($exists == ::ENTRY_EXISTS) { is($resp,"VALUE $key 0 $value_len\r\n$value\r\nEND\r\n","Retrieve entry with key $key using ASCII protocol"); } else { is($resp,"END\r\n","Retrieve non existing entry with key $key using ASCII protocol"); } } elsif ($protocol == ::IS_BINARY) { my ($resp_magic, $resp_op_code, $resp_key_len, $resp_extra_len, $resp_data_type, $resp_status, $resp_total_len, $resp_opaque, $resp_ident_hi, $resp_ident_lo) = unpack(::RES_PKT_FMT, $resp); if ($exists == ::ENTRY_EXISTS) { is($resp_status,"0","Retrieve entry with key $key using binary protocol"); is(substr($resp,::MIN_RECV_BYTES + $resp_extra_len + $resp_key_len, $value_len),$value,"Value for key $key retrieved with binary protocol matches"); } else { is($resp_status,"1","Retrieve non existing entry with key $key using binary protocol"); } } } sub udp_delete_test { my ($protocol, $req_id, $key) = @_; my $req = ""; my $key_len = length($key); if ($protocol == ::IS_ASCII) { $req = "delete $key\r\n"; } elsif ($protocol == ::IS_BINARY) { $req = pack(::REQ_PKT_FMT, ::BIN_REQ_MAGIC, ::CMD_DELETE, $key_len, 0, 0, 0, $key_len, 0, 0, 0); $req .= $key; } my $datagrams = send_udp_request($usock, $req_id, $req); my $resp = construct_udp_message($datagrams); if ($protocol == ::IS_ASCII) { is($resp,"DELETED\r\n","Delete key $key using ASCII protocol"); } elsif ($protocol == ::IS_BINARY) { my ($resp_magic, $resp_op_code, $resp_key_len, $resp_extra_len, $resp_data_type, $resp_status, $resp_total_len, $resp_opaque, $resp_ident_hi, $resp_ident_lo) = unpack(::RES_PKT_FMT, $resp); is($resp_status,"0","Delete key $key using binary protocol"); } } sub udp_incr_decr_test { my ($protocol, $req_id, $key, $val, $optype, $init_val) = @_; my $req = ""; my $key_len = length($key); my $expected_value = 0; my $acmd = "incr"; my $bcmd = ::CMD_INCR; if ($optype eq "incr") { $expected_value = $init_val + $val; } else { $acmd = "decr"; $bcmd = ::CMD_DECR; $expected_value = $init_val - $val; } if ($protocol == ::IS_ASCII) { $req = "$acmd $key $val\r\n"; } elsif ($protocol == ::IS_BINARY) { my $extra = pack(::INCRDECR_PKT_FMT, ($val / 2 ** 32),($val % 2 ** 32), 0, 0, 0); my $extra_len = length($extra); $req = pack(::REQ_PKT_FMT, ::BIN_REQ_MAGIC, $bcmd, $key_len, $extra_len, 0, 0, $key_len + $extra_len, 0, 0, 0); $req .= $extra . $key; } my $datagrams = send_udp_request($usock, $req_id, $req); my $resp = construct_udp_message($datagrams); if ($protocol == ::IS_ASCII) { is($resp,"$expected_value\r\n","perform $acmd math operation on key $key with ASCII protocol"); } elsif ($protocol == ::IS_BINARY) { my ($resp_magic, $resp_op_code, $resp_key_len, $resp_extra_len, $resp_data_type, $resp_status, $resp_total_len, $resp_opaque, $resp_ident_hi, $resp_ident_lo) = unpack(::RES_PKT_FMT, $resp); is($resp_status,"0","perform $acmd math operation on key $key with binary protocol"); my ($resp_hi,$resp_lo) = unpack("NN",substr($resp,::MIN_RECV_BYTES + $resp_extra_len + $resp_key_len, $resp_total_len - $resp_extra_len - $resp_key_len)); is(($resp_hi * 2 ** 32) + $resp_lo,$expected_value,"validate result of binary protocol math operation $acmd . Expected value $expected_value") } } sub construct_udp_message { my $datagrams = shift; my $num_datagram = keys (%$datagrams); my $msg = ""; my $cur_dg =""; my $cur_udp_header =""; for (my $cur_dg_index = 0; $cur_dg_index < $num_datagram; $cur_dg_index++) { $cur_dg = $datagrams->{$cur_dg_index}; isnt($cur_dg,"","missing datagram for segment $cur_dg_index"); $cur_udp_header=substr($cur_dg, 0, 8); $msg .= substr($cur_dg,8); } return $msg; } sub hexify { my $val = shift; $val =~ s/(.)/sprintf("%02x", ord($1))/egs; return $val; } # returns undef on select timeout, or hashref of "seqnum" -> payload (including headers) # verifies that resp_id is equal to id sent in request # ensures consistency in num packets that make up response sub send_udp_request { my ($sock, $reqid, $req) = @_; my $pkt = pack("nnnn", $reqid, 0, 1, 0); # request id (opaque), seq num, #packets, reserved (must be 0) $pkt .= $req; my $fail = sub { my $msg = shift; warn " FAILING send_udp because: $msg\n"; return undef; }; return $fail->("send") unless send($sock, $pkt, 0); my $ret = {}; my $got = 0; # packets got my $numpkts = undef; while (!defined($numpkts) || $got < $numpkts) { my $rin = ''; vec($rin, fileno($sock), 1) = 1; my $rout; return $fail->("timeout after $got packets") unless select($rout = $rin, undef, undef, 1.5); my $res; my $sender = $sock->recv($res, 1500, 0); my ($resid, $seq, $this_numpkts, $resv) = unpack("nnnn", substr($res, 0, 8)); die "Response ID of $resid doesn't match request if of $reqid" unless $resid == $reqid; die "Reserved area not zero" unless $resv == 0; die "num packets changed midstream!" if defined $numpkts && $this_numpkts != $numpkts; $numpkts = $this_numpkts; $ret->{$seq} = $res; $got++; } return $ret; } __END__ $sender = recv($usock, $ans, 1050, 0); __END__ $usock->send ($hispaddr = recv(SOCKET, $rtime, 4, 0)) || die "recv: $!"; ($port, $hisiaddr) = sockaddr_in($hispaddr); $host = gethostbyaddr($hisiaddr, AF_INET); $histime = unpack("N", $rtime) - $SECS_of_70_YEARS ; memcached-1.4.14/t/dash-M.t0000644000175000017500000000132511304704376012177 00000000000000#!/usr/bin/perl use strict; use Test::More; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached('-M -m 1'); my $sock = $server->sock; my $value = "B" x 8192; my $vallen = length($value); my $resp = "STORED\r\n"; my $key = 0; while($resp eq "STORED\r\n") { print $sock "set dash$key 0 0 $vallen\r\n$value\r\n"; $key++; $resp = scalar <$sock>; } my $max_stored = $key - 1; plan tests => $max_stored + 1; print $sock "set dash$key 0 0 $vallen\r\n$value\r\n"; is(scalar <$sock>, "SERVER_ERROR out of memory storing object\r\n", "failed to add another one."); for($key = 0; $key < $max_stored; $key++) { mem_get_is $sock, "dash$key", $value, "Failed at dash$key"; } memcached-1.4.14/t/issue_14.t0000644000175000017500000000144611446413300012515 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 21; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $value = "B"x66560; my $key = 0; for ($key = 0; $key < 10; $key++) { print $sock "set key$key 0 2 66560\r\n$value\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } #print $sock "stats slabs" my $first_stats = mem_stats($sock, "slabs"); my $first_malloc = $first_stats->{total_malloced}; sleep(4); for ($key = 10; $key < 20; $key++) { print $sock "set key$key 0 2 66560\r\n$value\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } my $second_stats = mem_stats($sock, "slabs"); my $second_malloc = $second_stats->{total_malloced}; is ($second_malloc, $first_malloc, "Memory grows..") memcached-1.4.14/t/bogus-commands.t0000755000175000017500000000041711246331452014004 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 1; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; print $sock "boguscommand slkdsldkfjsd\r\n"; is(scalar <$sock>, "ERROR\r\n", "got error back"); memcached-1.4.14/t/whitespace.t0000755000175000017500000000237512005413117013220 00000000000000#!/usr/bin/perl use strict; use FindBin qw($Bin); our @files; BEGIN { chdir "$Bin/.." or die; my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am README README.md); push(@exempted, glob("doc/*.xml")); push(@exempted, glob("doc/xml2rfc/*.xsl")); push(@exempted, glob("m4/*backport*m4")); push(@exempted, glob("*.orig")); my %exempted_hash = map { $_ => 1 } @exempted; my @stuff = split /\0/, `git ls-files -z -c -m -o --exclude-standard`; @files = grep { ! $exempted_hash{$_} } @stuff; # We won't find any files if git isn't installed. If git isn't # installed, they're probably not doing any useful development, or # at the very least am will clean up whitespace when we receive # their patch. unless (@files) { use Test::More; plan skip_all => "Skipping tests probably because you don't have git."; exit 0; } } use Test::More tests => scalar(@files); foreach my $f (@files) { open(my $fh, $f) or die "Cannot open file $f: $!"; my $before = do { local $/; <$fh>; }; close ($fh); my $after = $before; $after =~ s/\t/ /g; $after =~ s/ +$//mg; $after .= "\n" unless $after =~ /\n$/; ok ($after eq $before, "$f (see devtools/clean-whitespace.pl)"); } memcached-1.4.14/t/issue_67.t0000644000175000017500000000462311701635506012535 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 22; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; use Carp qw(croak); use Cwd; my $builddir = getcwd; $ENV{'MEMCACHED_PORT_FILENAME'} = "/tmp/ports.$$"; sub read_ports { my %rv = (); open(my $f, "/tmp/ports.$$") || die("Can't open ports file."); while(<$f>) { my ($type, $port) = split(/:\s+/); $rv{$type} = $port + 0; } unlink "/tmp/ports.$$"; return %rv; } sub validate_port { my ($name, $got, $expected) = @_; # diag "Wanted $expected, got $got"; if ($expected == -1) { ok(!defined($got), "$name expected no port, got $got"); } elsif ($expected == 0) { ok($got != 11211, "$name expected random port (got $got)"); } else { is($got, $expected, "$name"); } } sub run_server { my ($args) = @_; my $exe = "$builddir/memcached-debug"; croak("memcached binary doesn't exist. Haven't run 'make' ?\n") unless -e $exe; my $childpid = fork(); my $root = ''; $root = "-u root" if ($< == 0); my $cmd = "$builddir/timedrun 10 $exe $root $args"; unless($childpid) { exec $cmd; exit; # NOTREACHED } for (1..20) { if (-f "/tmp/ports.$$") { return Memcached::Handle->new(pid => $childpid); } select undef, undef, undef, 0.10; } croak "Failed to start server."; } sub when { my ($name, $params, $expected_tcp, $expected_udp) = @_; my $server = run_server($params); my %ports = read_ports(); validate_port($name, $ports{'TCP INET'}, $expected_tcp); validate_port($name, $ports{'UDP INET'}, $expected_udp); } # Disabling the defaults since it conflicts with a running instance. # when('no arguments', '', 11211, 11211); when('specifying tcp port', '-p 11212', 11212, 11212); when('specifying udp port', '-U 11222', 11222, 11222); when('specifying tcp ephemeral port', '-p -1', 0, 0); when('specifying udp ephemeral port', '-U -1', 0, 0); when('tcp port disabled', '-p 0', -1, -1); when('udp port disabled', '-U 0', -1, -1); when('specifying tcp and udp ports', '-p 11232 -U 11233', 11232, 11233); when('specifying tcp and disabling udp', '-p 11242 -U 0', 11242, -1); when('specifying udp and disabling tcp', '-p -1 -U 11252', 0, 11252); when('specifying tcp and ephemeral udp', '-p 11262 -U -1', 11262, 0); when('specifying udp and ephemeral tcp', '-p -1 -U 11272', 0, 11272); memcached-1.4.14/t/stats.t0000755000175000017500000001200011701635506012216 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 95; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; ## Output looks like this: ## ## STAT pid 22969 ## STAT uptime 13 ## STAT time 1259170891 ## STAT version 1.4.3 ## STAT libevent 1.4.13-stable. ## STAT pointer_size 32 ## STAT rusage_user 0.001198 ## STAT rusage_system 0.003523 ## STAT curr_connections 10 ## STAT total_connections 11 ## STAT connection_structures 11 ## STAT cmd_get 0 ## STAT cmd_set 0 ## STAT cmd_flush 0 ## STAT get_hits 0 ## STAT get_misses 0 ## STAT delete_misses 0 ## STAT delete_hits 0 ## STAT incr_misses 0 ## STAT incr_hits 0 ## STAT decr_misses 0 ## STAT decr_hits 0 ## STAT cas_misses 0 ## STAT cas_hits 0 ## STAT cas_badval 0 ## STAT auth_cmds 0 ## STAT auth_unknowns 0 ## STAT bytes_read 7 ## STAT bytes_written 0 ## STAT limit_maxbytes 67108864 ## STAT accepting_conns 1 ## STAT listen_disabled_num 0 ## STAT threads 4 ## STAT conn_yields 0 ## STAT bytes 0 ## STAT curr_items 0 ## STAT total_items 0 ## STAT evictions 0 ## STAT reclaimed 0 # note that auth stats are tested in auth specfic tests my $stats = mem_stats($sock); # Test number of keys is(scalar(keys(%$stats)), 48, "48 stats values"); # Test initial state foreach my $key (qw(curr_items total_items bytes cmd_get cmd_set get_hits evictions get_misses bytes_written delete_hits delete_misses incr_hits incr_misses decr_hits decr_misses listen_disabled_num)) { is($stats->{$key}, 0, "initial $key is zero"); } is($stats->{accepting_conns}, 1, "initial accepting_conns is one"); # Do some operations print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); my $stats = mem_stats($sock); foreach my $key (qw(total_items curr_items cmd_get cmd_set get_hits)) { is($stats->{$key}, 1, "after one set/one get $key is 1"); } my $cache_dump = mem_stats($sock, " cachedump 1 100"); ok(defined $cache_dump->{'foo'}, "got foo from cachedump"); print $sock "delete foo\r\n"; is(scalar <$sock>, "DELETED\r\n", "deleted foo"); my $stats = mem_stats($sock); is($stats->{delete_hits}, 1); is($stats->{delete_misses}, 0); print $sock "delete foo\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't delete foo again"); my $stats = mem_stats($sock); is($stats->{delete_hits}, 1); is($stats->{delete_misses}, 1); # incr stats sub check_incr_stats { my ($ih, $im, $dh, $dm) = @_; my $stats = mem_stats($sock); is($stats->{incr_hits}, $ih); is($stats->{incr_misses}, $im); is($stats->{decr_hits}, $dh); is($stats->{decr_misses}, $dm); } print $sock "incr i 1\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't incr a missing thing"); check_incr_stats(0, 1, 0, 0); print $sock "decr d 1\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't decr a missing thing"); check_incr_stats(0, 1, 0, 1); print $sock "set n 0 0 1\r\n0\r\n"; is(scalar <$sock>, "STORED\r\n", "stored n"); print $sock "incr n 3\r\n"; is(scalar <$sock>, "3\r\n", "incr works"); check_incr_stats(1, 1, 0, 1); print $sock "decr n 1\r\n"; is(scalar <$sock>, "2\r\n", "decr works"); check_incr_stats(1, 1, 1, 1); # cas stats sub check_cas_stats { my ($ch, $cm, $cb) = @_; my $stats = mem_stats($sock); is($stats->{cas_hits}, $ch); is($stats->{cas_misses}, $cm); is($stats->{cas_badval}, $cb); } check_cas_stats(0, 0, 0); print $sock "cas c 0 0 1 99999999\r\nz\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "missed cas"); check_cas_stats(0, 1, 0); print $sock "set c 0 0 1\r\nx\r\n"; is(scalar <$sock>, "STORED\r\n", "stored c"); my ($id, $v) = mem_gets($sock, 'c'); is('x', $v, 'got the expected value'); print $sock "cas c 0 0 1 99999999\r\nz\r\n"; is(scalar <$sock>, "EXISTS\r\n", "missed cas"); check_cas_stats(0, 1, 1); my ($newid, $v) = mem_gets($sock, 'c'); is('x', $v, 'got the expected value'); print $sock "cas c 0 0 1 $id\r\nz\r\n"; is(scalar <$sock>, "STORED\r\n", "good cas"); check_cas_stats(1, 1, 1); my ($newid, $v) = mem_gets($sock, 'c'); is('z', $v, 'got the expected value'); my $settings = mem_stats($sock, ' settings'); is(1024, $settings->{'maxconns'}); is('NULL', $settings->{'domain_socket'}); is('on', $settings->{'evictions'}); is('yes', $settings->{'cas_enabled'}); is('no', $settings->{'auth_enabled_sasl'}); print $sock "stats reset\r\n"; is(scalar <$sock>, "RESET\r\n", "good stats reset"); my $stats = mem_stats($sock); is(0, $stats->{'cmd_get'}); is(0, $stats->{'cmd_set'}); is(0, $stats->{'get_hits'}); is(0, $stats->{'get_misses'}); is(0, $stats->{'delete_misses'}); is(0, $stats->{'delete_hits'}); is(0, $stats->{'incr_misses'}); is(0, $stats->{'incr_hits'}); is(0, $stats->{'decr_misses'}); is(0, $stats->{'decr_hits'}); is(0, $stats->{'cas_misses'}); is(0, $stats->{'cas_hits'}); is(0, $stats->{'cas_badval'}); is(0, $stats->{'evictions'}); is(0, $stats->{'reclaimed'}); print $sock "flush_all\r\n"; is(scalar <$sock>, "OK\r\n", "flushed"); my $stats = mem_stats($sock); is($stats->{cmd_flush}, 1, "after one flush cmd_flush is 1"); memcached-1.4.14/t/stats-detail.t0000644000175000017500000000410511446413300013452 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 24; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $expire; print $sock "stats detail dump\r\n"; is(scalar <$sock>, "END\r\n", "verified empty stats at start"); print $sock "stats detail on\r\n"; is(scalar <$sock>, "OK\r\n", "detail collection turned on"); print $sock "set foo:123 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 0 hit 0 set 1 del 0\r\n", "details after set"); is(scalar <$sock>, "END\r\n", "end of details"); mem_get_is($sock, "foo:123", "fooval"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 1 del 0\r\n", "details after get with hit"); is(scalar <$sock>, "END\r\n", "end of details"); mem_get_is($sock, "foo:124", undef); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 2 hit 1 set 1 del 0\r\n", "details after get without hit"); is(scalar <$sock>, "END\r\n", "end of details"); print $sock "delete foo:125\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "sent delete command"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 2 hit 1 set 1 del 1\r\n", "details after delete"); is(scalar <$sock>, "END\r\n", "end of details"); print $sock "stats reset\r\n"; is(scalar <$sock>, "RESET\r\n", "stats cleared"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "END\r\n", "empty stats after clear"); mem_get_is($sock, "foo:123", "fooval"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 0 del 0\r\n", "details after clear and get"); is(scalar <$sock>, "END\r\n", "end of details"); print $sock "stats detail off\r\n"; is(scalar <$sock>, "OK\r\n", "detail collection turned off"); mem_get_is($sock, "foo:124", undef); mem_get_is($sock, "foo:123", "fooval"); print $sock "stats detail dump\r\n"; is(scalar <$sock>, "PREFIX foo get 1 hit 1 set 0 del 0\r\n", "details after stats turned off"); is(scalar <$sock>, "END\r\n", "end of details"); memcached-1.4.14/t/issue_183.t0000644000175000017500000000120511620331123012571 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 5; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; print $sock "set key 0 0 1\r\n1\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $s1 = mem_stats($sock); my $r1 = $s1->{"reclaimed"}; is ($r1, "0", "Objects should not be reclaimed"); sleep(2); print $sock "flush_all\r\n"; is (scalar <$sock>, "OK\r\n", "Cache flushed"); print $sock "set key 0 0 1\r\n1\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $s2 = mem_stats($sock); my $r2 = $s2->{"reclaimed"}; is ($r2, "1", "Objects should be reclaimed"); memcached-1.4.14/t/issue_152.t0000644000175000017500000000060611606254362012606 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 2; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $key = "a"x251; print $sock "set a 1 0 1\r\na\r\n"; is (scalar <$sock>, "STORED\r\n", "Stored key"); print $sock "get a $key\r\n"; is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n", "illegal key"); memcached-1.4.14/t/issue_42.t0000644000175000017500000000077411701635506012531 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 11; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $value = "B"x10; my $key = 0; for ($key = 0; $key < 10; $key++) { print $sock "set key$key 0 0 10\r\n$value\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } my $first_stats = mem_stats($sock, "slabs"); my $req = $first_stats->{"1:mem_requested"}; ok ($req == "640" || $req == "800", "Check allocated size"); memcached-1.4.14/t/cas.t0000644000175000017500000001113511701635506011633 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 43; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $sock2 = $server->new_sock; my @result; my @result2; ok($sock != $sock2, "have two different connections open"); sub check_args { my ($line, $name) = @_; my $svr = new_memcached(); my $s = $svr->sock; print $s $line; is(scalar <$s>, "CLIENT_ERROR bad command line format\r\n", $name); undef $svr; } check_args "cas bad blah 0 0 0\r\n\r\n", "bad flags"; check_args "cas bad 0 blah 0 0\r\n\r\n", "bad exp"; check_args "cas bad 0 0 blah 0\r\n\r\n", "bad cas"; check_args "cas bad 0 0 0 blah\r\n\r\n", "bad size"; # gets foo (should not exist) print $sock "gets foo\r\n"; is(scalar <$sock>, "END\r\n", "gets failed"); # set foo print $sock "set foo 0 0 6\r\nbarval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored barval"); # gets foo and verify identifier exists @result = mem_gets($sock, "foo"); mem_gets_is($sock,$result[0],"foo","barval"); # cas fail print $sock "cas foo 0 0 6 123\r\nbarva2\r\n"; is(scalar <$sock>, "EXISTS\r\n", "cas failed for foo"); # gets foo - success @result = mem_gets($sock, "foo"); mem_gets_is($sock,$result[0],"foo","barval"); # cas success print $sock "cas foo 0 0 6 $result[0]\r\nbarva2\r\n"; is(scalar <$sock>, "STORED\r\n", "cas success, set foo"); # cas failure (reusing the same key) print $sock "cas foo 0 0 6 $result[0]\r\nbarva2\r\n"; is(scalar <$sock>, "EXISTS\r\n", "reusing a CAS ID"); # delete foo print $sock "delete foo\r\n"; is(scalar <$sock>, "DELETED\r\n", "deleted foo"); # cas missing print $sock "cas foo 0 0 6 $result[0]\r\nbarva2\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "cas failed, foo does not exist"); # cas empty print $sock "cas foo 0 0 6 \r\nbarva2\r\n"; is(scalar <$sock>, "ERROR\r\n", "cas empty, throw error"); # cant parse barval2\r\n is(scalar <$sock>, "ERROR\r\n", "error out on barval2 parsing"); # set foo1 print $sock "set foo1 0 0 1\r\n1\r\n"; is(scalar <$sock>, "STORED\r\n", "set foo1"); # set foo2 print $sock "set foo2 0 0 1\r\n2\r\n"; is(scalar <$sock>, "STORED\r\n", "set foo2"); # gets foo1 check print $sock "gets foo1\r\n"; ok(scalar <$sock> =~ /VALUE foo1 0 1 (\d+)\r\n/, "gets foo1 regexp success"); my $foo1_cas = $1; is(scalar <$sock>, "1\r\n","gets foo1 data is 1"); is(scalar <$sock>, "END\r\n","gets foo1 END"); # gets foo2 check print $sock "gets foo2\r\n"; ok(scalar <$sock> =~ /VALUE foo2 0 1 (\d+)\r\n/,"gets foo2 regexp success"); my $foo2_cas = $1; is(scalar <$sock>, "2\r\n","gets foo2 data is 2"); is(scalar <$sock>, "END\r\n","gets foo2 END"); # validate foo1 != foo2 ok($foo1_cas != $foo2_cas,"foo1 != foo2 single-gets success"); # multi-gets print $sock "gets foo1 foo2\r\n"; ok(scalar <$sock> =~ /VALUE foo1 0 1 (\d+)\r\n/, "validating first set of data is foo1"); $foo1_cas = $1; is(scalar <$sock>, "1\r\n", "validating foo1 set of data is 1"); ok(scalar <$sock> =~ /VALUE foo2 0 1 (\d+)\r\n/, "validating second set of data is foo2"); $foo2_cas = $1; is(scalar <$sock>, "2\r\n", "validating foo2 set of data is 2"); is(scalar <$sock>, "END\r\n","validating foo1,foo2 gets is over - END"); # validate foo1 != foo2 ok($foo1_cas != $foo2_cas, "foo1 != foo2 multi-gets success"); ### simulate race condition with cas # gets foo1 - success @result = mem_gets($sock, "foo1"); ok($result[0] != "", "sock - gets foo1 is not empty"); # gets foo2 - success @result2 = mem_gets($sock2, "foo1"); ok($result2[0] != "","sock2 - gets foo1 is not empty"); print $sock "cas foo1 0 0 6 $result[0]\r\nbarva2\r\n"; print $sock2 "cas foo1 0 0 5 $result2[0]\r\napple\r\n"; my $res1 = <$sock>; my $res2 = <$sock2>; ok( ( $res1 eq "STORED\r\n" && $res2 eq "EXISTS\r\n") || ( $res1 eq "EXISTS\r\n" && $res2 eq "STORED\r\n"), "cas on same item from two sockets"); ### bug 15: http://code.google.com/p/memcached/issues/detail?id=15 # set foo print $sock "set bug15 0 0 1\r\n0\r\n"; is(scalar <$sock>, "STORED\r\n", "stored 0"); # Check out the first gets. print $sock "gets bug15\r\n"; ok(scalar <$sock> =~ /VALUE bug15 0 1 (\d+)\r\n/, "gets bug15 regexp success"); my $bug15_cas = $1; is(scalar <$sock>, "0\r\n", "gets bug15 data is 0"); is(scalar <$sock>, "END\r\n","gets bug15 END"); # Increment print $sock "incr bug15 1\r\n"; is(scalar <$sock>, "1\r\n", "incr worked"); # Validate a changed CAS print $sock "gets bug15\r\n"; ok(scalar <$sock> =~ /VALUE bug15 0 1 (\d+)\r\n/, "gets bug15 regexp success"); my $next_bug15_cas = $1; is(scalar <$sock>, "1\r\n", "gets bug15 data is 0"); is(scalar <$sock>, "END\r\n","gets bug15 END"); ok($bug15_cas != $next_bug15_cas, "CAS changed"); memcached-1.4.14/t/issue_163.t0000644000175000017500000000205311701635506012605 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 7; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $value1 = "A"x66560; my $value2 = "B"x66570; print $sock "set key 0 1 66560\r\n$value1\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $stats = mem_stats($sock, "slabs"); my $requested = $stats->{"31:mem_requested"}; isnt ($requested, "0", "We should have requested some memory"); sleep(3); print $sock "set key 0 0 66570\r\n$value2\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $stats = mem_stats($sock, "items"); my $reclaimed = $stats->{"items:31:reclaimed"}; is ($reclaimed, "1", "Objects should be reclaimed"); print $sock "delete key\r\n"; is (scalar <$sock>, "DELETED\r\n", "deleted key"); print $sock "set key 0 0 66560\r\n$value1\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $stats = mem_stats($sock, "slabs"); my $requested2 = $stats->{"31:mem_requested"}; is ($requested2, $requested, "we've not allocated and freed the same amont"); memcached-1.4.14/t/flush-all.t0000755000175000017500000000326511712367413012765 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 21; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $expire; print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); print $sock "flush_all\r\n"; is(scalar <$sock>, "OK\r\n", "did flush_all"); mem_get_is($sock, "foo", undef); # Test flush_all with zero delay. print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); print $sock "flush_all 0\r\n"; is(scalar <$sock>, "OK\r\n", "did flush_all"); mem_get_is($sock, "foo", undef); # check that flush_all doesn't blow away items that immediately get set print $sock "set foo 0 0 3\r\nnew\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo = 'new'"); mem_get_is($sock, "foo", 'new'); # and the other form, specifying a flush_all time... my $expire = time() + 2; print $sock "flush_all $expire\r\n"; is(scalar <$sock>, "OK\r\n", "did flush_all in future"); print $sock "set foo 0 0 4\r\n1234\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo = '1234'"); mem_get_is($sock, "foo", '1234'); sleep(3); mem_get_is($sock, "foo", undef); print $sock "set foo 0 0 5\r\n12345\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo = '12345'"); mem_get_is($sock, "foo", '12345'); print $sock "flush_all 86400\r\n"; is(scalar <$sock>, "OK\r\n", "did flush_all for far future"); # Check foo still exists. mem_get_is($sock, "foo", '12345'); print $sock "set foo2 0 0 5\r\n54321\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo2 = '54321'"); mem_get_is($sock, "foo", '12345'); mem_get_is($sock, "foo2", '54321'); memcached-1.4.14/t/issue_108.t0000644000175000017500000000125711446413300012601 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 4; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $key = "del_key"; print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Added a key"); print $sock "delete $key 0\r\n"; is (scalar <$sock>, "DELETED\r\n", "Properly deleted with 0"); print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Added again a key"); print $sock "delete $key 0 noreply\r\n"; # will not reply, but a subsequent add will succeed print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Add succeeded after quiet deletion."); memcached-1.4.14/t/issue_61.t0000644000175000017500000000141511446413300012513 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 7; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached("-R 1"); my $sock = $server->sock; print $sock "set foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\nset foobar 0 0 5\r\nBubba\r\n"; is (scalar <$sock>, "STORED\r\n", "stored foobar"); is (scalar <$sock>, "STORED\r\n", "stored foobar"); is (scalar <$sock>, "STORED\r\n", "stored foobar"); is (scalar <$sock>, "STORED\r\n", "stored foobar"); is (scalar <$sock>, "STORED\r\n", "stored foobar"); is (scalar <$sock>, "STORED\r\n", "stored foobar"); my $stats = mem_stats($sock); is ($stats->{"conn_yields"}, "5", "Got a decent number of yields"); memcached-1.4.14/t/maxconns.t0000755000175000017500000000111211701635506012710 00000000000000#!/usr/bin/perl # NOTE: This test never worked. Memcached would ignore maxconns requests lower # than the current ulimit. Test needs to be updated. use strict; use warnings; use Test::More tests => 11; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; # start up a server with 10 maximum connections my $server = new_memcached('-c 100'); my $sock = $server->sock; my @sockets; ok(defined($sock), 'Connection 0'); push (@sockets, $sock); foreach my $conn (1..10) { $sock = $server->new_sock; ok(defined($sock), "Made connection $conn"); push(@sockets, $sock); } memcached-1.4.14/t/line-lengths.t0000755000175000017500000000100411246331452013450 00000000000000#!/usr/bin/perl use strict; use FindBin qw($Bin); our @files; BEGIN { chdir "$Bin/.." or die; @files = ( "doc/protocol.txt" ); } use Test::More tests => scalar(@files); foreach my $f (@files) { open(my $fh, $f) or die("Can't open $f"); my @long_lines = (); my $line_number = 0; while(<$fh>) { $line_number++; if(length($_) > 80) { push(@long_lines, $line_number); } } close($fh); ok(@long_lines == 0, "$f has a long lines: @long_lines"); } memcached-1.4.14/t/unixsocket.t0000755000175000017500000000076711246331452013272 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 3; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $filename = "/tmp/memcachetest$$"; my $server = new_memcached("-s $filename"); my $sock = $server->sock; ok(-S $filename, "creating unix domain socket $filename"); # set foo (and should get it) print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); unlink($filename); ## Just some basic stuff for now... memcached-1.4.14/t/00-startup.t0000755000175000017500000000337611446413300013007 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 18; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; eval { my $server = new_memcached(); ok($server, "started the server"); }; is($@, '', 'Basic startup works'); eval { my $server = new_memcached("-l fooble"); }; ok($@, "Died with illegal -l args"); eval { my $server = new_memcached("-l 127.0.0.1"); }; is($@,'', "-l 127.0.0.1 works"); eval { my $server = new_memcached('-C'); my $stats = mem_stats($server->sock, 'settings'); is('no', $stats->{'cas_enabled'}); }; is($@, '', "-C works"); eval { my $server = new_memcached('-b 8675'); my $stats = mem_stats($server->sock, 'settings'); is('8675', $stats->{'tcp_backlog'}); }; is($@, '', "-b works"); foreach my $val ('auto', 'ascii') { eval { my $server = new_memcached("-B $val"); my $stats = mem_stats($server->sock, 'settings'); ok($stats->{'binding_protocol'} =~ /$val/, "$val works"); }; is($@, '', "$val works"); } # For the binary test, we just verify it starts since we don't have an easy bin client. eval { my $server = new_memcached("-B binary"); }; is($@, '', "binary works"); eval { my $server = new_memcached("-vv -B auto"); }; is($@, '', "auto works"); eval { my $server = new_memcached("-vv -B ascii"); }; is($@, '', "ascii works"); # For the binary test, we just verify it starts since we don't have an easy bin client. eval { my $server = new_memcached("-vv -B binary"); }; is($@, '', "binary works"); # Should blow up with something invalid. eval { my $server = new_memcached("-B http"); }; ok($@, "Died with illegal -B arg."); # Should not allow -t 0 eval { my $server = new_memcached("-t 0"); }; ok($@, "Died with illegal 0 thread count"); memcached-1.4.14/t/issue_41.t0000644000175000017500000000172411246331452012521 00000000000000#!/usr/bin/perl use strict; use warnings; use POSIX qw(ceil); use Test::More tests => 691; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $factor = 2; my $val = "x" x $factor; my $key = ''; # SET items of diverse size to the daemon so it can attempt # to return a large stats output for slabs for (my $i=0; $i<69; $i++) { for (my $j=0; $j<10; $j++) { $key = "$i:$j"; print $sock "set key$key 0 0 $factor\r\n$val\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } $factor *= 1.2; $factor = ceil($factor); $val = "x" x $factor; } # This request will kill the daemon if it has not allocated # enough memory internally. my $stats = mem_stats($sock, "slabs"); # Verify whether the daemon is still running or not by asking # it for statistics. print $sock "version\r\n"; my $v = scalar <$sock>; ok(defined $v && length($v), "memcached didn't respond"); memcached-1.4.14/t/binary-sasl.t0000755000175000017500000003765211711074307013325 00000000000000#!/usr/bin/perl use strict; use warnings; use Cwd; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $supports_sasl = supports_sasl(); use Test::More; if (supports_sasl()) { if ($ENV{'RUN_SASL_TESTS'}) { plan tests => 25; } else { plan skip_all => 'Skipping SASL tests'; exit 0; } } else { plan tests => 1; eval { my $server = new_memcached("-S"); }; ok($@, "Died with illegal -S args when SASL is not supported."); exit 0; } eval { my $server = new_memcached("-S -B auto"); }; ok($@, "SASL shouldn't be used with protocol auto negotiate"); eval { my $server = new_memcached("-S -B ascii"); }; ok($@, "SASL isn't implemented in the ascii protocol"); eval { my $server = new_memcached("-S -B binary -B ascii"); }; ok($@, "SASL isn't implemented in the ascii protocol"); # Based almost 100% off testClient.py which is: # Copyright (c) 2007 Dustin Sallings # Command constants use constant CMD_GET => 0x00; use constant CMD_SET => 0x01; use constant CMD_ADD => 0x02; use constant CMD_REPLACE => 0x03; use constant CMD_DELETE => 0x04; use constant CMD_INCR => 0x05; use constant CMD_DECR => 0x06; use constant CMD_QUIT => 0x07; use constant CMD_FLUSH => 0x08; use constant CMD_GETQ => 0x09; use constant CMD_NOOP => 0x0A; use constant CMD_VERSION => 0x0B; use constant CMD_GETK => 0x0C; use constant CMD_GETKQ => 0x0D; use constant CMD_APPEND => 0x0E; use constant CMD_PREPEND => 0x0F; use constant CMD_STAT => 0x10; use constant CMD_SETQ => 0x11; use constant CMD_ADDQ => 0x12; use constant CMD_REPLACEQ => 0x13; use constant CMD_DELETEQ => 0x14; use constant CMD_INCREMENTQ => 0x15; use constant CMD_DECREMENTQ => 0x16; use constant CMD_QUITQ => 0x17; use constant CMD_FLUSHQ => 0x18; use constant CMD_APPENDQ => 0x19; use constant CMD_PREPENDQ => 0x1A; use constant CMD_SASL_LIST_MECHS => 0x20; use constant CMD_SASL_AUTH => 0x21; use constant CMD_SASL_STEP => 0x22; use constant ERR_AUTH_ERROR => 0x20; # REQ and RES formats are divided even though they currently share # the same format, since they _could_ differ in the future. use constant REQ_PKT_FMT => "CCnCCnNNNN"; use constant RES_PKT_FMT => "CCnCCnNNNN"; use constant INCRDECR_PKT_FMT => "NNNNN"; use constant MIN_RECV_BYTES => length(pack(RES_PKT_FMT)); use constant REQ_MAGIC => 0x80; use constant RES_MAGIC => 0x81; my $pwd=getcwd; $ENV{'SASL_CONF_PATH'} = "$pwd/t/sasl"; my $server = new_memcached('-B binary -S '); my $mc = MC::Client->new; my $check = sub { my ($key, $orig_val) = @_; my ($status, $val, $cas) = $mc->get($key); if ($val =~ /^\d+$/) { cmp_ok($val,'==', $orig_val, "$val = $orig_val"); } else { cmp_ok($val, 'eq', $orig_val, "$val = $orig_val"); } }; my $set = sub { my ($key, $orig_value, $exp) = @_; $exp = defined $exp ? $exp : 0; my ($status, $rv)= $mc->set($key, $orig_value, $exp); $check->($key, $orig_value); }; my $empty = sub { my $key = shift; my ($status,$rv) =()= eval { $mc->get($key) }; #if ($status == ERR_AUTH_ERROR) { # ok($@->auth_error, "Not authorized to connect"); #} #else { # ok($@->not_found, "We got a not found error when we expected one"); #} if ($status) { ok($@->not_found, "We got a not found error when we expected one"); } }; my $delete = sub { my ($key, $when) = @_; $mc->delete($key, $when); $empty->($key); }; # BEGIN THE TEST ok($server, "started the server"); my $v = $mc->version; ok(defined $v && length($v), "Proper version: $v"); # list mechs my $mechs= $mc->list_mechs(); Test::More::cmp_ok($mechs, 'eq', 'CRAM-MD5 PLAIN', "list_mechs $mechs"); # this should fail, not authenticated { my ($status, $val)= $mc->set('x', "somevalue"); ok($status, "this fails to authenticate"); cmp_ok($status,'==',ERR_AUTH_ERROR, "error code matches"); } $empty->('x'); { my $mc = MC::Client->new; my ($status, $val) = $mc->delete('x'); ok($status, "this fails to authenticate"); cmp_ok($status,'==',ERR_AUTH_ERROR, "error code matches"); } $empty->('x'); { my $mc = MC::Client->new; my ($status, $val)= $mc->set('x', "somevalue"); ok($status, "this fails to authenticate"); cmp_ok($status,'==',ERR_AUTH_ERROR, "error code matches"); } $empty->('x'); { my $mc = MC::Client->new; my ($status, $val)= $mc->flush('x'); ok($status, "this fails to authenticate"); cmp_ok($status,'==',ERR_AUTH_ERROR, "error code matches"); } $empty->('x'); # Build the auth DB for testing. my $sasldb = '/tmp/test-memcached.sasldb'; unlink $sasldb; my $saslpasswd_path; for my $dir (split(/:/, $ENV{PATH}), "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin", ) { my $exe = $dir . '/saslpasswd2'; if (-x $exe) { $saslpasswd_path = $exe; last; } } system("echo testpass | $saslpasswd_path -a memcached -c -p testuser"); $mc = MC::Client->new; # Attempt a bad auth mech. is ($mc->authenticate('testuser', 'testpass', "X" x 40), 0x4, "bad mech"); # Attempt bad authentication. is ($mc->authenticate('testuser', 'wrongpassword'), 0x20, "bad auth"); # Now try good authentication and make the tests work. is ($mc->authenticate('testuser', 'testpass'), 0, "authenticated"); # these should work { my ($status, $val)= $mc->set('x', "somevalue"); ok(! $status); } $check->('x','somevalue'); { my ($status, $val)= $mc->delete('x'); ok(! $status); } $empty->('x'); { my ($status, $val)= $mc->set('x', "somevalue"); ok(! $status); } $check->('x','somevalue'); { my ($status, $val)= $mc->flush('x'); ok(! $status); } $empty->('x'); # check the SASL stats, make sure they track things correctly # note: the enabled or not is presence checked in stats.t # while authenticated, get current counter # # My initial approach was going to be to get current counts, reauthenticate # and fail, followed by a reauth successfully so I'd know what happened. # Reauthentication is currently unsupported, so it doesn't work that way at the # moment. Adding tests may break this. { my %stats = $mc->stats(''); is ($stats{'auth_cmds'}, 2, "auth commands counted"); is ($stats{'auth_errors'}, 1, "auth errors correct"); } # Along with the assertion added to the code to verify we're staying # within bounds when we do a stats detail dump (detail turned on at # the top). # my %stats = $mc->stats('detail dump'); # ###################################################################### # Test ends around here. # ###################################################################### package MC::Client; use strict; use warnings; use fields qw(socket); use IO::Socket::INET; use constant ERR_AUTH_ERROR => 0x20; sub new { my $self = shift; my ($s) = @_; $s = $server unless defined $s; my $sock = $s->sock; $self = fields::new($self); $self->{socket} = $sock; return $self; } sub authenticate { my ($self, $user, $pass, $mech)= @_; $mech ||= 'PLAIN'; my $buf = sprintf("%c%s%c%s", 0, $user, 0, $pass); my ($status, $rv, undef) = $self->_do_command(::CMD_SASL_AUTH, $mech, $buf, ''); return $status; } sub list_mechs { my ($self)= @_; my ($status, $rv, undef) = $self->_do_command(::CMD_SASL_LIST_MECHS, '', '', ''); return join(" ", sort(split(/\s+/, $rv))); } sub build_command { my $self = shift; die "Not enough args to send_command" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; $extra_header = '' unless defined $extra_header; my $keylen = length($key); my $vallen = length($val); my $extralen = length($extra_header); my $datatype = 0; # field for future use my $reserved = 0; # field for future use my $totallen = $keylen + $vallen + $extralen; my $ident_hi = 0; my $ident_lo = 0; if ($cas) { $ident_hi = int($cas / 2 ** 32); $ident_lo = int($cas % 2 ** 32); } my $msg = pack(::REQ_PKT_FMT, ::REQ_MAGIC, $cmd, $keylen, $extralen, $datatype, $reserved, $totallen, $opaque, $ident_hi, $ident_lo); my $full_msg = $msg . $extra_header . $key . $val; return $full_msg; } sub send_command { my $self = shift; die "Not enough args to send_command" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; my $full_msg = $self->build_command($cmd, $key, $val, $opaque, $extra_header, $cas); my $sent = $self->{socket}->send($full_msg); die("Send failed: $!") unless $sent; if($sent != length($full_msg)) { die("only sent $sent of " . length($full_msg) . " bytes"); } } sub flush_socket { my $self = shift; $self->{socket}->flush; } # Send a silent command and ensure it doesn't respond. sub send_silent { my $self = shift; die "Not enough args to send_silent" unless @_ >= 4; my ($cmd, $key, $val, $opaque, $extra_header, $cas) = @_; $self->send_command($cmd, $key, $val, $opaque, $extra_header, $cas); $self->send_command(::CMD_NOOP, '', '', $opaque + 1); my ($ropaque, $status, $data) = $self->_handle_single_response; Test::More::is($ropaque, $opaque + 1); } sub silent_mutation { my $self = shift; my ($cmd, $key, $value) = @_; $empty->($key); my $extra = pack "NN", 82, 0; $mc->send_silent($cmd, $key, $value, 7278552, $extra, 0); $check->($key, $value); } sub _handle_single_response { my $self = shift; my $myopaque = shift; $self->{socket}->recv(my $response, ::MIN_RECV_BYTES); my ($magic, $cmd, $keylen, $extralen, $datatype, $status, $remaining, $opaque, $ident_hi, $ident_lo) = unpack(::RES_PKT_FMT, $response); return ($opaque, '', '', '', 0) if not defined $remaining; return ($opaque, '', '', '', 0) if ($remaining == 0); # fetch the value my $rv=""; while($remaining - length($rv) > 0) { $self->{socket}->recv(my $buf, $remaining - length($rv)); $rv .= $buf; } if(length($rv) != $remaining) { my $found = length($rv); die("Expected $remaining bytes, got $found"); } my $cas = ($ident_hi * 2 ** 32) + $ident_lo; #if ($status) { #die MC::Error->new($status, $rv); #} return ($opaque, $status, $rv, $cas, $keylen); } sub _do_command { my $self = shift; die unless @_ >= 3; my ($cmd, $key, $val, $extra_header, $cas) = @_; $extra_header = '' unless defined $extra_header; my $opaque = int(rand(2**32)); $self->send_command($cmd, $key, $val, $opaque, $extra_header, $cas); my (undef, $status, $rv, $rcas) = $self->_handle_single_response($opaque); return ($status, $rv, $rcas); } sub _incrdecr_header { my $self = shift; my ($amt, $init, $exp) = @_; my $amt_hi = int($amt / 2 ** 32); my $amt_lo = int($amt % 2 ** 32); my $init_hi = int($init / 2 ** 32); my $init_lo = int($init % 2 ** 32); my $extra_header = pack(::INCRDECR_PKT_FMT, $amt_hi, $amt_lo, $init_hi, $init_lo, $exp); return $extra_header; } sub _incrdecr { my $self = shift; my ($cmd, $key, $amt, $init, $exp) = @_; my ($status, $data, undef) = $self->_do_command($cmd, $key, '', $self->_incrdecr_header($amt, $init, $exp)); my $header = substr $data, 0, 8, ''; my ($resp_hi, $resp_lo) = unpack "NN", $header; my $resp = ($resp_hi * 2 ** 32) + $resp_lo; return $resp; } sub silent_incrdecr { my $self = shift; my ($cmd, $key, $amt, $init, $exp) = @_; my $opaque = 8275753; $mc->send_silent($cmd, $key, '', $opaque, $mc->_incrdecr_header($amt, $init, $exp)); } sub stats { my $self = shift; my $key = shift; my $cas = 0; my $opaque = int(rand(2**32)); $self->send_command(::CMD_STAT, $key, '', $opaque, '', $cas); my %rv = (); my $found_key = ''; my $found_val = ''; my $status= 0; do { my ($op, $status, $data, $cas, $keylen) = $self->_handle_single_response($opaque); if ($keylen > 0) { $found_key = substr($data, 0, $keylen); $found_val = substr($data, $keylen); $rv{$found_key} = $found_val; } else { $found_key = ''; } } while($found_key ne ''); return %rv; } sub get { my $self = shift; my $key = shift; my ($status, $rv, $cas) = $self->_do_command(::CMD_GET, $key, '', ''); my $header = substr $rv, 0, 4, ''; my $flags = unpack("N", $header); return ($status, $rv); } sub get_multi { my $self = shift; my @keys = @_; for (my $i = 0; $i < @keys; $i++) { $self->send_command(::CMD_GETQ, $keys[$i], '', $i, '', 0); } my $terminal = @keys + 10; $self->send_command(::CMD_NOOP, '', '', $terminal); my %return; my $status = 0; while (1) { my ($opaque, $status, $data) = $self->_handle_single_response; last if $opaque == $terminal; my $header = substr $data, 0, 4, ''; my $flags = unpack("N", $header); $return{$keys[$opaque]} = [$flags, $data]; } return %return if wantarray; return \%return; } sub version { my $self = shift; return $self->_do_command(::CMD_VERSION, '', ''); } sub flush { my $self = shift; return $self->_do_command(::CMD_FLUSH, '', ''); } sub add { my $self = shift; my ($key, $val, $flags, $expire) = @_; my $extra_header = pack "NN", $flags, $expire; my $cas = 0; return $self->_do_command(::CMD_ADD, $key, $val, $extra_header, $cas); } sub set { my $self = shift; my $flags = 0; my $cas = 0; my ($key, $val, $expire) = @_; $expire = defined $expire ? $expire : 0; my $extra_header = pack "NN", $flags, $expire; return $self->_do_command(::CMD_SET, $key, $val, $extra_header, $cas); } sub _append_prepend { my $self = shift; my ($cmd, $key, $val, $cas) = @_; return $self->_do_command($cmd, $key, $val, '', $cas); } sub replace { my $self = shift; my ($key, $val, $flags, $expire) = @_; my $extra_header = pack "NN", $flags, $expire; my $cas = 0; return $self->_do_command(::CMD_REPLACE, $key, $val, $extra_header, $cas); } sub delete { my $self = shift; my ($key) = @_; return $self->_do_command(::CMD_DELETE, $key, ''); } sub incr { my $self = shift; my ($key, $amt, $init, $exp) = @_; $amt = 1 unless defined $amt; $init = 0 unless defined $init; $exp = 0 unless defined $exp; return $self->_incrdecr(::CMD_INCR, $key, $amt, $init, $exp); } sub decr { my $self = shift; my ($key, $amt, $init, $exp) = @_; $amt = 1 unless defined $amt; $init = 0 unless defined $init; $exp = 0 unless defined $exp; return $self->_incrdecr(::CMD_DECR, $key, $amt, $init, $exp); } sub noop { my $self = shift; return $self->_do_command(::CMD_NOOP, '', ''); } package MC::Error; use strict; use warnings; use constant ERR_UNKNOWN_CMD => 0x81; use constant ERR_NOT_FOUND => 0x1; use constant ERR_EXISTS => 0x2; use constant ERR_TOO_BIG => 0x3; use constant ERR_EINVAL => 0x4; use constant ERR_NOT_STORED => 0x5; use constant ERR_DELTA_BADVAL => 0x6; use constant ERR_AUTH_ERROR => 0x20; use overload '""' => sub { my $self = shift; return "Memcache Error ($self->[0]): $self->[1]"; }; sub new { my $class = shift; my $error = [@_]; my $self = bless $error, (ref $class || $class); return $self; } sub not_found { my $self = shift; return $self->[0] == ERR_NOT_FOUND; } sub exists { my $self = shift; return $self->[0] == ERR_EXISTS; } sub too_big { my $self = shift; return $self->[0] == ERR_TOO_BIG; } sub delta_badval { my $self = shift; return $self->[0] == ERR_DELTA_BADVAL; } sub auth_error { my $self = shift; return $self->[0] == ERR_AUTH_ERROR; } unlink $sasldb; # vim: filetype=perl memcached-1.4.14/t/issue_29.t0000644000175000017500000000116711246331452012530 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 4; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; print $sock "set issue29 0 0 0\r\n\r\n"; is (scalar <$sock>, "STORED\r\n", "stored issue29"); my $first_stats = mem_stats($sock, "slabs"); my $first_used = $first_stats->{"1:used_chunks"}; is(1, $first_used, "Used one"); print $sock "set issue29_b 0 0 0\r\n\r\n"; is (scalar <$sock>, "STORED\r\n", "stored issue29_b"); my $second_stats = mem_stats($sock, "slabs"); my $second_used = $second_stats->{"1:used_chunks"}; is(2, $second_used, "Used two") memcached-1.4.14/t/stress-memcached.pl0000755000175000017500000000426511246331452014472 00000000000000#!/usr/bin/perl # use strict; use lib '../../api/perl/lib'; use Cache::Memcached; use Time::HiRes qw(time); unless (@ARGV == 2) { die "Usage: stress-memcached.pl ip:port threads\n"; } my $host = shift; my $threads = shift; my $memc = new Cache::Memcached; $memc->set_servers([$host]); unless ($memc->set("foo", "bar") && $memc->get("foo") eq "bar") { die "memcached not running at $host ?\n"; } $memc->disconnect_all(); my $running = 0; while (1) { if ($running < $threads) { my $cpid = fork(); if ($cpid) { $running++; #print "Launched $cpid. Running $running threads.\n"; } else { stress(); exit 0; } } else { wait(); $running--; } } sub stress { undef $memc; $memc = new Cache::Memcached; $memc->set_servers([$host]); my ($t1, $t2); my $start = sub { $t1 = time(); }; my $stop = sub { my $op = shift; $t2 = time(); my $td = sprintf("%0.3f", $t2 - $t1); if ($td > 0.25) { print "Took $td seconds for: $op\n"; } }; my $max = rand(50); my $sets = 0; for (my $i = 0; $i < $max; $i++) { my $key = key($i); my $set = $memc->set($key, $key); $sets++ if $set; } for (1..int(rand(500))) { my $rand = int(rand($max)); my $key = key($rand); my $meth = int(rand(3)); my $exp = int(rand(3)); undef $exp unless $exp; $start->(); if ($meth == 0) { $memc->add($key, $key, $exp); $stop->("add"); } elsif ($meth == 1) { $memc->delete($key); $stop->("delete"); } else { $memc->set($key, $key, $exp); $stop->("set"); } $rand = int(rand($max)); $key = key($rand); $start->(); my $v = $memc->get($key); $stop->("get"); if ($v && $v ne $key) { die "Bogus: $v for key $rand\n"; } } $start->(); my $multi = $memc->get_multi(map { key(int(rand($max))) } (1..$max)); $stop->("get_multi"); } sub key { my $n = shift; $_ = sprintf("%04d", $n); if ($n % 2) { $_ .= "a"x20; } $_; } memcached-1.4.14/t/evictions.t0000644000175000017500000000155111446413300013061 00000000000000#!/usr/bin/perl # Test the 'stats items' evictions counters. use strict; use Test::More tests => 92; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached("-m 3"); my $sock = $server->sock; my $value = "B"x66560; my $key = 0; # These aren't set to expire. for ($key = 0; $key < 40; $key++) { print $sock "set key$key 0 0 66560\r\n$value\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key$key"); } # These ones would expire in 600 seconds. for ($key = 0; $key < 50; $key++) { print $sock "set key$key 0 600 66560\r\n$value\r\n"; is(scalar <$sock>, "STORED\r\n", "stored key$key"); } my $stats = mem_stats($sock, "items"); my $evicted = $stats->{"items:31:evicted"}; isnt($evicted, "0", "check evicted"); my $evicted_nonzero = $stats->{"items:31:evicted_nonzero"}; isnt($evicted_nonzero, "0", "check evicted_nonzero"); memcached-1.4.14/t/issue_3.t0000644000175000017500000000252411446413300012431 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 8; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $key = "del_key"; print $sock "delete $key\r\n"; is (scalar <$sock>, "NOT_FOUND\r\n", "not found on delete"); print $sock "delete $key 10\r\n"; is (scalar <$sock>, "CLIENT_ERROR bad command line format." . " Usage: delete [noreply]\r\n", "invalid delete"); print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Add before a broken delete."); print $sock "delete $key 10 noreply\r\n"; # Does not reply # is (scalar <$sock>, "ERROR\r\n", "Even more invalid delete"); print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "NOT_STORED\r\n", "Failed to add after failed silent delete."); print $sock "delete $key noreply\r\n"; # Will not reply, so let's do a set and check that. print $sock "set $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Stored a key"); print $sock "delete $key\r\n"; is (scalar <$sock>, "DELETED\r\n", "Properly deleted"); print $sock "set $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Stored a key"); print $sock "delete $key noreply\r\n"; # will not reply, but a subsequent add will succeed print $sock "add $key 0 0 1\r\nx\r\n"; is (scalar <$sock>, "STORED\r\n", "Add succeeded after deletion."); memcached-1.4.14/t/flags.t0000755000175000017500000000071011246331452012156 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 6; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # set foo (and should get it) for my $flags (0, 123, 2**16-1) { print $sock "set foo $flags 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is({ sock => $sock, flags => $flags }, "foo", "fooval", "got flags $flags back"); } memcached-1.4.14/t/issue_104.t0000755000175000017500000000114511446413300012574 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 6; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # first get should miss print $sock "get foo\r\n"; is(scalar <$sock>, "END\r\n", "get foo"); # Now set and get (should hit) print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); my $stats = mem_stats($sock); is($stats->{cmd_get}, 2, "Should have 2 get requests"); is($stats->{get_hits}, 1, "Should have 1 hit"); is($stats->{get_misses}, 1, "Should have 1 miss"); memcached-1.4.14/t/lib/0000755000175000017500000000000011701635506011525 500000000000000memcached-1.4.14/t/lib/MemcachedTest.pm0000644000175000017500000001670711701635506014524 00000000000000package MemcachedTest; use strict; use IO::Socket::INET; use IO::Socket::UNIX; use Exporter 'import'; use Carp qw(croak); use vars qw(@EXPORT); # Instead of doing the substitution with Autoconf, we assume that # cwd == builddir. use Cwd; my $builddir = getcwd; @EXPORT = qw(new_memcached sleep mem_get_is mem_gets mem_gets_is mem_stats supports_sasl free_port); sub sleep { my $n = shift; select undef, undef, undef, $n; } sub mem_stats { my ($sock, $type) = @_; $type = $type ? " $type" : ""; print $sock "stats$type\r\n"; my $stats = {}; while (<$sock>) { last if /^(\.|END)/; /^(STAT|ITEM) (\S+)\s+([^\r\n]+)/; #print " slabs: $_"; $stats->{$2} = $3; } return $stats; } sub mem_get_is { # works on single-line values only. no newlines in value. my ($sock_opts, $key, $val, $msg) = @_; my $opts = ref $sock_opts eq "HASH" ? $sock_opts : {}; my $sock = ref $sock_opts eq "HASH" ? $opts->{sock} : $sock_opts; my $expect_flags = $opts->{flags} || 0; my $dval = defined $val ? "'$val'" : ""; $msg ||= "$key == $dval"; print $sock "get $key\r\n"; if (! defined $val) { my $line = scalar <$sock>; if ($line =~ /^VALUE/) { $line .= scalar(<$sock>) . scalar(<$sock>); } Test::More::is($line, "END\r\n", $msg); } else { my $len = length($val); my $body = scalar(<$sock>); my $expected = "VALUE $key $expect_flags $len\r\n$val\r\nEND\r\n"; if (!$body || $body =~ /^END/) { Test::More::is($body, $expected, $msg); return; } $body .= scalar(<$sock>) . scalar(<$sock>); Test::More::is($body, $expected, $msg); } } sub mem_gets { # works on single-line values only. no newlines in value. my ($sock_opts, $key) = @_; my $opts = ref $sock_opts eq "HASH" ? $sock_opts : {}; my $sock = ref $sock_opts eq "HASH" ? $opts->{sock} : $sock_opts; my $val; my $expect_flags = $opts->{flags} || 0; print $sock "gets $key\r\n"; my $response = <$sock>; if ($response =~ /^END/) { return "NOT_FOUND"; } else { $response =~ /VALUE (.*) (\d+) (\d+) (\d+)/; my $flags = $2; my $len = $3; my $identifier = $4; read $sock, $val , $len; # get the END $_ = <$sock>; $_ = <$sock>; return ($identifier,$val); } } sub mem_gets_is { # works on single-line values only. no newlines in value. my ($sock_opts, $identifier, $key, $val, $msg) = @_; my $opts = ref $sock_opts eq "HASH" ? $sock_opts : {}; my $sock = ref $sock_opts eq "HASH" ? $opts->{sock} : $sock_opts; my $expect_flags = $opts->{flags} || 0; my $dval = defined $val ? "'$val'" : ""; $msg ||= "$key == $dval"; print $sock "gets $key\r\n"; if (! defined $val) { my $line = scalar <$sock>; if ($line =~ /^VALUE/) { $line .= scalar(<$sock>) . scalar(<$sock>); } Test::More::is($line, "END\r\n", $msg); } else { my $len = length($val); my $body = scalar(<$sock>); my $expected = "VALUE $key $expect_flags $len $identifier\r\n$val\r\nEND\r\n"; if (!$body || $body =~ /^END/) { Test::More::is($body, $expected, $msg); return; } $body .= scalar(<$sock>) . scalar(<$sock>); Test::More::is($body, $expected, $msg); } } sub free_port { my $type = shift || "tcp"; my $sock; my $port; while (!$sock) { $port = int(rand(20000)) + 30000; $sock = IO::Socket::INET->new(LocalAddr => '127.0.0.1', LocalPort => $port, Proto => $type, ReuseAddr => 1); } return $port; } sub supports_udp { my $output = `$builddir/memcached-debug -h`; return 0 if $output =~ /^memcached 1\.1\./; return 1; } sub supports_sasl { my $output = `$builddir/memcached-debug -h`; return 1 if $output =~ /sasl/i; return 0; } sub new_memcached { my ($args, $passed_port) = @_; my $port = $passed_port || free_port(); my $host = '127.0.0.1'; if ($ENV{T_MEMD_USE_DAEMON}) { my ($host, $port) = ($ENV{T_MEMD_USE_DAEMON} =~ m/^([^:]+):(\d+)$/); my $conn = IO::Socket::INET->new(PeerAddr => "$host:$port"); if ($conn) { return Memcached::Handle->new(conn => $conn, host => $host, port => $port); } croak("Failed to connect to specified memcached server.") unless $conn; } my $udpport = free_port("udp"); $args .= " -p $port"; if (supports_udp()) { $args .= " -U $udpport"; } if ($< == 0) { $args .= " -u root"; } my $childpid = fork(); my $exe = "$builddir/memcached-debug"; croak("memcached binary doesn't exist. Haven't run 'make' ?\n") unless -e $exe; croak("memcached binary not executable\n") unless -x _; unless ($childpid) { exec "$builddir/timedrun 600 $exe $args"; exit; # never gets here. } # unix domain sockets if ($args =~ /-s (\S+)/) { sleep 1; my $filename = $1; my $conn = IO::Socket::UNIX->new(Peer => $filename) || croak("Failed to connect to unix domain socket: $! '$filename'"); return Memcached::Handle->new(pid => $childpid, conn => $conn, domainsocket => $filename, host => $host, port => $port); } # try to connect / find open port, only if we're not using unix domain # sockets for (1..20) { my $conn = IO::Socket::INET->new(PeerAddr => "127.0.0.1:$port"); if ($conn) { return Memcached::Handle->new(pid => $childpid, conn => $conn, udpport => $udpport, host => $host, port => $port); } select undef, undef, undef, 0.10; } croak("Failed to startup/connect to memcached server."); } ############################################################################ package Memcached::Handle; sub new { my ($class, %params) = @_; return bless \%params, $class; } sub DESTROY { my $self = shift; kill 2, $self->{pid}; } sub stop { my $self = shift; kill 15, $self->{pid}; } sub host { $_[0]{host} } sub port { $_[0]{port} } sub udpport { $_[0]{udpport} } sub sock { my $self = shift; if ($self->{conn} && ($self->{domainsocket} || getpeername($self->{conn}))) { return $self->{conn}; } return $self->new_sock; } sub new_sock { my $self = shift; if ($self->{domainsocket}) { return IO::Socket::UNIX->new(Peer => $self->{domainsocket}); } else { return IO::Socket::INET->new(PeerAddr => "$self->{host}:$self->{port}"); } } sub new_udp_sock { my $self = shift; return IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $self->{udpport}, Proto => 'udp', LocalAddr => '127.0.0.1', LocalPort => MemcachedTest::free_port('udp'), ); } 1; memcached-1.4.14/t/issue_70.t0000644000175000017500000000114411701635506012522 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 4; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; print $sock "set issue70 0 0 0\r\n\r\n"; is (scalar <$sock>, "STORED\r\n", "stored issue70"); print $sock "set issue70 0 0 -1\r\n"; is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); print $sock "set issue70 0 0 4294967295\r\n"; is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); print $sock "set issue70 0 0 2147483647\r\nscoobyscoobydoo"; is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n"); memcached-1.4.14/t/issue_140.t0000644000175000017500000000171611701635506012605 00000000000000#!/usr/bin/perl use strict; use Test::More; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; plan skip_all => 'Fix for Issue 140 was only an illusion'; plan tests => 7; my $server = new_memcached(); my $sock = $server->sock; print $sock "set a 0 0 1\r\na\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $stats = mem_stats($sock, "items"); my $age = $stats->{"items:1:age"}; isnt ($age, "0", "Age should not be zero"); print $sock "flush_all\r\n"; is (scalar <$sock>, "OK\r\n", "items flushed"); my $stats = mem_stats($sock, "items"); my $age = $stats->{"items:1:age"}; is ($age, undef, "all should be gone"); print $sock "set a 0 1 1\r\na\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key"); my $stats = mem_stats($sock, "items"); my $age = $stats->{"items:1:age"}; isnt ($age, "0", "Age should not be zero"); sleep(3); my $stats = mem_stats($sock, "items"); my $age = $stats->{"items:1:age"}; is ($age, undef, "all should be gone"); memcached-1.4.14/t/issue_22.t0000644000175000017500000000216611606254362012525 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 84; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached("-m 3"); my $sock = $server->sock; my $value = "B"x66560; my $key = 0; for ($key = 0; $key < 40; $key++) { print $sock "set key$key 0 0 66560\r\n$value\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } my $first_stats = mem_stats($sock, "items"); my $first_evicted = $first_stats->{"items:31:evicted"}; # I get 1 eviction on a 32 bit binary, but 4 on a 64 binary.. # Just check that I have evictions... isnt ($first_evicted, "0", "check evicted"); print $sock "stats reset\r\n"; is (scalar <$sock>, "RESET\r\n", "Stats reset"); my $second_stats = mem_stats($sock, "items"); my $second_evicted = $second_stats->{"items:31:evicted"}; is ($second_evicted, "0", "check evicted"); for ($key = 40; $key < 80; $key++) { print $sock "set key$key 0 0 66560\r\n$value\r\n"; is (scalar <$sock>, "STORED\r\n", "stored key$key"); } my $last_stats = mem_stats($sock, "items"); my $last_evicted = $last_stats->{"items:31:evicted"}; is ($last_evicted, "40", "check evicted"); memcached-1.4.14/t/incrdecr.t0000755000175000017500000000415511246331452012662 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 23; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # Bug 21 print $sock "set bug21 0 0 19\r\n9223372036854775807\r\n"; is(scalar <$sock>, "STORED\r\n", "stored text"); print $sock "incr bug21 1\r\n"; is(scalar <$sock>, "9223372036854775808\r\n", "bug21 incr 1"); print $sock "incr bug21 1\r\n"; is(scalar <$sock>, "9223372036854775809\r\n", "bug21 incr 2"); print $sock "decr bug21 1\r\n"; is(scalar <$sock>, "9223372036854775808\r\n", "bug21 decr"); print $sock "set num 0 0 1\r\n1\r\n"; is(scalar <$sock>, "STORED\r\n", "stored num"); mem_get_is($sock, "num", 1, "stored 1"); print $sock "incr num 1\r\n"; is(scalar <$sock>, "2\r\n", "+ 1 = 2"); mem_get_is($sock, "num", 2); print $sock "incr num 8\r\n"; is(scalar <$sock>, "10\r\n", "+ 8 = 10"); mem_get_is($sock, "num", 10); print $sock "decr num 1\r\n"; is(scalar <$sock>, "9\r\n", "- 1 = 9"); print $sock "decr num 9\r\n"; is(scalar <$sock>, "0\r\n", "- 9 = 0"); print $sock "decr num 5\r\n"; is(scalar <$sock>, "0\r\n", "- 5 = 0"); printf $sock "set num 0 0 10\r\n4294967296\r\n"; is(scalar <$sock>, "STORED\r\n", "stored 2**32"); print $sock "incr num 1\r\n"; is(scalar <$sock>, "4294967297\r\n", "4294967296 + 1 = 4294967297"); printf $sock "set num 0 0 %d\r\n18446744073709551615\r\n", length("18446744073709551615"); is(scalar <$sock>, "STORED\r\n", "stored 2**64-1"); print $sock "incr num 1\r\n"; is(scalar <$sock>, "0\r\n", "(2**64 - 1) + 1 = 0"); print $sock "decr bogus 5\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "can't decr bogus key"); print $sock "decr incr 5\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "can't incr bogus key"); print $sock "set bigincr 0 0 1\r\n0\r\n"; is(scalar <$sock>, "STORED\r\n", "stored bigincr"); print $sock "incr bigincr 18446744073709551610\r\n"; is(scalar <$sock>, "18446744073709551610\r\n"); print $sock "set text 0 0 2\r\nhi\r\n"; is(scalar <$sock>, "STORED\r\n", "stored hi"); print $sock "incr text 1\r\n"; is(scalar <$sock>, "CLIENT_ERROR cannot increment or decrement non-numeric value\r\n", "hi - 1 = 0"); memcached-1.4.14/t/lru.t0000755000175000017500000000313411701635506011672 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 149; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; # assuming max slab is 1M and default mem is 64M my $server = new_memcached(); my $sock = $server->sock; # create a big value for the largest slab my $max = 1024 * 1024; my $big = 'x' x (1024 * 1024 - 250); ok(length($big) > 512 * 1024); ok(length($big) < 1024 * 1024); # test that an even bigger value is rejected while we're here my $too_big = $big . $big . $big; my $len = length($too_big); print $sock "set too_big 0 0 $len\r\n$too_big\r\n"; is(scalar <$sock>, "SERVER_ERROR object too large for cache\r\n", "too_big not stored"); # set the big value my $len = length($big); print $sock "set big 0 0 $len\r\n$big\r\n"; is(scalar <$sock>, "STORED\r\n", "stored big"); mem_get_is($sock, "big", $big); # no evictions yet my $stats = mem_stats($sock); is($stats->{"evictions"}, "0", "no evictions to start"); # set many big items, enough to get evictions for (my $i = 0; $i < 100; $i++) { print $sock "set item_$i 0 0 $len\r\n$big\r\n"; is(scalar <$sock>, "STORED\r\n", "stored item_$i"); } # some evictions should have happened my $stats = mem_stats($sock); my $evictions = int($stats->{"evictions"}); ok($evictions == 37, "some evictions happened"); # the first big value should be gone mem_get_is($sock, "big", undef); # the earliest items should be gone too for (my $i = 0; $i < $evictions - 1; $i++) { mem_get_is($sock, "item_$i", undef); } # check that the non-evicted are the right ones for (my $i = $evictions - 1; $i < $evictions + 4; $i++) { mem_get_is($sock, "item_$i", $big); } memcached-1.4.14/t/getset.t0000755000175000017500000000617411446413300012362 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 539; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # set foo (and should get it) print $sock "set foo 0 0 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); # add bar (and should get it) print $sock "add bar 0 0 6\r\nbarval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored barval"); mem_get_is($sock, "bar", "barval"); # add foo (but shouldn't get new value) print $sock "add foo 0 0 5\r\nfoov2\r\n"; is(scalar <$sock>, "NOT_STORED\r\n", "not stored"); mem_get_is($sock, "foo", "fooval"); # replace bar (should work) print $sock "replace bar 0 0 6\r\nbarva2\r\n"; is(scalar <$sock>, "STORED\r\n", "replaced barval 2"); # replace notexist (shouldn't work) print $sock "replace notexist 0 0 6\r\nbarva2\r\n"; is(scalar <$sock>, "NOT_STORED\r\n", "didn't replace notexist"); # delete foo. print $sock "delete foo\r\n"; is(scalar <$sock>, "DELETED\r\n", "deleted foo"); # delete foo again. not found this time. print $sock "delete foo\r\n"; is(scalar <$sock>, "NOT_FOUND\r\n", "deleted foo, but not found"); # add moo # print $sock "add moo 0 0 6\r\nmooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored barval"); mem_get_is($sock, "moo", "mooval"); # check-and-set (cas) failure case, try to set value with incorrect cas unique val print $sock "cas moo 0 0 6 0\r\nMOOVAL\r\n"; is(scalar <$sock>, "EXISTS\r\n", "check and set with invalid id"); # test "gets", grab unique ID print $sock "gets moo\r\n"; # VALUE moo 0 6 3084947704 # my @retvals = split(/ /, scalar <$sock>); my $data = scalar <$sock>; # grab data my $dot = scalar <$sock>; # grab dot on line by itself is($retvals[0], "VALUE", "get value using 'gets'"); my $unique_id = $retvals[4]; # clean off \r\n $unique_id =~ s/\r\n$//; ok($unique_id =~ /^\d+$/, "unique ID '$unique_id' is an integer"); # now test that we can store moo with the correct unique id print $sock "cas moo 0 0 6 $unique_id\r\nMOOVAL\r\n"; is(scalar <$sock>, "STORED\r\n"); mem_get_is($sock, "moo", "MOOVAL"); # pipeling is okay print $sock "set foo 0 0 6\r\nfooval\r\ndelete foo\r\nset foo 0 0 6\r\nfooval\r\ndelete foo\r\n"; is(scalar <$sock>, "STORED\r\n", "pipeline set"); is(scalar <$sock>, "DELETED\r\n", "pipeline delete"); is(scalar <$sock>, "STORED\r\n", "pipeline set"); is(scalar <$sock>, "DELETED\r\n", "pipeline delete"); # Test sets up to a large size around 1MB. # Everything up to 1MB - 1k should succeed, everything 1MB +1k should fail. my $len = 1024; while ($len < 1024*1028) { my $val = "B"x$len; if ($len > (1024*1024)) { # Ensure causing a memory overflow doesn't leave stale data. print $sock "set foo_$len 0 0 3\r\nMOO\r\n"; is(scalar <$sock>, "STORED\r\n"); print $sock "set foo_$len 0 0 $len\r\n$val\r\n"; is(scalar <$sock>, "SERVER_ERROR object too large for cache\r\n", "failed to store size $len"); mem_get_is($sock, "foo_$len"); } else { print $sock "set foo_$len 0 0 $len\r\n$val\r\n"; is(scalar <$sock>, "STORED\r\n", "stored size $len"); } $len += 2048; } memcached-1.4.14/t/touch.t0000755000175000017500000000073111701635506012212 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 4; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; # set foo (and should get it) print $sock "set foo 0 2 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); # touch it print $sock "touch foo 10\r\n"; is(scalar <$sock>, "TOUCHED\r\n", "touched foo"); sleep 2; mem_get_is($sock, "foo", "fooval"); memcached-1.4.14/t/multiversioning.t0000755000175000017500000000301611246331452014322 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 13; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $sock2 = $server->new_sock; ok($sock != $sock2, "have two different connections open"); # set large value my $size = 256 * 1024; # 256 kB my $bigval = "0123456789abcdef" x ($size / 16); $bigval =~ s/^0/\[/; $bigval =~ s/f$/\]/; my $bigval2 = uc($bigval); print $sock "set big 0 0 $size\r\n$bigval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "big", $bigval, "big value got correctly"); print $sock "get big\r\n"; my $buf; is(read($sock, $buf, $size / 2), $size / 2, "read half the answer back"); like($buf, qr/VALUE big/, "buf has big value header in it"); like($buf, qr/abcdef/, "buf has some data in it"); unlike($buf, qr/abcde\]/, "buf doesn't yet close"); # sock2 interrupts (maybe sock1 is slow) and deletes stuff: print $sock2 "delete big\r\n"; is(scalar <$sock2>, "DELETED\r\n", "deleted big from sock2 while sock1's still reading it"); mem_get_is($sock2, "big", undef, "nothing from sock2 now. gone from namespace."); print $sock2 "set big 0 0 $size\r\n$bigval2\r\n"; is(scalar <$sock2>, "STORED\r\n", "stored big w/ val2"); mem_get_is($sock2, "big", $bigval2, "big value2 got correctly"); # sock1 resumes reading... $buf .= <$sock>; $buf .= <$sock>; like($buf, qr/abcde\]/, "buf now closes"); # and if sock1 reads again, it's the uppercase version: mem_get_is($sock, "big", $bigval2, "big value2 got correctly from sock1"); memcached-1.4.14/t/issue_50.t0000644000175000017500000000060511246331452012516 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 1; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached('-B binary'); my $sock = $server->sock; $SIG{ALRM} = sub { die "alarm\n" }; alarm(2); print $sock "Here's a bunch of garbage that doesn't look like the bin prot."; my $rv = <$sock>; ok(1, "Either the above worked and quit, or hung forever."); memcached-1.4.14/t/issue_68.t0000644000175000017500000000077111446413300012526 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 996; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; for (my $keyi = 1; $keyi < 250; $keyi++) { my $key = "x" x $keyi; print $sock "set $key 0 0 1\r\n9\r\n"; is (scalar <$sock>, "STORED\r\n", "stored $key"); mem_get_is($sock, $key, "9"); print $sock "incr $key 1\r\n"; is (scalar <$sock>, "10\r\n", "incr $key to 10"); mem_get_is($sock, $key, "10"); } memcached-1.4.14/t/expirations.t0000755000175000017500000000332511246331452013434 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 15; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $expire; sub wait_for_early_second { my $have_hires = eval "use Time::HiRes (); 1"; if ($have_hires) { my $tsh = Time::HiRes::time(); my $ts = int($tsh); return if ($tsh - $ts) < 0.5; } my $ts = int(time()); while (1) { my $t = int(time()); return if $t != $ts; select undef, undef, undef, 0.10; # 1/10th of a second sleeps until time changes. } } wait_for_early_second(); print $sock "set foo 0 1 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "fooval"); sleep(1.5); mem_get_is($sock, "foo", undef); $expire = time() - 1; print $sock "set foo 0 $expire 6\r\nfooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", undef, "already expired"); $expire = time() + 1; print $sock "set foo 0 $expire 6\r\nfoov+1\r\n"; is(scalar <$sock>, "STORED\r\n", "stored foo"); mem_get_is($sock, "foo", "foov+1"); sleep(2.2); mem_get_is($sock, "foo", undef, "now expired"); $expire = time() - 20; print $sock "set boo 0 $expire 6\r\nbooval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored boo"); mem_get_is($sock, "boo", undef, "now expired"); print $sock "add add 0 2 6\r\naddval\r\n"; is(scalar <$sock>, "STORED\r\n", "stored add"); mem_get_is($sock, "add", "addval"); # second add fails print $sock "add add 0 2 7\r\naddval2\r\n"; is(scalar <$sock>, "NOT_STORED\r\n", "add failure"); sleep(2.3); print $sock "add add 0 2 7\r\naddval3\r\n"; is(scalar <$sock>, "STORED\r\n", "stored add again"); mem_get_is($sock, "add", "addval3"); memcached-1.4.14/t/binary-get.t0000755000175000017500000000076311246331452013133 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 8; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $count = 1; foreach my $blob ("mooo\0", "mumble\0\0\0\0\r\rblarg", "\0", "\r") { my $key = "foo$count"; my $len = length($blob); print "len is $len\n"; print $sock "set $key 0 0 $len\r\n$blob\r\n"; is(scalar <$sock>, "STORED\r\n", "stored $key"); mem_get_is($sock, $key, $blob); $count++; } memcached-1.4.14/t/sasl/0000755000175000017500000000000011446413300011711 500000000000000memcached-1.4.14/t/sasl/memcached.conf0000644000175000017500000000011711446413300014405 00000000000000mech_list: plain cram-md5 log_level: 5 sasldb_path: /tmp/test-memcached.sasldb memcached-1.4.14/t/64bit.t0000755000175000017500000000216211246331452012015 00000000000000#!/usr/bin/perl use strict; use Test::More; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; $ENV{T_MEMD_INITIAL_MALLOC} = "4294967328"; # 2**32 + 32 , just over 4GB $ENV{T_MEMD_SLABS_ALLOC} = 0; # don't preallocate slabs my $server = new_memcached("-m 4098 -M"); my $sock = $server->sock; my ($stats, $slabs) = @_; $stats = mem_stats($sock); if ($stats->{'pointer_size'} eq "32") { plan skip_all => 'Skipping 64-bit tests on 32-bit build'; exit 0; } else { plan tests => 6; } is($stats->{'pointer_size'}, 64, "is 64 bit"); is($stats->{'limit_maxbytes'}, "4297064448", "max bytes is 4098 MB"); $slabs = mem_stats($sock, 'slabs'); is($slabs->{'total_malloced'}, "4294967328", "expected (faked) value of total_malloced"); is($slabs->{'active_slabs'}, 0, "no active slabs"); my $hit_limit = 0; for (1..5) { my $size = 400 * 1024; my $data = "a" x $size; print $sock "set big$_ 0 0 $size\r\n$data\r\n"; my $res = <$sock>; $hit_limit = 1 if $res ne "STORED\r\n"; } ok($hit_limit, "hit size limit"); $slabs = mem_stats($sock, 'slabs'); is($slabs->{'active_slabs'}, 1, "1 active slab"); memcached-1.4.14/t/item_size_max.t0000644000175000017500000000227411446413300013716 00000000000000#!/usr/bin/perl use strict; use Test::More tests => 7; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; my $server = new_memcached(); my $sock = $server->sock; my $stats = mem_stats($sock, ' settings'); # Ensure default still works. is($stats->{item_size_max}, 1024 * 1024); $server->stop(); # Should die. eval { $server = new_memcached('-I 1000'); }; ok($@ && $@ =~ m/^Failed/, "Shouldn't start with < 1k item max"); eval { $server = new_memcached('-I 256m'); }; ok($@ && $@ =~ m/^Failed/, "Shouldn't start with > 128m item max"); # Minimum. $server = new_memcached('-I 1024'); my $stats = mem_stats($server->sock, ' settings'); is($stats->{item_size_max}, 1024); $server->stop(); # Reasonable but unreasonable. $server = new_memcached('-I 1049600'); my $stats = mem_stats($server->sock, ' settings'); is($stats->{item_size_max}, 1049600); $server->stop(); # Suffix kilobytes. $server = new_memcached('-I 512k'); my $stats = mem_stats($server->sock, ' settings'); is($stats->{item_size_max}, 524288); $server->stop(); # Suffix megabytes. $server = new_memcached('-I 32m'); my $stats = mem_stats($server->sock, ' settings'); is($stats->{item_size_max}, 33554432); $server->stop(); memcached-1.4.14/stats.c0000644000175000017500000003031211701635506011735 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Detailed statistics management. For simple stats like total number of * "get" requests, we use inline code in memcached.c and friends, but when * stats detail mode is activated, the code here records more information. * * Author: * Steven Grimm */ #include "memcached.h" #include #include #include #include /* * Stats are tracked on the basis of key prefixes. This is a simple * fixed-size hash of prefixes; we run the prefixes through the same * CRC function used by the cache hashtable. */ typedef struct _prefix_stats PREFIX_STATS; struct _prefix_stats { char *prefix; size_t prefix_len; uint64_t num_gets; uint64_t num_sets; uint64_t num_deletes; uint64_t num_hits; PREFIX_STATS *next; }; #define PREFIX_HASH_SIZE 256 static PREFIX_STATS *prefix_stats[PREFIX_HASH_SIZE]; static int num_prefixes = 0; static int total_prefix_size = 0; void stats_prefix_init() { memset(prefix_stats, 0, sizeof(prefix_stats)); } /* * Cleans up all our previously collected stats. NOTE: the stats lock is * assumed to be held when this is called. */ void stats_prefix_clear() { int i; for (i = 0; i < PREFIX_HASH_SIZE; i++) { PREFIX_STATS *cur, *next; for (cur = prefix_stats[i]; cur != NULL; cur = next) { next = cur->next; free(cur->prefix); free(cur); } prefix_stats[i] = NULL; } num_prefixes = 0; total_prefix_size = 0; } /* * Returns the stats structure for a prefix, creating it if it's not already * in the list. */ /*@null@*/ static PREFIX_STATS *stats_prefix_find(const char *key, const size_t nkey) { PREFIX_STATS *pfs; uint32_t hashval; size_t length; bool bailout = true; assert(key != NULL); for (length = 0; length < nkey && key[length] != '\0'; length++) { if (key[length] == settings.prefix_delimiter) { bailout = false; break; } } if (bailout) { return NULL; } hashval = hash(key, length, 0) % PREFIX_HASH_SIZE; for (pfs = prefix_stats[hashval]; NULL != pfs; pfs = pfs->next) { if (strncmp(pfs->prefix, key, length) == 0) return pfs; } pfs = calloc(sizeof(PREFIX_STATS), 1); if (NULL == pfs) { perror("Can't allocate space for stats structure: calloc"); return NULL; } pfs->prefix = malloc(length + 1); if (NULL == pfs->prefix) { perror("Can't allocate space for copy of prefix: malloc"); free(pfs); return NULL; } strncpy(pfs->prefix, key, length); pfs->prefix[length] = '\0'; /* because strncpy() sucks */ pfs->prefix_len = length; pfs->next = prefix_stats[hashval]; prefix_stats[hashval] = pfs; num_prefixes++; total_prefix_size += length; return pfs; } /* * Records a "get" of a key. */ void stats_prefix_record_get(const char *key, const size_t nkey, const bool is_hit) { PREFIX_STATS *pfs; STATS_LOCK(); pfs = stats_prefix_find(key, nkey); if (NULL != pfs) { pfs->num_gets++; if (is_hit) { pfs->num_hits++; } } STATS_UNLOCK(); } /* * Records a "delete" of a key. */ void stats_prefix_record_delete(const char *key, const size_t nkey) { PREFIX_STATS *pfs; STATS_LOCK(); pfs = stats_prefix_find(key, nkey); if (NULL != pfs) { pfs->num_deletes++; } STATS_UNLOCK(); } /* * Records a "set" of a key. */ void stats_prefix_record_set(const char *key, const size_t nkey) { PREFIX_STATS *pfs; STATS_LOCK(); pfs = stats_prefix_find(key, nkey); if (NULL != pfs) { pfs->num_sets++; } STATS_UNLOCK(); } /* * Returns stats in textual form suitable for writing to a client. */ /*@null@*/ char *stats_prefix_dump(int *length) { const char *format = "PREFIX %s get %llu hit %llu set %llu del %llu\r\n"; PREFIX_STATS *pfs; char *buf; int i, pos; size_t size = 0, written = 0, total_written = 0; /* * Figure out how big the buffer needs to be. This is the sum of the * lengths of the prefixes themselves, plus the size of one copy of * the per-prefix output with 20-digit values for all the counts, * plus space for the "END" at the end. */ STATS_LOCK(); size = strlen(format) + total_prefix_size + num_prefixes * (strlen(format) - 2 /* %s */ + 4 * (20 - 4)) /* %llu replaced by 20-digit num */ + sizeof("END\r\n"); buf = malloc(size); if (NULL == buf) { perror("Can't allocate stats response: malloc"); STATS_UNLOCK(); return NULL; } pos = 0; for (i = 0; i < PREFIX_HASH_SIZE; i++) { for (pfs = prefix_stats[i]; NULL != pfs; pfs = pfs->next) { written = snprintf(buf + pos, size-pos, format, pfs->prefix, pfs->num_gets, pfs->num_hits, pfs->num_sets, pfs->num_deletes); pos += written; total_written += written; assert(total_written < size); } } STATS_UNLOCK(); memcpy(buf + pos, "END\r\n", 6); *length = pos + 5; return buf; } #ifdef UNIT_TEST /**************************************************************************** To run unit tests, compile with $(CC) -DUNIT_TEST stats.c assoc.o (need assoc.o to get the hash() function). ****************************************************************************/ struct settings settings; static char *current_test = ""; static int test_count = 0; static int fail_count = 0; static void fail(char *what) { printf("\tFAIL: %s\n", what); fflush(stdout); fail_count++; } static void test_equals_int(char *what, int a, int b) { test_count++; if (a != b) fail(what); } static void test_equals_ptr(char *what, void *a, void *b) { test_count++; if (a != b) fail(what); } static void test_equals_str(char *what, const char *a, const char *b) { test_count++; if (strcmp(a, b)) fail(what); } static void test_equals_ull(char *what, uint64_t a, uint64_t b) { test_count++; if (a != b) fail(what); } static void test_notequals_ptr(char *what, void *a, void *b) { test_count++; if (a == b) fail(what); } static void test_notnull_ptr(char *what, void *a) { test_count++; if (NULL == a) fail(what); } static void test_prefix_find() { PREFIX_STATS *pfs1, *pfs2; pfs1 = stats_prefix_find("abc"); test_notnull_ptr("initial prefix find", pfs1); test_equals_ull("request counts", 0ULL, pfs1->num_gets + pfs1->num_sets + pfs1->num_deletes + pfs1->num_hits); pfs2 = stats_prefix_find("abc"); test_equals_ptr("find of same prefix", pfs1, pfs2); pfs2 = stats_prefix_find("abc:"); test_equals_ptr("find of same prefix, ignoring delimiter", pfs1, pfs2); pfs2 = stats_prefix_find("abc:d"); test_equals_ptr("find of same prefix, ignoring extra chars", pfs1, pfs2); pfs2 = stats_prefix_find("xyz123"); test_notequals_ptr("find of different prefix", pfs1, pfs2); pfs2 = stats_prefix_find("ab:"); test_notequals_ptr("find of shorter prefix", pfs1, pfs2); } static void test_prefix_record_get() { PREFIX_STATS *pfs; stats_prefix_record_get("abc:123", 0); pfs = stats_prefix_find("abc:123"); test_equals_ull("get count after get #1", 1, pfs->num_gets); test_equals_ull("hit count after get #1", 0, pfs->num_hits); stats_prefix_record_get("abc:456", 0); test_equals_ull("get count after get #2", 2, pfs->num_gets); test_equals_ull("hit count after get #2", 0, pfs->num_hits); stats_prefix_record_get("abc:456", 1); test_equals_ull("get count after get #3", 3, pfs->num_gets); test_equals_ull("hit count after get #3", 1, pfs->num_hits); stats_prefix_record_get("def:", 1); test_equals_ull("get count after get #4", 3, pfs->num_gets); test_equals_ull("hit count after get #4", 1, pfs->num_hits); } static void test_prefix_record_delete() { PREFIX_STATS *pfs; stats_prefix_record_delete("abc:123"); pfs = stats_prefix_find("abc:123"); test_equals_ull("get count after delete #1", 0, pfs->num_gets); test_equals_ull("hit count after delete #1", 0, pfs->num_hits); test_equals_ull("delete count after delete #1", 1, pfs->num_deletes); test_equals_ull("set count after delete #1", 0, pfs->num_sets); stats_prefix_record_delete("def:"); test_equals_ull("delete count after delete #2", 1, pfs->num_deletes); } static void test_prefix_record_set() { PREFIX_STATS *pfs; stats_prefix_record_set("abc:123"); pfs = stats_prefix_find("abc:123"); test_equals_ull("get count after set #1", 0, pfs->num_gets); test_equals_ull("hit count after set #1", 0, pfs->num_hits); test_equals_ull("delete count after set #1", 0, pfs->num_deletes); test_equals_ull("set count after set #1", 1, pfs->num_sets); stats_prefix_record_delete("def:"); test_equals_ull("set count after set #2", 1, pfs->num_sets); } static void test_prefix_dump() { int hashval = hash("abc", 3, 0) % PREFIX_HASH_SIZE; char tmp[500]; char *expected; int keynum; int length; test_equals_str("empty stats", "END\r\n", stats_prefix_dump(&length)); test_equals_int("empty stats length", 5, length); stats_prefix_record_set("abc:123"); expected = "PREFIX abc get 0 hit 0 set 1 del 0\r\nEND\r\n"; test_equals_str("stats after set", expected, stats_prefix_dump(&length)); test_equals_int("stats length after set", strlen(expected), length); stats_prefix_record_get("abc:123", 0); expected = "PREFIX abc get 1 hit 0 set 1 del 0\r\nEND\r\n"; test_equals_str("stats after get #1", expected, stats_prefix_dump(&length)); test_equals_int("stats length after get #1", strlen(expected), length); stats_prefix_record_get("abc:123", 1); expected = "PREFIX abc get 2 hit 1 set 1 del 0\r\nEND\r\n"; test_equals_str("stats after get #2", expected, stats_prefix_dump(&length)); test_equals_int("stats length after get #2", strlen(expected), length); stats_prefix_record_delete("abc:123"); expected = "PREFIX abc get 2 hit 1 set 1 del 1\r\nEND\r\n"; test_equals_str("stats after del #1", expected, stats_prefix_dump(&length)); test_equals_int("stats length after del #1", strlen(expected), length); /* The order of results might change if we switch hash functions. */ stats_prefix_record_delete("def:123"); expected = "PREFIX abc get 2 hit 1 set 1 del 1\r\n" "PREFIX def get 0 hit 0 set 0 del 1\r\n" "END\r\n"; test_equals_str("stats after del #2", expected, stats_prefix_dump(&length)); test_equals_int("stats length after del #2", strlen(expected), length); /* Find a key that hashes to the same bucket as "abc" */ for (keynum = 0; keynum < PREFIX_HASH_SIZE * 100; keynum++) { snprintf(tmp, sizeof(tmp), "%d", keynum); if (hashval == hash(tmp, strlen(tmp), 0) % PREFIX_HASH_SIZE) { break; } } stats_prefix_record_set(tmp); snprintf(tmp, sizeof(tmp), "PREFIX %d get 0 hit 0 set 1 del 0\r\n" "PREFIX abc get 2 hit 1 set 1 del 1\r\n" "PREFIX def get 0 hit 0 set 0 del 1\r\n" "END\r\n", keynum); test_equals_str("stats with two stats in one bucket", tmp, stats_prefix_dump(&length)); test_equals_int("stats length with two stats in one bucket", strlen(tmp), length); } static void run_test(char *what, void (*func)(void)) { current_test = what; test_count = fail_count = 0; puts(what); fflush(stdout); stats_prefix_clear(); (func)(); printf("\t%d / %d pass\n", (test_count - fail_count), test_count); } /* In case we're compiled in thread mode */ void mt_stats_lock() { } void mt_stats_unlock() { } main(int argc, char **argv) { stats_prefix_init(); settings.prefix_delimiter = ':'; run_test("stats_prefix_find", test_prefix_find); run_test("stats_prefix_record_get", test_prefix_record_get); run_test("stats_prefix_record_delete", test_prefix_record_delete); run_test("stats_prefix_record_set", test_prefix_record_set); run_test("stats_prefix_dump", test_prefix_dump); } #endif memcached-1.4.14/daemon.c0000644000175000017500000000601211701635506012042 00000000000000/* $Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $ */ /* $NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $ */ /*- * 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. 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 __SUNPRO_C || defined __DECC || defined __HP_cc # pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $" # pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $" #endif #include #include #include #include #include "memcached.h" int daemonize(int nochdir, int noclose) { int fd; switch (fork()) { case -1: return (-1); case 0: break; default: _exit(EXIT_SUCCESS); } if (setsid() == -1) return (-1); if (nochdir == 0) { if(chdir("/") != 0) { perror("chdir"); return (-1); } } if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) { if(dup2(fd, STDIN_FILENO) < 0) { perror("dup2 stdin"); return (-1); } if(dup2(fd, STDOUT_FILENO) < 0) { perror("dup2 stdout"); return (-1); } if(dup2(fd, STDERR_FILENO) < 0) { perror("dup2 stderr"); return (-1); } if (fd > STDERR_FILENO) { if(close(fd) < 0) { perror("close"); return (-1); } } } return (0); } memcached-1.4.14/hash.h0000644000175000017500000000031511701635506011527 00000000000000#ifndef HASH_H #define HASH_H #ifdef __cplusplus extern "C" { #endif uint32_t hash(const void *key, size_t length, const uint32_t initval); #ifdef __cplusplus } #endif #endif /* HASH_H */ memcached-1.4.14/stats.h0000644000175000017500000000052611701635506011746 00000000000000/* stats */ void stats_prefix_init(void); void stats_prefix_clear(void); void stats_prefix_record_get(const char *key, const size_t nkey, const bool is_hit); void stats_prefix_record_delete(const char *key, const size_t nkey); void stats_prefix_record_set(const char *key, const size_t nkey); /*@null@*/ char *stats_prefix_dump(int *length); memcached-1.4.14/hash.c0000644000175000017500000003463211701635506011533 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Hash table * * The hash function used here is by Bob Jenkins, 1996: * * "By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. * You may use this code any way you wish, private, educational, * or commercial. It's free." * */ #include "memcached.h" /* * Since the hash function does bit manipulation, it needs to know * whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG * are set in the configure script. */ #if ENDIAN_BIG == 1 # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 1 #else # if ENDIAN_LITTLE == 1 # define HASH_LITTLE_ENDIAN 1 # define HASH_BIG_ENDIAN 0 # else # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 0 # endif #endif #define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k)))) /* ------------------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. This is reversible, so any information in (a,b,c) before mix() is still in (a,b,c) after mix(). If four pairs of (a,b,c) inputs are run through mix(), or through mix() in reverse, there are at least 32 bits of the output that are sometimes the same for one pair and different for another pair. This was tested for: * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that satisfy this are 4 6 8 16 19 4 9 15 3 18 27 15 14 9 3 7 17 3 Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing for "differ" defined as + with a one-bit base and a two-bit delta. I used http://burtleburtle.net/bob/hash/avalanche.html to choose the operations, constants, and arrangements of the variables. This does not achieve avalanche. There are input bits of (a,b,c) that fail to affect some output bits of (a,b,c), especially of a. The most thoroughly mixed value is c, but it doesn't really even achieve avalanche in c. This allows some parallelism. Read-after-writes are good at doubling the number of bits affected, so the goal of mixing pulls in the opposite direction as the goal of parallelism. I did what I could. Rotates seem to cost as much as shifts on every machine I could lay my hands on, and rotates are much kinder to the top and bottom bits, so I used rotates. ------------------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } /* ------------------------------------------------------------------------------- final -- final mixing of 3 32-bit values (a,b,c) into c Pairs of (a,b,c) values differing in only a few bits will usually produce values of c that look totally different. This was tested for * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. These constants passed: 14 11 25 16 4 14 24 12 14 25 16 4 14 24 and these came close: 4 8 15 26 3 22 24 10 8 15 26 3 22 24 11 8 15 26 3 22 24 ------------------------------------------------------------------------------- */ #define final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } #if HASH_LITTLE_ENDIAN == 1 uint32_t hash( const void *key, /* the key to hash */ size_t length, /* length of the key */ const uint32_t initval) /* initval */ { uint32_t a,b,c; /* internal state */ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; u.ptr = key; if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = key; /* read 32-bit chunks */ #ifdef VALGRIND const uint8_t *k8; #endif /* ifdef VALGRIND */ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]&0xffffff" actually reads beyond the end of the string, but * then masks off the part it's not allowed to read. Because the * string is aligned, the masked-off tail is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). */ #ifndef VALGRIND switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff; a+=k[0]; break; case 6 : b+=k[1]&0xffff; a+=k[0]; break; case 5 : b+=k[1]&0xff; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff; break; case 2 : a+=k[0]&0xffff; break; case 1 : a+=k[0]&0xff; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ case 1 : a+=k8[0]; break; case 0 : return c; /* zero length strings require no mixing */ } #endif /* !valgrind */ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { const uint16_t *k = key; /* read 16-bit chunks */ const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ while (length > 12) { a += k[0] + (((uint32_t)k[1])<<16); b += k[2] + (((uint32_t)k[3])<<16); c += k[4] + (((uint32_t)k[5])<<16); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[4]+(((uint32_t)k[5])<<16); b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 11: c+=((uint32_t)k8[10])<<16; /* @fallthrough */ case 10: c+=k[4]; /* @fallthrough@ */ b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 9 : c+=k8[8]; /* @fallthrough */ case 8 : b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 7 : b+=((uint32_t)k8[6])<<16; /* @fallthrough */ case 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; case 5 : b+=k8[4]; /* @fallthrough */ case 4 : a+=k[0]+(((uint32_t)k[1])<<16); break; case 3 : a+=((uint32_t)k8[2])<<16; /* @fallthrough */ case 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : return c; /* zero length strings require no mixing */ } } else { /* need to read the key one byte at a time */ const uint8_t *k = key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; a += ((uint32_t)k[1])<<8; a += ((uint32_t)k[2])<<16; a += ((uint32_t)k[3])<<24; b += k[4]; b += ((uint32_t)k[5])<<8; b += ((uint32_t)k[6])<<16; b += ((uint32_t)k[7])<<24; c += k[8]; c += ((uint32_t)k[9])<<8; c += ((uint32_t)k[10])<<16; c += ((uint32_t)k[11])<<24; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=((uint32_t)k[11])<<24; case 11: c+=((uint32_t)k[10])<<16; case 10: c+=((uint32_t)k[9])<<8; case 9 : c+=k[8]; case 8 : b+=((uint32_t)k[7])<<24; case 7 : b+=((uint32_t)k[6])<<16; case 6 : b+=((uint32_t)k[5])<<8; case 5 : b+=k[4]; case 4 : a+=((uint32_t)k[3])<<24; case 3 : a+=((uint32_t)k[2])<<16; case 2 : a+=((uint32_t)k[1])<<8; case 1 : a+=k[0]; break; case 0 : return c; /* zero length strings require no mixing */ } } final(a,b,c); return c; /* zero length strings require no mixing */ } #elif HASH_BIG_ENDIAN == 1 /* * hashbig(): * This is the same as hashword() on big-endian machines. It is different * from hashlittle() on all machines. hashbig() takes advantage of * big-endian byte ordering. */ uint32_t hash( const void *key, size_t length, const uint32_t initval) { uint32_t a,b,c; union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; u.ptr = key; if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = key; /* read 32-bit chunks */ #ifdef VALGRIND const uint8_t *k8; #endif /* ifdef VALGRIND */ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]<<8" actually reads beyond the end of the string, but * then shifts out the part it's not allowed to read. Because the * string is aligned, the illegal read is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). */ #ifndef VALGRIND switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; case 5 : b+=k[1]&0xff000000; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff00; break; case 2 : a+=k[0]&0xffff0000; break; case 1 : a+=k[0]&0xff000000; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ k8 = (const uint8_t *)k; switch(length) /* all the case statements fall through */ { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ case 1 : a+=((uint32_t)k8[0])<<24; break; case 0 : return c; } #endif /* !VALGRIND */ } else { /* need to read the key one byte at a time */ const uint8_t *k = key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += ((uint32_t)k[0])<<24; a += ((uint32_t)k[1])<<16; a += ((uint32_t)k[2])<<8; a += ((uint32_t)k[3]); b += ((uint32_t)k[4])<<24; b += ((uint32_t)k[5])<<16; b += ((uint32_t)k[6])<<8; b += ((uint32_t)k[7]); c += ((uint32_t)k[8])<<24; c += ((uint32_t)k[9])<<16; c += ((uint32_t)k[10])<<8; c += ((uint32_t)k[11]); mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=k[11]; case 11: c+=((uint32_t)k[10])<<8; case 10: c+=((uint32_t)k[9])<<16; case 9 : c+=((uint32_t)k[8])<<24; case 8 : b+=k[7]; case 7 : b+=((uint32_t)k[6])<<8; case 6 : b+=((uint32_t)k[5])<<16; case 5 : b+=((uint32_t)k[4])<<24; case 4 : a+=k[3]; case 3 : a+=((uint32_t)k[2])<<8; case 2 : a+=((uint32_t)k[1])<<16; case 1 : a+=((uint32_t)k[0])<<24; break; case 0 : return c; } } final(a,b,c); return c; } #else /* HASH_XXX_ENDIAN == 1 */ #error Must define HASH_BIG_ENDIAN or HASH_LITTLE_ENDIAN #endif /* HASH_XXX_ENDIAN == 1 */ memcached-1.4.14/install-sh0000755000175000017500000003253711331674343012453 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: memcached-1.4.14/assoc.h0000644000175000017500000000060211701635506011713 00000000000000/* associative array */ void assoc_init(const int hashpower_init); item *assoc_find(const char *key, const size_t nkey, const uint32_t hv); int assoc_insert(item *item, const uint32_t hv); void assoc_delete(const char *key, const size_t nkey, const uint32_t hv); void do_assoc_move_next_bucket(void); int start_assoc_maintenance_thread(void); void stop_assoc_maintenance_thread(void); memcached-1.4.14/sasl_defs.c0000644000175000017500000001172111712423271012541 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "memcached.h" #include #include #include #include char my_sasl_hostname[1025]; #ifdef HAVE_SASL_CB_GETCONF /* The locations we may search for a SASL config file if the user didn't * specify one in the environment variable SASL_CONF_PATH */ const char * const locations[] = { "/etc/sasl/memcached.conf", "/etc/sasl2/memcached.conf", NULL }; #endif #ifndef HAVE_SASL_CALLBACK_FT typedef int (*sasl_callback_ft)(void); #endif #ifdef ENABLE_SASL_PWDB #define MAX_ENTRY_LEN 256 static const char *memcached_sasl_pwdb; static int sasl_server_userdb_checkpass(sasl_conn_t *conn, void *context, const char *user, const char *pass, unsigned passlen, struct propctx *propctx) { size_t unmlen = strlen(user); if ((passlen + unmlen) > (MAX_ENTRY_LEN - 4)) { fprintf(stderr, "WARNING: Failed to authenticate <%s> due to too long password (%d)\n", user, passlen); return SASL_NOAUTHZ; } FILE *pwfile = fopen(memcached_sasl_pwdb, "r"); if (pwfile == NULL) { if (settings.verbose) { vperror("WARNING: Failed to open sasl database <%s>", memcached_sasl_pwdb); } return SASL_NOAUTHZ; } char buffer[MAX_ENTRY_LEN]; bool ok = false; while ((fgets(buffer, sizeof(buffer), pwfile)) != NULL) { if (memcmp(user, buffer, unmlen) == 0 && buffer[unmlen] == ':') { /* This is the correct user */ ++unmlen; if (memcmp(pass, buffer + unmlen, passlen) == 0 && (buffer[unmlen + passlen] == ':' || /* Additional tokens */ buffer[unmlen + passlen] == '\n' || /* end of line */ buffer[unmlen + passlen] == '\r'|| /* dos format? */ buffer[unmlen + passlen] == '\0')) { /* line truncated */ ok = true; } break; } } (void)fclose(pwfile); if (ok) { return SASL_OK; } if (settings.verbose) { fprintf(stderr, "INFO: User <%s> failed to authenticate\n", user); } return SASL_NOAUTHZ; } #endif #ifdef HAVE_SASL_CB_GETCONF static int sasl_getconf(void *context, const char **path) { *path = getenv("SASL_CONF_PATH"); if (*path == NULL) { for (int i = 0; locations[i] != NULL; ++i) { if (access(locations[i], F_OK) == 0) { *path = locations[i]; break; } } } if (settings.verbose) { if (*path != NULL) { fprintf(stderr, "Reading configuration from: <%s>\n", *path); } else { fprintf(stderr, "Failed to locate a config path\n"); } } return (*path != NULL) ? SASL_OK : SASL_FAIL; } #endif static int sasl_log(void *context, int level, const char *message) { bool log = true; switch (level) { case SASL_LOG_NONE: log = false; break; case SASL_LOG_PASS: case SASL_LOG_TRACE: case SASL_LOG_DEBUG: case SASL_LOG_NOTE: if (settings.verbose < 2) { log = false; } break; case SASL_LOG_WARN: case SASL_LOG_FAIL: if (settings.verbose < 1) { log = false; } break; default: /* This is an error */ ; } if (log) { fprintf(stderr, "SASL (severity %d): %s\n", level, message); } return SASL_OK; } static sasl_callback_t sasl_callbacks[] = { #ifdef ENABLE_SASL_PWDB { SASL_CB_SERVER_USERDB_CHECKPASS, sasl_server_userdb_checkpass, NULL }, #endif { SASL_CB_LOG, (sasl_callback_ft)sasl_log, NULL }, #ifdef HAVE_SASL_CB_GETCONF { SASL_CB_GETCONF, sasl_getconf, NULL }, #endif { SASL_CB_LIST_END, NULL, NULL } }; void init_sasl(void) { #ifdef ENABLE_SASL_PWDB memcached_sasl_pwdb = getenv("MEMCACHED_SASL_PWDB"); if (memcached_sasl_pwdb == NULL) { if (settings.verbose) { fprintf(stderr, "INFO: MEMCACHED_SASL_PWDB not specified. " "Internal passwd database disabled\n"); } sasl_callbacks[0].id = SASL_CB_LIST_END; sasl_callbacks[0].proc = NULL; } #endif memset(my_sasl_hostname, 0, sizeof(my_sasl_hostname)); if (gethostname(my_sasl_hostname, sizeof(my_sasl_hostname)-1) == -1) { if (settings.verbose) { fprintf(stderr, "Error discovering hostname for SASL\n"); } my_sasl_hostname[0] = '\0'; } if (sasl_server_init(sasl_callbacks, "memcached") != SASL_OK) { fprintf(stderr, "Error initializing sasl.\n"); exit(EXIT_FAILURE); } else { if (settings.verbose) { fprintf(stderr, "Initialized SASL.\n"); } } } memcached-1.4.14/testapp.c0000644000175000017500000020067212004570104012254 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #undef NDEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "cache.h" #include "util.h" #include "protocol_binary.h" #define TMP_TEMPLATE "/tmp/test_file.XXXXXXX" enum test_return { TEST_SKIP, TEST_PASS, TEST_FAIL }; static pid_t server_pid; static in_port_t port; static int sock; static bool allow_closed_read = false; static enum test_return cache_create_test(void) { cache_t *cache = cache_create("test", sizeof(uint32_t), sizeof(char*), NULL, NULL); assert(cache != NULL); cache_destroy(cache); return TEST_PASS; } const uint64_t constructor_pattern = 0xdeadcafebabebeef; static int cache_constructor(void *buffer, void *notused1, int notused2) { uint64_t *ptr = buffer; *ptr = constructor_pattern; return 0; } static enum test_return cache_constructor_test(void) { cache_t *cache = cache_create("test", sizeof(uint64_t), sizeof(uint64_t), cache_constructor, NULL); assert(cache != NULL); uint64_t *ptr = cache_alloc(cache); uint64_t pattern = *ptr; cache_free(cache, ptr); cache_destroy(cache); return (pattern == constructor_pattern) ? TEST_PASS : TEST_FAIL; } static int cache_fail_constructor(void *buffer, void *notused1, int notused2) { return 1; } static enum test_return cache_fail_constructor_test(void) { enum test_return ret = TEST_PASS; cache_t *cache = cache_create("test", sizeof(uint64_t), sizeof(uint64_t), cache_fail_constructor, NULL); assert(cache != NULL); uint64_t *ptr = cache_alloc(cache); if (ptr != NULL) { ret = TEST_FAIL; } cache_destroy(cache); return ret; } static void *destruct_data = 0; static void cache_destructor(void *buffer, void *notused) { destruct_data = buffer; } static enum test_return cache_destructor_test(void) { cache_t *cache = cache_create("test", sizeof(uint32_t), sizeof(char*), NULL, cache_destructor); assert(cache != NULL); char *ptr = cache_alloc(cache); cache_free(cache, ptr); cache_destroy(cache); return (ptr == destruct_data) ? TEST_PASS : TEST_FAIL; } static enum test_return cache_reuse_test(void) { int ii; cache_t *cache = cache_create("test", sizeof(uint32_t), sizeof(char*), NULL, NULL); char *ptr = cache_alloc(cache); cache_free(cache, ptr); for (ii = 0; ii < 100; ++ii) { char *p = cache_alloc(cache); assert(p == ptr); cache_free(cache, ptr); } cache_destroy(cache); return TEST_PASS; } static enum test_return cache_bulkalloc(size_t datasize) { cache_t *cache = cache_create("test", datasize, sizeof(char*), NULL, NULL); #define ITERATIONS 1024 void *ptr[ITERATIONS]; for (int ii = 0; ii < ITERATIONS; ++ii) { ptr[ii] = cache_alloc(cache); assert(ptr[ii] != 0); memset(ptr[ii], 0xff, datasize); } for (int ii = 0; ii < ITERATIONS; ++ii) { cache_free(cache, ptr[ii]); } #undef ITERATIONS cache_destroy(cache); return TEST_PASS; } static enum test_return test_issue_161(void) { enum test_return ret = cache_bulkalloc(1); if (ret == TEST_PASS) { ret = cache_bulkalloc(512); } return ret; } static enum test_return cache_redzone_test(void) { #ifndef HAVE_UMEM_H cache_t *cache = cache_create("test", sizeof(uint32_t), sizeof(char*), NULL, NULL); /* Ignore SIGABORT */ struct sigaction old_action; struct sigaction action = { .sa_handler = SIG_IGN, .sa_flags = 0}; sigemptyset(&action.sa_mask); sigaction(SIGABRT, &action, &old_action); /* check memory debug.. */ char *p = cache_alloc(cache); char old = *(p - 1); *(p - 1) = 0; cache_free(cache, p); assert(cache_error == -1); *(p - 1) = old; p[sizeof(uint32_t)] = 0; cache_free(cache, p); assert(cache_error == 1); /* restore signal handler */ sigaction(SIGABRT, &old_action, NULL); cache_destroy(cache); return TEST_PASS; #else return TEST_SKIP; #endif } static enum test_return test_safe_strtoul(void) { uint32_t val; assert(safe_strtoul("123", &val)); assert(val == 123); assert(safe_strtoul("+123", &val)); assert(val == 123); assert(!safe_strtoul("", &val)); // empty assert(!safe_strtoul("123BOGUS", &val)); // non-numeric assert(!safe_strtoul(" issue221", &val)); // non-numeric /* Not sure what it does, but this works with ICC :/ assert(!safe_strtoul("92837498237498237498029383", &val)); // out of range */ // extremes: assert(safe_strtoul("4294967295", &val)); // 2**32 - 1 assert(val == 4294967295L); /* This actually works on 64-bit ubuntu assert(!safe_strtoul("4294967296", &val)); // 2**32 */ assert(!safe_strtoul("-1", &val)); // negative return TEST_PASS; } static enum test_return test_safe_strtoull(void) { uint64_t val; assert(safe_strtoull("123", &val)); assert(val == 123); assert(safe_strtoull("+123", &val)); assert(val == 123); assert(!safe_strtoull("", &val)); // empty assert(!safe_strtoull("123BOGUS", &val)); // non-numeric assert(!safe_strtoull("92837498237498237498029383", &val)); // out of range assert(!safe_strtoull(" issue221", &val)); // non-numeric // extremes: assert(safe_strtoull("18446744073709551615", &val)); // 2**64 - 1 assert(val == 18446744073709551615ULL); assert(!safe_strtoull("18446744073709551616", &val)); // 2**64 assert(!safe_strtoull("-1", &val)); // negative return TEST_PASS; } static enum test_return test_safe_strtoll(void) { int64_t val; assert(safe_strtoll("123", &val)); assert(val == 123); assert(safe_strtoll("+123", &val)); assert(val == 123); assert(safe_strtoll("-123", &val)); assert(val == -123); assert(!safe_strtoll("", &val)); // empty assert(!safe_strtoll("123BOGUS", &val)); // non-numeric assert(!safe_strtoll("92837498237498237498029383", &val)); // out of range assert(!safe_strtoll(" issue221", &val)); // non-numeric // extremes: assert(!safe_strtoll("18446744073709551615", &val)); // 2**64 - 1 assert(safe_strtoll("9223372036854775807", &val)); // 2**63 - 1 assert(val == 9223372036854775807LL); /* assert(safe_strtoll("-9223372036854775808", &val)); // -2**63 assert(val == -9223372036854775808LL); */ assert(!safe_strtoll("-9223372036854775809", &val)); // -2**63 - 1 // We'll allow space to terminate the string. And leading space. assert(safe_strtoll(" 123 foo", &val)); assert(val == 123); return TEST_PASS; } static enum test_return test_safe_strtol(void) { int32_t val; assert(safe_strtol("123", &val)); assert(val == 123); assert(safe_strtol("+123", &val)); assert(val == 123); assert(safe_strtol("-123", &val)); assert(val == -123); assert(!safe_strtol("", &val)); // empty assert(!safe_strtol("123BOGUS", &val)); // non-numeric assert(!safe_strtol("92837498237498237498029383", &val)); // out of range assert(!safe_strtol(" issue221", &val)); // non-numeric // extremes: /* This actually works on 64-bit ubuntu assert(!safe_strtol("2147483648", &val)); // (expt 2.0 31.0) */ assert(safe_strtol("2147483647", &val)); // (- (expt 2.0 31) 1) assert(val == 2147483647L); /* This actually works on 64-bit ubuntu assert(!safe_strtol("-2147483649", &val)); // (- (expt -2.0 31) 1) */ // We'll allow space to terminate the string. And leading space. assert(safe_strtol(" 123 foo", &val)); assert(val == 123); return TEST_PASS; } /** * Function to start the server and let it listen on a random port * * @param port_out where to store the TCP port number the server is * listening on * @param daemon set to true if you want to run the memcached server * as a daemon process * @return the pid of the memcached server */ static pid_t start_server(in_port_t *port_out, bool daemon, int timeout) { char environment[80]; snprintf(environment, sizeof(environment), "MEMCACHED_PORT_FILENAME=/tmp/ports.%lu", (long)getpid()); char *filename= environment + strlen("MEMCACHED_PORT_FILENAME="); char pid_file[80]; snprintf(pid_file, sizeof(pid_file), "/tmp/pid.%lu", (long)getpid()); remove(filename); remove(pid_file); #ifdef __sun /* I want to name the corefiles differently so that they don't overwrite each other */ char coreadm[128]; snprintf(coreadm, sizeof(coreadm), "coreadm -p core.%%f.%%p %lu", (unsigned long)getpid()); system(coreadm); #endif pid_t pid = fork(); assert(pid != -1); if (pid == 0) { /* Child */ char *argv[20]; int arg = 0; char tmo[24]; snprintf(tmo, sizeof(tmo), "%u", timeout); putenv(environment); #ifdef __sun putenv("LD_PRELOAD=watchmalloc.so.1"); putenv("MALLOC_DEBUG=WATCH"); #endif if (!daemon) { argv[arg++] = "./timedrun"; argv[arg++] = tmo; } argv[arg++] = "./memcached-debug"; argv[arg++] = "-p"; argv[arg++] = "-1"; argv[arg++] = "-U"; argv[arg++] = "0"; /* Handle rpmbuild and the like doing this as root */ if (getuid() == 0) { argv[arg++] = "-u"; argv[arg++] = "root"; } if (daemon) { argv[arg++] = "-d"; argv[arg++] = "-P"; argv[arg++] = pid_file; } #ifdef MESSAGE_DEBUG argv[arg++] = "-vvv"; #endif argv[arg++] = NULL; assert(execv(argv[0], argv) != -1); } /* Yeah just let us "busy-wait" for the file to be created ;-) */ while (access(filename, F_OK) == -1) { usleep(10); } FILE *fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "Failed to open the file containing port numbers: %s\n", strerror(errno)); assert(false); } *port_out = (in_port_t)-1; char buffer[80]; while ((fgets(buffer, sizeof(buffer), fp)) != NULL) { if (strncmp(buffer, "TCP INET: ", 10) == 0) { int32_t val; assert(safe_strtol(buffer + 10, &val)); *port_out = (in_port_t)val; } } fclose(fp); assert(remove(filename) == 0); if (daemon) { /* loop and wait for the pid file.. There is a potential race * condition that the server just created the file but isn't * finished writing the content, so we loop a few times * reading as well */ while (access(pid_file, F_OK) == -1) { usleep(10); } fp = fopen(pid_file, "r"); if (fp == NULL) { fprintf(stderr, "Failed to open pid file: %s\n", strerror(errno)); assert(false); } /* Avoid race by retrying 20 times */ for (int x = 0; x < 20 && fgets(buffer, sizeof(buffer), fp) == NULL; x++) { usleep(10); } fclose(fp); int32_t val; assert(safe_strtol(buffer, &val)); pid = (pid_t)val; } return pid; } static enum test_return test_issue_44(void) { in_port_t port; pid_t pid = start_server(&port, true, 15); assert(kill(pid, SIGHUP) == 0); sleep(1); assert(kill(pid, SIGTERM) == 0); return TEST_PASS; } static struct addrinfo *lookuphost(const char *hostname, in_port_t port) { struct addrinfo *ai = 0; struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_protocol = IPPROTO_TCP, .ai_socktype = SOCK_STREAM }; char service[NI_MAXSERV]; int error; (void)snprintf(service, NI_MAXSERV, "%d", port); if ((error = getaddrinfo(hostname, service, &hints, &ai)) != 0) { if (error != EAI_SYSTEM) { fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error)); } else { perror("getaddrinfo()"); } } return ai; } static int connect_server(const char *hostname, in_port_t port, bool nonblock) { struct addrinfo *ai = lookuphost(hostname, port); int sock = -1; if (ai != NULL) { if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) != -1) { if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { fprintf(stderr, "Failed to connect socket: %s\n", strerror(errno)); close(sock); sock = -1; } else if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); if (flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) { fprintf(stderr, "Failed to enable nonblocking mode: %s\n", strerror(errno)); close(sock); sock = -1; } } } else { fprintf(stderr, "Failed to create socket: %s\n", strerror(errno)); } freeaddrinfo(ai); } return sock; } static enum test_return test_vperror(void) { int rv = 0; int oldstderr = dup(STDERR_FILENO); char tmpl[sizeof(TMP_TEMPLATE)+1]; strncpy(tmpl, TMP_TEMPLATE, sizeof(TMP_TEMPLATE)+1); int newfile = mkstemp(tmpl); assert(newfile > 0); rv = dup2(newfile, STDERR_FILENO); assert(rv == STDERR_FILENO); rv = close(newfile); assert(rv == 0); errno = EIO; vperror("Old McDonald had a farm. %s", "EI EIO"); /* Restore stderr */ rv = dup2(oldstderr, STDERR_FILENO); assert(rv == STDERR_FILENO); /* Go read the file */ char buf[80] = { 0 }; FILE *efile = fopen(tmpl, "r"); assert(efile); char *prv = fgets(buf, sizeof(buf), efile); assert(prv); fclose(efile); unlink(tmpl); char expected[80] = { 0 }; snprintf(expected, sizeof(expected), "Old McDonald had a farm. EI EIO: %s\n", strerror(EIO)); /* fprintf(stderr, "\nExpected: ``%s''" "\nGot: ``%s''\n", expected, buf); */ return strcmp(expected, buf) == 0 ? TEST_PASS : TEST_FAIL; } static void send_ascii_command(const char *buf) { off_t offset = 0; const char* ptr = buf; size_t len = strlen(buf); do { ssize_t nw = write(sock, ptr + offset, len - offset); if (nw == -1) { if (errno != EINTR) { fprintf(stderr, "Failed to write: %s\n", strerror(errno)); abort(); } } else { offset += nw; } } while (offset < len); } /* * This is a dead slow single byte read, but it should only read out * _one_ response and I don't have an input buffer... The current * implementation only supports single-line responses, so if you want to use * it for get commands you need to implement that first ;-) */ static void read_ascii_response(char *buffer, size_t size) { off_t offset = 0; bool need_more = true; do { ssize_t nr = read(sock, buffer + offset, 1); if (nr == -1) { if (errno != EINTR) { fprintf(stderr, "Failed to read: %s\n", strerror(errno)); abort(); } } else { assert(nr == 1); if (buffer[offset] == '\n') { need_more = false; buffer[offset + 1] = '\0'; } offset += nr; assert(offset + 1 < size); } } while (need_more); } static enum test_return test_issue_92(void) { char buffer[1024]; close(sock); sock = connect_server("127.0.0.1", port, false); send_ascii_command("stats cachedump 1 0 0\r\n"); read_ascii_response(buffer, sizeof(buffer)); assert(strncmp(buffer, "END", strlen("END")) == 0); send_ascii_command("stats cachedump 200 0 0\r\n"); read_ascii_response(buffer, sizeof(buffer)); assert(strncmp(buffer, "CLIENT_ERROR", strlen("CLIENT_ERROR")) == 0); close(sock); sock = connect_server("127.0.0.1", port, false); return TEST_PASS; } static enum test_return test_issue_102(void) { char buffer[4096]; memset(buffer, ' ', sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; close(sock); sock = connect_server("127.0.0.1", port, false); send_ascii_command(buffer); /* verify that the server closed the connection */ assert(read(sock, buffer, sizeof(buffer)) == 0); close(sock); sock = connect_server("127.0.0.1", port, false); snprintf(buffer, sizeof(buffer), "gets "); size_t offset = 5; while (offset < 4000) { offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%010u ", (unsigned int)offset); } send_ascii_command(buffer); usleep(250); send_ascii_command("\r\n"); char rsp[80]; read_ascii_response(rsp, sizeof(rsp)); assert(strncmp(rsp, "END", strlen("END")) == 0); buffer[3]= ' '; send_ascii_command(buffer); usleep(250); send_ascii_command("\r\n"); read_ascii_response(rsp, sizeof(rsp)); assert(strncmp(rsp, "END", strlen("END")) == 0); memset(buffer, ' ', sizeof(buffer)); int len = snprintf(buffer + 101, sizeof(buffer) - 101, "gets foo"); buffer[101 + len] = ' '; buffer[sizeof(buffer) - 1] = '\0'; send_ascii_command(buffer); /* verify that the server closed the connection */ assert(read(sock, buffer, sizeof(buffer)) == 0); close(sock); sock = connect_server("127.0.0.1", port, false); return TEST_PASS; } static enum test_return start_memcached_server(void) { server_pid = start_server(&port, false, 600); sock = connect_server("127.0.0.1", port, false); return TEST_PASS; } static enum test_return stop_memcached_server(void) { close(sock); assert(kill(server_pid, SIGTERM) == 0); return TEST_PASS; } static void safe_send(const void* buf, size_t len, bool hickup) { off_t offset = 0; const char* ptr = buf; #ifdef MESSAGE_DEBUG uint8_t val = *ptr; assert(val == (uint8_t)0x80); fprintf(stderr, "About to send %lu bytes:", (unsigned long)len); for (int ii = 0; ii < len; ++ii) { if (ii % 4 == 0) { fprintf(stderr, "\n "); } val = *(ptr + ii); fprintf(stderr, " 0x%02x", val); } fprintf(stderr, "\n"); usleep(500); #endif do { size_t num_bytes = len - offset; if (hickup) { if (num_bytes > 1024) { num_bytes = (rand() % 1023) + 1; } } ssize_t nw = write(sock, ptr + offset, num_bytes); if (nw == -1) { if (errno != EINTR) { fprintf(stderr, "Failed to write: %s\n", strerror(errno)); abort(); } } else { if (hickup) { usleep(100); } offset += nw; } } while (offset < len); } static bool safe_recv(void *buf, size_t len) { if (len == 0) { return true; } off_t offset = 0; do { ssize_t nr = read(sock, ((char*)buf) + offset, len - offset); if (nr == -1) { if (errno != EINTR) { fprintf(stderr, "Failed to read: %s\n", strerror(errno)); abort(); } } else { if (nr == 0 && allow_closed_read) { return false; } assert(nr != 0); offset += nr; } } while (offset < len); return true; } static bool safe_recv_packet(void *buf, size_t size) { protocol_binary_response_no_extras *response = buf; assert(size > sizeof(*response)); if (!safe_recv(response, sizeof(*response))) { return false; } response->message.header.response.keylen = ntohs(response->message.header.response.keylen); response->message.header.response.status = ntohs(response->message.header.response.status); response->message.header.response.bodylen = ntohl(response->message.header.response.bodylen); size_t len = sizeof(*response); char *ptr = buf; ptr += len; if (!safe_recv(ptr, response->message.header.response.bodylen)) { return false; } #ifdef MESSAGE_DEBUG usleep(500); ptr = buf; len += response->message.header.response.bodylen; uint8_t val = *ptr; assert(val == (uint8_t)0x81); fprintf(stderr, "Received %lu bytes:", (unsigned long)len); for (int ii = 0; ii < len; ++ii) { if (ii % 4 == 0) { fprintf(stderr, "\n "); } val = *(ptr + ii); fprintf(stderr, " 0x%02x", val); } fprintf(stderr, "\n"); #endif return true; } static off_t storage_command(char*buf, size_t bufsz, uint8_t cmd, const void* key, size_t keylen, const void* dta, size_t dtalen, uint32_t flags, uint32_t exp) { /* all of the storage commands use the same command layout */ protocol_binary_request_set *request = (void*)buf; assert(bufsz > sizeof(*request) + keylen + dtalen); memset(request, 0, sizeof(*request)); request->message.header.request.magic = PROTOCOL_BINARY_REQ; request->message.header.request.opcode = cmd; request->message.header.request.keylen = htons(keylen); request->message.header.request.extlen = 8; request->message.header.request.bodylen = htonl(keylen + 8 + dtalen); request->message.header.request.opaque = 0xdeadbeef; request->message.body.flags = flags; request->message.body.expiration = exp; off_t key_offset = sizeof(protocol_binary_request_no_extras) + 8; memcpy(buf + key_offset, key, keylen); if (dta != NULL) { memcpy(buf + key_offset + keylen, dta, dtalen); } return key_offset + keylen + dtalen; } static off_t raw_command(char* buf, size_t bufsz, uint8_t cmd, const void* key, size_t keylen, const void* dta, size_t dtalen) { /* all of the storage commands use the same command layout */ protocol_binary_request_no_extras *request = (void*)buf; assert(bufsz > sizeof(*request) + keylen + dtalen); memset(request, 0, sizeof(*request)); request->message.header.request.magic = PROTOCOL_BINARY_REQ; request->message.header.request.opcode = cmd; request->message.header.request.keylen = htons(keylen); request->message.header.request.bodylen = htonl(keylen + dtalen); request->message.header.request.opaque = 0xdeadbeef; off_t key_offset = sizeof(protocol_binary_request_no_extras); if (key != NULL) { memcpy(buf + key_offset, key, keylen); } if (dta != NULL) { memcpy(buf + key_offset + keylen, dta, dtalen); } return sizeof(*request) + keylen + dtalen; } static off_t flush_command(char* buf, size_t bufsz, uint8_t cmd, uint32_t exptime, bool use_extra) { protocol_binary_request_flush *request = (void*)buf; assert(bufsz > sizeof(*request)); memset(request, 0, sizeof(*request)); request->message.header.request.magic = PROTOCOL_BINARY_REQ; request->message.header.request.opcode = cmd; off_t size = sizeof(protocol_binary_request_no_extras); if (use_extra) { request->message.header.request.extlen = 4; request->message.body.expiration = htonl(exptime); request->message.header.request.bodylen = htonl(4); size += 4; } request->message.header.request.opaque = 0xdeadbeef; return size; } static off_t touch_command(char* buf, size_t bufsz, uint8_t cmd, const void* key, size_t keylen, uint32_t exptime) { protocol_binary_request_touch *request = (void*)buf; assert(bufsz > sizeof(*request)); memset(request, 0, sizeof(*request)); request->message.header.request.magic = PROTOCOL_BINARY_REQ; request->message.header.request.opcode = cmd; request->message.header.request.keylen = htons(keylen); request->message.header.request.extlen = 4; request->message.body.expiration = htonl(exptime); request->message.header.request.bodylen = htonl(keylen + 4); request->message.header.request.opaque = 0xdeadbeef; off_t key_offset = sizeof(protocol_binary_request_no_extras) + 4; memcpy(buf + key_offset, key, keylen); return sizeof(protocol_binary_request_no_extras) + 4 + keylen; } static off_t arithmetic_command(char* buf, size_t bufsz, uint8_t cmd, const void* key, size_t keylen, uint64_t delta, uint64_t initial, uint32_t exp) { protocol_binary_request_incr *request = (void*)buf; assert(bufsz > sizeof(*request) + keylen); memset(request, 0, sizeof(*request)); request->message.header.request.magic = PROTOCOL_BINARY_REQ; request->message.header.request.opcode = cmd; request->message.header.request.keylen = htons(keylen); request->message.header.request.extlen = 20; request->message.header.request.bodylen = htonl(keylen + 20); request->message.header.request.opaque = 0xdeadbeef; request->message.body.delta = htonll(delta); request->message.body.initial = htonll(initial); request->message.body.expiration = htonl(exp); off_t key_offset = sizeof(protocol_binary_request_no_extras) + 20; memcpy(buf + key_offset, key, keylen); return key_offset + keylen; } static void validate_response_header(protocol_binary_response_no_extras *response, uint8_t cmd, uint16_t status) { assert(response->message.header.response.magic == PROTOCOL_BINARY_RES); assert(response->message.header.response.opcode == cmd); assert(response->message.header.response.datatype == PROTOCOL_BINARY_RAW_BYTES); assert(response->message.header.response.status == status); assert(response->message.header.response.opaque == 0xdeadbeef); if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) { switch (cmd) { case PROTOCOL_BINARY_CMD_ADDQ: case PROTOCOL_BINARY_CMD_APPENDQ: case PROTOCOL_BINARY_CMD_DECREMENTQ: case PROTOCOL_BINARY_CMD_DELETEQ: case PROTOCOL_BINARY_CMD_FLUSHQ: case PROTOCOL_BINARY_CMD_INCREMENTQ: case PROTOCOL_BINARY_CMD_PREPENDQ: case PROTOCOL_BINARY_CMD_QUITQ: case PROTOCOL_BINARY_CMD_REPLACEQ: case PROTOCOL_BINARY_CMD_SETQ: assert("Quiet command shouldn't return on success" == NULL); default: break; } switch (cmd) { case PROTOCOL_BINARY_CMD_ADD: case PROTOCOL_BINARY_CMD_REPLACE: case PROTOCOL_BINARY_CMD_SET: case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_PREPEND: assert(response->message.header.response.keylen == 0); assert(response->message.header.response.extlen == 0); assert(response->message.header.response.bodylen == 0); assert(response->message.header.response.cas != 0); break; case PROTOCOL_BINARY_CMD_FLUSH: case PROTOCOL_BINARY_CMD_NOOP: case PROTOCOL_BINARY_CMD_QUIT: case PROTOCOL_BINARY_CMD_DELETE: assert(response->message.header.response.keylen == 0); assert(response->message.header.response.extlen == 0); assert(response->message.header.response.bodylen == 0); assert(response->message.header.response.cas == 0); break; case PROTOCOL_BINARY_CMD_DECREMENT: case PROTOCOL_BINARY_CMD_INCREMENT: assert(response->message.header.response.keylen == 0); assert(response->message.header.response.extlen == 0); assert(response->message.header.response.bodylen == 8); assert(response->message.header.response.cas != 0); break; case PROTOCOL_BINARY_CMD_STAT: assert(response->message.header.response.extlen == 0); /* key and value exists in all packets except in the terminating */ assert(response->message.header.response.cas == 0); break; case PROTOCOL_BINARY_CMD_VERSION: assert(response->message.header.response.keylen == 0); assert(response->message.header.response.extlen == 0); assert(response->message.header.response.bodylen != 0); assert(response->message.header.response.cas == 0); break; case PROTOCOL_BINARY_CMD_GET: case PROTOCOL_BINARY_CMD_GETQ: assert(response->message.header.response.keylen == 0); assert(response->message.header.response.extlen == 4); assert(response->message.header.response.cas != 0); break; case PROTOCOL_BINARY_CMD_GETK: case PROTOCOL_BINARY_CMD_GETKQ: assert(response->message.header.response.keylen != 0); assert(response->message.header.response.extlen == 4); assert(response->message.header.response.cas != 0); break; default: /* Undefined command code */ break; } } else { assert(response->message.header.response.cas == 0); assert(response->message.header.response.extlen == 0); if (cmd != PROTOCOL_BINARY_CMD_GETK && cmd != PROTOCOL_BINARY_CMD_GATK) { assert(response->message.header.response.keylen == 0); } } } static enum test_return test_binary_noop(void) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } buffer; size_t len = raw_command(buffer.bytes, sizeof(buffer.bytes), PROTOCOL_BINARY_CMD_NOOP, NULL, 0, NULL, 0); safe_send(buffer.bytes, len, false); safe_recv_packet(buffer.bytes, sizeof(buffer.bytes)); validate_response_header(&buffer.response, PROTOCOL_BINARY_CMD_NOOP, PROTOCOL_BINARY_RESPONSE_SUCCESS); return TEST_PASS; } static enum test_return test_binary_quit_impl(uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } buffer; size_t len = raw_command(buffer.bytes, sizeof(buffer.bytes), cmd, NULL, 0, NULL, 0); safe_send(buffer.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_QUIT) { safe_recv_packet(buffer.bytes, sizeof(buffer.bytes)); validate_response_header(&buffer.response, PROTOCOL_BINARY_CMD_QUIT, PROTOCOL_BINARY_RESPONSE_SUCCESS); } /* Socket should be closed now, read should return 0 */ assert(read(sock, buffer.bytes, sizeof(buffer.bytes)) == 0); close(sock); sock = connect_server("127.0.0.1", port, false); return TEST_PASS; } static enum test_return test_binary_quit(void) { return test_binary_quit_impl(PROTOCOL_BINARY_CMD_QUIT); } static enum test_return test_binary_quitq(void) { return test_binary_quit_impl(PROTOCOL_BINARY_CMD_QUITQ); } static enum test_return test_binary_set_impl(const char *key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; uint64_t value = 0xdeadbeefdeadcafe; size_t len = storage_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), &value, sizeof(value), 0, 0); /* Set should work over and over again */ int ii; for (ii = 0; ii < 10; ++ii) { safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_SET) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } } if (cmd == PROTOCOL_BINARY_CMD_SETQ) { return test_binary_noop(); } send.request.message.header.request.cas = receive.response.message.header.response.cas; safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_SET) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); assert(receive.response.message.header.response.cas != send.request.message.header.request.cas); } else { return test_binary_noop(); } return TEST_PASS; } static enum test_return test_binary_set(void) { return test_binary_set_impl("test_binary_set", PROTOCOL_BINARY_CMD_SET); } static enum test_return test_binary_setq(void) { return test_binary_set_impl("test_binary_setq", PROTOCOL_BINARY_CMD_SETQ); } static enum test_return test_binary_add_impl(const char *key, uint8_t cmd) { uint64_t value = 0xdeadbeefdeadcafe; union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; size_t len = storage_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), &value, sizeof(value), 0, 0); /* Add should only work the first time */ int ii; for (ii = 0; ii < 10; ++ii) { safe_send(send.bytes, len, false); if (ii == 0) { if (cmd == PROTOCOL_BINARY_CMD_ADD) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } } else { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); } } return TEST_PASS; } static enum test_return test_binary_add(void) { return test_binary_add_impl("test_binary_add", PROTOCOL_BINARY_CMD_ADD); } static enum test_return test_binary_addq(void) { return test_binary_add_impl("test_binary_addq", PROTOCOL_BINARY_CMD_ADDQ); } static enum test_return test_binary_replace_impl(const char* key, uint8_t cmd) { uint64_t value = 0xdeadbeefdeadcafe; union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; size_t len = storage_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), &value, sizeof(value), 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), &value, sizeof(value), 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); len = storage_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), &value, sizeof(value), 0, 0); int ii; for (ii = 0; ii < 10; ++ii) { safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_REPLACE) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_REPLACE, PROTOCOL_BINARY_RESPONSE_SUCCESS); } } if (cmd == PROTOCOL_BINARY_CMD_REPLACEQ) { test_binary_noop(); } return TEST_PASS; } static enum test_return test_binary_replace(void) { return test_binary_replace_impl("test_binary_replace", PROTOCOL_BINARY_CMD_REPLACE); } static enum test_return test_binary_replaceq(void) { return test_binary_replace_impl("test_binary_replaceq", PROTOCOL_BINARY_CMD_REPLACEQ); } static enum test_return test_binary_delete_impl(const char *key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; size_t len = raw_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), NULL, 0, 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); len = raw_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_DELETE) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_DELETE, PROTOCOL_BINARY_RESPONSE_SUCCESS); } safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); return TEST_PASS; } static enum test_return test_binary_delete(void) { return test_binary_delete_impl("test_binary_delete", PROTOCOL_BINARY_CMD_DELETE); } static enum test_return test_binary_deleteq(void) { return test_binary_delete_impl("test_binary_deleteq", PROTOCOL_BINARY_CMD_DELETEQ); } static enum test_return test_binary_get_impl(const char *key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; size_t len = raw_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), NULL, 0, 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); /* run a little pipeline test ;-) */ len = 0; int ii; for (ii = 0; ii < 10; ++ii) { union { protocol_binary_request_no_extras request; char bytes[1024]; } temp; size_t l = raw_command(temp.bytes, sizeof(temp.bytes), cmd, key, strlen(key), NULL, 0); memcpy(send.bytes + len, temp.bytes, l); len += l; } safe_send(send.bytes, len, false); for (ii = 0; ii < 10; ++ii) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } return TEST_PASS; } static enum test_return test_binary_get(void) { return test_binary_get_impl("test_binary_get", PROTOCOL_BINARY_CMD_GET); } static enum test_return test_binary_getk(void) { return test_binary_get_impl("test_binary_getk", PROTOCOL_BINARY_CMD_GETK); } static enum test_return test_binary_getq_impl(const char *key, uint8_t cmd) { const char *missing = "test_binary_getq_missing"; union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, temp, receive; size_t len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), NULL, 0, 0, 0); size_t len2 = raw_command(temp.bytes, sizeof(temp.bytes), cmd, missing, strlen(missing), NULL, 0); /* I need to change the first opaque so that I can separate the two * return packets */ temp.request.message.header.request.opaque = 0xfeedface; memcpy(send.bytes + len, temp.bytes, len2); len += len2; len2 = raw_command(temp.bytes, sizeof(temp.bytes), cmd, key, strlen(key), NULL, 0); memcpy(send.bytes + len, temp.bytes, len2); len += len2; safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); /* The first GETQ shouldn't return anything */ safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); return TEST_PASS; } static enum test_return test_binary_getq(void) { return test_binary_getq_impl("test_binary_getq", PROTOCOL_BINARY_CMD_GETQ); } static enum test_return test_binary_getkq(void) { return test_binary_getq_impl("test_binary_getkq", PROTOCOL_BINARY_CMD_GETKQ); } static enum test_return test_binary_incr_impl(const char* key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response_header; protocol_binary_response_incr response; char bytes[1024]; } send, receive; size_t len = arithmetic_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), 1, 0, 0); int ii; for (ii = 0; ii < 10; ++ii) { safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_INCREMENT) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response_header, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); assert(ntohll(receive.response.message.body.value) == ii); } } if (cmd == PROTOCOL_BINARY_CMD_INCREMENTQ) { test_binary_noop(); } return TEST_PASS; } static enum test_return test_binary_incr(void) { return test_binary_incr_impl("test_binary_incr", PROTOCOL_BINARY_CMD_INCREMENT); } static enum test_return test_binary_incrq(void) { return test_binary_incr_impl("test_binary_incrq", PROTOCOL_BINARY_CMD_INCREMENTQ); } static enum test_return test_binary_decr_impl(const char* key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response_header; protocol_binary_response_decr response; char bytes[1024]; } send, receive; size_t len = arithmetic_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), 1, 9, 0); int ii; for (ii = 9; ii >= 0; --ii) { safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_DECREMENT) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response_header, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); assert(ntohll(receive.response.message.body.value) == ii); } } /* decr on 0 should not wrap */ safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_DECREMENT) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response_header, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); assert(ntohll(receive.response.message.body.value) == 0); } else { test_binary_noop(); } return TEST_PASS; } static enum test_return test_binary_decr(void) { return test_binary_decr_impl("test_binary_decr", PROTOCOL_BINARY_CMD_DECREMENT); } static enum test_return test_binary_decrq(void) { return test_binary_decr_impl("test_binary_decrq", PROTOCOL_BINARY_CMD_DECREMENTQ); } static enum test_return test_binary_version(void) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } buffer; size_t len = raw_command(buffer.bytes, sizeof(buffer.bytes), PROTOCOL_BINARY_CMD_VERSION, NULL, 0, NULL, 0); safe_send(buffer.bytes, len, false); safe_recv_packet(buffer.bytes, sizeof(buffer.bytes)); validate_response_header(&buffer.response, PROTOCOL_BINARY_CMD_VERSION, PROTOCOL_BINARY_RESPONSE_SUCCESS); return TEST_PASS; } static enum test_return test_binary_flush_impl(const char *key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; size_t len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), NULL, 0, 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); len = flush_command(send.bytes, sizeof(send.bytes), cmd, 2, true); safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_FLUSH) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } len = raw_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_GET, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_GET, PROTOCOL_BINARY_RESPONSE_SUCCESS); sleep(2); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_GET, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); int ii; for (ii = 0; ii < 2; ++ii) { len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), NULL, 0, 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); len = flush_command(send.bytes, sizeof(send.bytes), cmd, 0, ii == 0); safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_FLUSH) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } len = raw_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_GET, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_GET, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); } return TEST_PASS; } static enum test_return test_binary_flush(void) { return test_binary_flush_impl("test_binary_flush", PROTOCOL_BINARY_CMD_FLUSH); } static enum test_return test_binary_flushq(void) { return test_binary_flush_impl("test_binary_flushq", PROTOCOL_BINARY_CMD_FLUSHQ); } static enum test_return test_binary_concat_impl(const char *key, uint8_t cmd) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } send, receive; const char *value = "world"; size_t len = raw_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), value, strlen(value)); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_NOT_STORED); len = storage_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_ADD, key, strlen(key), value, strlen(value), 0, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_ADD, PROTOCOL_BINARY_RESPONSE_SUCCESS); len = raw_command(send.bytes, sizeof(send.bytes), cmd, key, strlen(key), value, strlen(value)); safe_send(send.bytes, len, false); if (cmd == PROTOCOL_BINARY_CMD_APPEND || cmd == PROTOCOL_BINARY_CMD_PREPEND) { safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, cmd, PROTOCOL_BINARY_RESPONSE_SUCCESS); } else { len = raw_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_NOOP, NULL, 0, NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_NOOP, PROTOCOL_BINARY_RESPONSE_SUCCESS); } len = raw_command(send.bytes, sizeof(send.bytes), PROTOCOL_BINARY_CMD_GETK, key, strlen(key), NULL, 0); safe_send(send.bytes, len, false); safe_recv_packet(receive.bytes, sizeof(receive.bytes)); validate_response_header(&receive.response, PROTOCOL_BINARY_CMD_GETK, PROTOCOL_BINARY_RESPONSE_SUCCESS); assert(receive.response.message.header.response.keylen == strlen(key)); assert(receive.response.message.header.response.bodylen == (strlen(key) + 2*strlen(value) + 4)); char *ptr = receive.bytes; ptr += sizeof(receive.response); ptr += 4; assert(memcmp(ptr, key, strlen(key)) == 0); ptr += strlen(key); assert(memcmp(ptr, value, strlen(value)) == 0); ptr += strlen(value); assert(memcmp(ptr, value, strlen(value)) == 0); return TEST_PASS; } static enum test_return test_binary_append(void) { return test_binary_concat_impl("test_binary_append", PROTOCOL_BINARY_CMD_APPEND); } static enum test_return test_binary_prepend(void) { return test_binary_concat_impl("test_binary_prepend", PROTOCOL_BINARY_CMD_PREPEND); } static enum test_return test_binary_appendq(void) { return test_binary_concat_impl("test_binary_appendq", PROTOCOL_BINARY_CMD_APPENDQ); } static enum test_return test_binary_prependq(void) { return test_binary_concat_impl("test_binary_prependq", PROTOCOL_BINARY_CMD_PREPENDQ); } static enum test_return test_binary_stat(void) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } buffer; size_t len = raw_command(buffer.bytes, sizeof(buffer.bytes), PROTOCOL_BINARY_CMD_STAT, NULL, 0, NULL, 0); safe_send(buffer.bytes, len, false); do { safe_recv_packet(buffer.bytes, sizeof(buffer.bytes)); validate_response_header(&buffer.response, PROTOCOL_BINARY_CMD_STAT, PROTOCOL_BINARY_RESPONSE_SUCCESS); } while (buffer.response.message.header.response.keylen != 0); return TEST_PASS; } static enum test_return test_binary_illegal(void) { uint8_t cmd = 0x25; while (cmd != 0x00) { union { protocol_binary_request_no_extras request; protocol_binary_response_no_extras response; char bytes[1024]; } buffer; size_t len = raw_command(buffer.bytes, sizeof(buffer.bytes), cmd, NULL, 0, NULL, 0); safe_send(buffer.bytes, len, false); safe_recv_packet(buffer.bytes, sizeof(buffer.bytes)); validate_response_header(&buffer.response, cmd, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND); ++cmd; } return TEST_PASS; } volatile bool hickup_thread_running; static void *binary_hickup_recv_verification_thread(void *arg) { protocol_binary_response_no_extras *response = malloc(65*1024); if (response != NULL) { while (safe_recv_packet(response, 65*1024)) { /* Just validate the packet format */ validate_response_header(response, response->message.header.response.opcode, response->message.header.response.status); } free(response); } hickup_thread_running = false; allow_closed_read = false; return NULL; } static enum test_return test_binary_pipeline_hickup_chunk(void *buffer, size_t buffersize) { off_t offset = 0; char *key[256]; uint64_t value = 0xfeedfacedeadbeef; while (hickup_thread_running && offset + sizeof(protocol_binary_request_no_extras) < buffersize) { union { protocol_binary_request_no_extras request; char bytes[65 * 1024]; } command; uint8_t cmd = (uint8_t)(rand() & 0xff); size_t len; size_t keylen = (rand() % 250) + 1; switch (cmd) { case PROTOCOL_BINARY_CMD_ADD: case PROTOCOL_BINARY_CMD_ADDQ: case PROTOCOL_BINARY_CMD_REPLACE: case PROTOCOL_BINARY_CMD_REPLACEQ: case PROTOCOL_BINARY_CMD_SET: case PROTOCOL_BINARY_CMD_SETQ: len = storage_command(command.bytes, sizeof(command.bytes), cmd, key, keylen , &value, sizeof(value), 0, 0); break; case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_APPENDQ: case PROTOCOL_BINARY_CMD_PREPEND: case PROTOCOL_BINARY_CMD_PREPENDQ: len = raw_command(command.bytes, sizeof(command.bytes), cmd, key, keylen, &value, sizeof(value)); break; case PROTOCOL_BINARY_CMD_FLUSH: case PROTOCOL_BINARY_CMD_FLUSHQ: len = raw_command(command.bytes, sizeof(command.bytes), cmd, NULL, 0, NULL, 0); break; case PROTOCOL_BINARY_CMD_NOOP: len = raw_command(command.bytes, sizeof(command.bytes), cmd, NULL, 0, NULL, 0); break; case PROTOCOL_BINARY_CMD_DELETE: case PROTOCOL_BINARY_CMD_DELETEQ: len = raw_command(command.bytes, sizeof(command.bytes), cmd, key, keylen, NULL, 0); break; case PROTOCOL_BINARY_CMD_DECREMENT: case PROTOCOL_BINARY_CMD_DECREMENTQ: case PROTOCOL_BINARY_CMD_INCREMENT: case PROTOCOL_BINARY_CMD_INCREMENTQ: len = arithmetic_command(command.bytes, sizeof(command.bytes), cmd, key, keylen, 1, 0, 0); break; case PROTOCOL_BINARY_CMD_VERSION: len = raw_command(command.bytes, sizeof(command.bytes), PROTOCOL_BINARY_CMD_VERSION, NULL, 0, NULL, 0); break; case PROTOCOL_BINARY_CMD_GET: case PROTOCOL_BINARY_CMD_GETK: case PROTOCOL_BINARY_CMD_GETKQ: case PROTOCOL_BINARY_CMD_GETQ: len = raw_command(command.bytes, sizeof(command.bytes), cmd, key, keylen, NULL, 0); break; case PROTOCOL_BINARY_CMD_TOUCH: case PROTOCOL_BINARY_CMD_GAT: case PROTOCOL_BINARY_CMD_GATQ: case PROTOCOL_BINARY_CMD_GATK: case PROTOCOL_BINARY_CMD_GATKQ: len = touch_command(command.bytes, sizeof(command.bytes), cmd, key, keylen, 10); break; case PROTOCOL_BINARY_CMD_STAT: len = raw_command(command.bytes, sizeof(command.bytes), PROTOCOL_BINARY_CMD_STAT, NULL, 0, NULL, 0); break; case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: case PROTOCOL_BINARY_CMD_SASL_AUTH: case PROTOCOL_BINARY_CMD_SASL_STEP: /* Ignoring SASL */ case PROTOCOL_BINARY_CMD_QUITQ: case PROTOCOL_BINARY_CMD_QUIT: /* I don't want to pass on the quit commands ;-) */ cmd |= 0xf0; /* FALLTHROUGH */ default: len = raw_command(command.bytes, sizeof(command.bytes), cmd, NULL, 0, NULL, 0); } if ((len + offset) < buffersize) { memcpy(((char*)buffer) + offset, command.bytes, len); offset += len; } else { break; } } safe_send(buffer, offset, true); return TEST_PASS; } static enum test_return test_binary_pipeline_hickup(void) { size_t buffersize = 65 * 1024; void *buffer = malloc(buffersize); int ii; pthread_t tid; int ret; allow_closed_read = true; hickup_thread_running = true; if ((ret = pthread_create(&tid, NULL, binary_hickup_recv_verification_thread, NULL)) != 0) { fprintf(stderr, "Can't create thread: %s\n", strerror(ret)); return TEST_FAIL; } /* Allow the thread to start */ usleep(250); srand((int)time(NULL)); for (ii = 0; ii < 2; ++ii) { test_binary_pipeline_hickup_chunk(buffer, buffersize); } /* send quitq to shut down the read thread ;-) */ size_t len = raw_command(buffer, buffersize, PROTOCOL_BINARY_CMD_QUITQ, NULL, 0, NULL, 0); safe_send(buffer, len, false); pthread_join(tid, NULL); free(buffer); return TEST_PASS; } static enum test_return test_issue_101(void) { const int max = 2; enum test_return ret = TEST_PASS; int fds[max]; int ii = 0; pid_t child = 0; if (getenv("SKIP_TEST_101") != NULL) { return TEST_SKIP; } const char *command = "stats\r\nstats\r\nstats\r\nstats\r\nstats\r\n"; size_t cmdlen = strlen(command); server_pid = start_server(&port, false, 1000); for (ii = 0; ii < max; ++ii) { fds[ii] = connect_server("127.0.0.1", port, true); assert(fds[ii] > 0); } /* Send command on the connection until it blocks */ for (ii = 0; ii < max; ++ii) { bool more = true; do { ssize_t err = write(fds[ii], command, cmdlen); if (err == -1) { switch (errno) { case EINTR: break; case ENOMEM: case EWOULDBLOCK: more = false; break; default: ret = TEST_FAIL; goto cleanup; } } } while (more); } child = fork(); if (child == (pid_t)-1) { abort(); } else if (child > 0) { int stat; pid_t c; while ((c = waitpid(child, &stat, 0)) == (pid_t)-1 && errno == EINTR); assert(c == child); assert(stat == 0); } else { sock = connect_server("127.0.0.1", port, false); ret = test_binary_noop(); close(sock); exit(0); } cleanup: /* close all connections */ for (ii = 0; ii < max; ++ii) { close(fds[ii]); } assert(kill(server_pid, SIGTERM) == 0); return ret; } typedef enum test_return (*TEST_FUNC)(void); struct testcase { const char *description; TEST_FUNC function; }; struct testcase testcases[] = { { "cache_create", cache_create_test }, { "cache_constructor", cache_constructor_test }, { "cache_constructor_fail", cache_fail_constructor_test }, { "cache_destructor", cache_destructor_test }, { "cache_reuse", cache_reuse_test }, { "cache_redzone", cache_redzone_test }, { "issue_161", test_issue_161 }, { "strtol", test_safe_strtol }, { "strtoll", test_safe_strtoll }, { "strtoul", test_safe_strtoul }, { "strtoull", test_safe_strtoull }, { "issue_44", test_issue_44 }, { "vperror", test_vperror }, { "issue_101", test_issue_101 }, /* The following tests all run towards the same server */ { "start_server", start_memcached_server }, { "issue_92", test_issue_92 }, { "issue_102", test_issue_102 }, { "binary_noop", test_binary_noop }, { "binary_quit", test_binary_quit }, { "binary_quitq", test_binary_quitq }, { "binary_set", test_binary_set }, { "binary_setq", test_binary_setq }, { "binary_add", test_binary_add }, { "binary_addq", test_binary_addq }, { "binary_replace", test_binary_replace }, { "binary_replaceq", test_binary_replaceq }, { "binary_delete", test_binary_delete }, { "binary_deleteq", test_binary_deleteq }, { "binary_get", test_binary_get }, { "binary_getq", test_binary_getq }, { "binary_getk", test_binary_getk }, { "binary_getkq", test_binary_getkq }, { "binary_incr", test_binary_incr }, { "binary_incrq", test_binary_incrq }, { "binary_decr", test_binary_decr }, { "binary_decrq", test_binary_decrq }, { "binary_version", test_binary_version }, { "binary_flush", test_binary_flush }, { "binary_flushq", test_binary_flushq }, { "binary_append", test_binary_append }, { "binary_appendq", test_binary_appendq }, { "binary_prepend", test_binary_prepend }, { "binary_prependq", test_binary_prependq }, { "binary_stat", test_binary_stat }, { "binary_illegal", test_binary_illegal }, { "binary_pipeline_hickup", test_binary_pipeline_hickup }, { "stop_server", stop_memcached_server }, { NULL, NULL } }; int main(int argc, char **argv) { int exitcode = 0; int ii = 0, num_cases = 0; for (num_cases = 0; testcases[num_cases].description; num_cases++) { /* Just counting */ } printf("1..%d\n", num_cases); for (ii = 0; testcases[ii].description != NULL; ++ii) { fflush(stdout); #ifndef DEBUG /* the test program shouldn't run longer than 10 minutes... */ alarm(600); #endif enum test_return ret = testcases[ii].function(); if (ret == TEST_SKIP) { fprintf(stdout, "ok # SKIP %d - %s\n", ii + 1, testcases[ii].description); } else if (ret == TEST_PASS) { fprintf(stdout, "ok %d - %s\n", ii + 1, testcases[ii].description); } else { fprintf(stdout, "not ok %d - %s\n", ii + 1, testcases[ii].description); exitcode = 1; } fflush(stdout); } return exitcode; } memcached-1.4.14/memcached.c0000644000175000017500000052062012005567007012511 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * memcached - memory caching daemon * * http://www.danga.com/memcached/ * * Copyright 2003 Danga Interactive, Inc. All rights reserved. * * Use and distribution licensed under the BSD license. See * the LICENSE file for full text. * * Authors: * Anatoly Vorobey * Brad Fitzpatrick */ #include "memcached.h" #include #include #include #include #include #include #include #include /* some POSIX systems need the following definition * to get mlockall flags out of sys/mman.h. */ #ifndef _P1003_1B_VISIBLE #define _P1003_1B_VISIBLE #endif /* need this to get IOV_MAX on some platforms. */ #ifndef __need_IOV_MAX #define __need_IOV_MAX #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* FreeBSD 4.x doesn't have IOV_MAX exposed. */ #ifndef IOV_MAX #if defined(__FreeBSD__) || defined(__APPLE__) # define IOV_MAX 1024 #endif #endif /* * forward declarations */ static void drive_machine(conn *c); static int new_socket(struct addrinfo *ai); static int try_read_command(conn *c); enum try_read_result { READ_DATA_RECEIVED, READ_NO_DATA_RECEIVED, READ_ERROR, /** an error occured (on the socket) (or client closed connection) */ READ_MEMORY_ERROR /** failed to allocate more memory */ }; static enum try_read_result try_read_network(conn *c); static enum try_read_result try_read_udp(conn *c); static void conn_set_state(conn *c, enum conn_states state); /* stats */ static void stats_init(void); static void server_stats(ADD_STAT add_stats, conn *c); static void process_stat_settings(ADD_STAT add_stats, void *c); /* defaults */ static void settings_init(void); /* event handling, network IO */ static void event_handler(const int fd, const short which, void *arg); static void conn_close(conn *c); static void conn_init(void); static bool update_event(conn *c, const int new_flags); static void complete_nread(conn *c); static void process_command(conn *c, char *command); static void write_and_free(conn *c, char *buf, int bytes); static int ensure_iov_space(conn *c); static int add_iov(conn *c, const void *buf, int len); static int add_msghdr(conn *c); static void conn_free(conn *c); /** exported globals **/ struct stats stats; struct settings settings; time_t process_started; /* when the process was started */ struct slab_rebalance slab_rebal; volatile int slab_rebalance_signal; /** file scope variables **/ static conn *listen_conn = NULL; static struct event_base *main_base; enum transmit_result { TRANSMIT_COMPLETE, /** All done writing. */ TRANSMIT_INCOMPLETE, /** More data remaining to write. */ TRANSMIT_SOFT_ERROR, /** Can't write any more right now. */ TRANSMIT_HARD_ERROR /** Can't write (c->state is set to conn_closing) */ }; static enum transmit_result transmit(conn *c); /* This reduces the latency without adding lots of extra wiring to be able to * notify the listener thread of when to listen again. * Also, the clock timer could be broken out into its own thread and we * can block the listener via a condition. */ static volatile bool allow_new_conns = true; static struct event maxconnsevent; static void maxconns_handler(const int fd, const short which, void *arg) { struct timeval t = {.tv_sec = 0, .tv_usec = 10000}; if (fd == -42 || allow_new_conns == false) { /* reschedule in 10ms if we need to keep polling */ evtimer_set(&maxconnsevent, maxconns_handler, 0); event_base_set(main_base, &maxconnsevent); evtimer_add(&maxconnsevent, &t); } else { evtimer_del(&maxconnsevent); accept_new_conns(true); } } #define REALTIME_MAXDELTA 60*60*24*30 /* * given time value that's either unix time or delta from current unix time, return * unix time. Use the fact that delta can't exceed one month (and real time value can't * be that low). */ static rel_time_t realtime(const time_t exptime) { /* no. of seconds in 30 days - largest possible delta exptime */ if (exptime == 0) return 0; /* 0 means never expire */ if (exptime > REALTIME_MAXDELTA) { /* if item expiration is at/before the server started, give it an expiration time of 1 second after the server started. (because 0 means don't expire). without this, we'd underflow and wrap around to some large value way in the future, effectively making items expiring in the past really expiring never */ if (exptime <= process_started) return (rel_time_t)1; return (rel_time_t)(exptime - process_started); } else { return (rel_time_t)(exptime + current_time); } } static void stats_init(void) { stats.curr_items = stats.total_items = stats.curr_conns = stats.total_conns = stats.conn_structs = 0; stats.get_cmds = stats.set_cmds = stats.get_hits = stats.get_misses = stats.evictions = stats.reclaimed = 0; stats.touch_cmds = stats.touch_misses = stats.touch_hits = stats.rejected_conns = 0; stats.curr_bytes = stats.listen_disabled_num = 0; stats.hash_power_level = stats.hash_bytes = stats.hash_is_expanding = 0; stats.expired_unfetched = stats.evicted_unfetched = 0; stats.slabs_moved = 0; stats.accepting_conns = true; /* assuming we start in this state. */ stats.slab_reassign_running = false; /* make the time we started always be 2 seconds before we really did, so time(0) - time.started is never zero. if so, things like 'settings.oldest_live' which act as booleans as well as values are now false in boolean context... */ process_started = time(0) - 2; stats_prefix_init(); } static void stats_reset(void) { STATS_LOCK(); stats.total_items = stats.total_conns = 0; stats.rejected_conns = 0; stats.evictions = 0; stats.reclaimed = 0; stats.listen_disabled_num = 0; stats_prefix_clear(); STATS_UNLOCK(); threadlocal_stats_reset(); item_stats_reset(); } static void settings_init(void) { settings.use_cas = true; settings.access = 0700; settings.port = 11211; settings.udpport = 11211; /* By default this string should be NULL for getaddrinfo() */ settings.inter = NULL; settings.maxbytes = 64 * 1024 * 1024; /* default is 64MB */ settings.maxconns = 1024; /* to limit connections-related memory to about 5MB */ settings.verbose = 0; settings.oldest_live = 0; settings.evict_to_free = 1; /* push old items out of cache when memory runs out */ settings.socketpath = NULL; /* by default, not using a unix socket */ settings.factor = 1.25; settings.chunk_size = 48; /* space for a modest key and value */ settings.num_threads = 4; /* N workers */ settings.num_threads_per_udp = 0; settings.prefix_delimiter = ':'; settings.detail_enabled = 0; settings.reqs_per_event = 20; settings.backlog = 1024; settings.binding_protocol = negotiating_prot; settings.item_size_max = 1024 * 1024; /* The famous 1MB upper limit. */ settings.maxconns_fast = false; settings.hashpower_init = 0; settings.slab_reassign = false; settings.slab_automove = 0; } /* * Adds a message header to a connection. * * Returns 0 on success, -1 on out-of-memory. */ static int add_msghdr(conn *c) { struct msghdr *msg; assert(c != NULL); if (c->msgsize == c->msgused) { msg = realloc(c->msglist, c->msgsize * 2 * sizeof(struct msghdr)); if (! msg) return -1; c->msglist = msg; c->msgsize *= 2; } msg = c->msglist + c->msgused; /* this wipes msg_iovlen, msg_control, msg_controllen, and msg_flags, the last 3 of which aren't defined on solaris: */ memset(msg, 0, sizeof(struct msghdr)); msg->msg_iov = &c->iov[c->iovused]; if (c->request_addr_size > 0) { msg->msg_name = &c->request_addr; msg->msg_namelen = c->request_addr_size; } c->msgbytes = 0; c->msgused++; if (IS_UDP(c->transport)) { /* Leave room for the UDP header, which we'll fill in later. */ return add_iov(c, NULL, UDP_HEADER_SIZE); } return 0; } /* * Free list management for connections. */ static conn **freeconns; static int freetotal; static int freecurr; /* Lock for connection freelist */ static pthread_mutex_t conn_lock = PTHREAD_MUTEX_INITIALIZER; static void conn_init(void) { freetotal = 200; freecurr = 0; if ((freeconns = calloc(freetotal, sizeof(conn *))) == NULL) { fprintf(stderr, "Failed to allocate connection structures\n"); } return; } /* * Returns a connection from the freelist, if any. */ conn *conn_from_freelist() { conn *c; pthread_mutex_lock(&conn_lock); if (freecurr > 0) { c = freeconns[--freecurr]; } else { c = NULL; } pthread_mutex_unlock(&conn_lock); return c; } /* * Adds a connection to the freelist. 0 = success. */ bool conn_add_to_freelist(conn *c) { bool ret = true; pthread_mutex_lock(&conn_lock); if (freecurr < freetotal) { freeconns[freecurr++] = c; ret = false; } else { /* try to enlarge free connections array */ size_t newsize = freetotal * 2; conn **new_freeconns = realloc(freeconns, sizeof(conn *) * newsize); if (new_freeconns) { freetotal = newsize; freeconns = new_freeconns; freeconns[freecurr++] = c; ret = false; } } pthread_mutex_unlock(&conn_lock); return ret; } static const char *prot_text(enum protocol prot) { char *rv = "unknown"; switch(prot) { case ascii_prot: rv = "ascii"; break; case binary_prot: rv = "binary"; break; case negotiating_prot: rv = "auto-negotiate"; break; } return rv; } conn *conn_new(const int sfd, enum conn_states init_state, const int event_flags, const int read_buffer_size, enum network_transport transport, struct event_base *base) { conn *c = conn_from_freelist(); if (NULL == c) { if (!(c = (conn *)calloc(1, sizeof(conn)))) { fprintf(stderr, "calloc()\n"); return NULL; } MEMCACHED_CONN_CREATE(c); c->rbuf = c->wbuf = 0; c->ilist = 0; c->suffixlist = 0; c->iov = 0; c->msglist = 0; c->hdrbuf = 0; c->rsize = read_buffer_size; c->wsize = DATA_BUFFER_SIZE; c->isize = ITEM_LIST_INITIAL; c->suffixsize = SUFFIX_LIST_INITIAL; c->iovsize = IOV_LIST_INITIAL; c->msgsize = MSG_LIST_INITIAL; c->hdrsize = 0; c->rbuf = (char *)malloc((size_t)c->rsize); c->wbuf = (char *)malloc((size_t)c->wsize); c->ilist = (item **)malloc(sizeof(item *) * c->isize); c->suffixlist = (char **)malloc(sizeof(char *) * c->suffixsize); c->iov = (struct iovec *)malloc(sizeof(struct iovec) * c->iovsize); c->msglist = (struct msghdr *)malloc(sizeof(struct msghdr) * c->msgsize); if (c->rbuf == 0 || c->wbuf == 0 || c->ilist == 0 || c->iov == 0 || c->msglist == 0 || c->suffixlist == 0) { conn_free(c); fprintf(stderr, "malloc()\n"); return NULL; } STATS_LOCK(); stats.conn_structs++; STATS_UNLOCK(); } c->transport = transport; c->protocol = settings.binding_protocol; /* unix socket mode doesn't need this, so zeroed out. but why * is this done for every command? presumably for UDP * mode. */ if (!settings.socketpath) { c->request_addr_size = sizeof(c->request_addr); } else { c->request_addr_size = 0; } if (settings.verbose > 1) { if (init_state == conn_listening) { fprintf(stderr, "<%d server listening (%s)\n", sfd, prot_text(c->protocol)); } else if (IS_UDP(transport)) { fprintf(stderr, "<%d server listening (udp)\n", sfd); } else if (c->protocol == negotiating_prot) { fprintf(stderr, "<%d new auto-negotiating client connection\n", sfd); } else if (c->protocol == ascii_prot) { fprintf(stderr, "<%d new ascii client connection.\n", sfd); } else if (c->protocol == binary_prot) { fprintf(stderr, "<%d new binary client connection.\n", sfd); } else { fprintf(stderr, "<%d new unknown (%d) client connection\n", sfd, c->protocol); assert(false); } } c->sfd = sfd; c->state = init_state; c->rlbytes = 0; c->cmd = -1; c->rbytes = c->wbytes = 0; c->wcurr = c->wbuf; c->rcurr = c->rbuf; c->ritem = 0; c->icurr = c->ilist; c->suffixcurr = c->suffixlist; c->ileft = 0; c->suffixleft = 0; c->iovused = 0; c->msgcurr = 0; c->msgused = 0; c->write_and_go = init_state; c->write_and_free = 0; c->item = 0; c->noreply = false; event_set(&c->event, sfd, event_flags, event_handler, (void *)c); event_base_set(base, &c->event); c->ev_flags = event_flags; if (event_add(&c->event, 0) == -1) { if (conn_add_to_freelist(c)) { conn_free(c); } perror("event_add"); return NULL; } STATS_LOCK(); stats.curr_conns++; stats.total_conns++; STATS_UNLOCK(); MEMCACHED_CONN_ALLOCATE(c->sfd); return c; } static void conn_cleanup(conn *c) { assert(c != NULL); if (c->item) { item_remove(c->item); c->item = 0; } if (c->ileft != 0) { for (; c->ileft > 0; c->ileft--,c->icurr++) { item_remove(*(c->icurr)); } } if (c->suffixleft != 0) { for (; c->suffixleft > 0; c->suffixleft--, c->suffixcurr++) { cache_free(c->thread->suffix_cache, *(c->suffixcurr)); } } if (c->write_and_free) { free(c->write_and_free); c->write_and_free = 0; } if (c->sasl_conn) { assert(settings.sasl); sasl_dispose(&c->sasl_conn); c->sasl_conn = NULL; } if (IS_UDP(c->transport)) { conn_set_state(c, conn_read); } } /* * Frees a connection. */ void conn_free(conn *c) { if (c) { MEMCACHED_CONN_DESTROY(c); if (c->hdrbuf) free(c->hdrbuf); if (c->msglist) free(c->msglist); if (c->rbuf) free(c->rbuf); if (c->wbuf) free(c->wbuf); if (c->ilist) free(c->ilist); if (c->suffixlist) free(c->suffixlist); if (c->iov) free(c->iov); free(c); } } static void conn_close(conn *c) { assert(c != NULL); /* delete the event, the socket and the conn */ event_del(&c->event); if (settings.verbose > 1) fprintf(stderr, "<%d connection closed.\n", c->sfd); MEMCACHED_CONN_RELEASE(c->sfd); close(c->sfd); pthread_mutex_lock(&conn_lock); allow_new_conns = true; pthread_mutex_unlock(&conn_lock); conn_cleanup(c); /* if the connection has big buffers, just free it */ if (c->rsize > READ_BUFFER_HIGHWAT || conn_add_to_freelist(c)) { conn_free(c); } STATS_LOCK(); stats.curr_conns--; STATS_UNLOCK(); return; } /* * Shrinks a connection's buffers if they're too big. This prevents * periodic large "get" requests from permanently chewing lots of server * memory. * * This should only be called in between requests since it can wipe output * buffers! */ static void conn_shrink(conn *c) { assert(c != NULL); if (IS_UDP(c->transport)) return; if (c->rsize > READ_BUFFER_HIGHWAT && c->rbytes < DATA_BUFFER_SIZE) { char *newbuf; if (c->rcurr != c->rbuf) memmove(c->rbuf, c->rcurr, (size_t)c->rbytes); newbuf = (char *)realloc((void *)c->rbuf, DATA_BUFFER_SIZE); if (newbuf) { c->rbuf = newbuf; c->rsize = DATA_BUFFER_SIZE; } /* TODO check other branch... */ c->rcurr = c->rbuf; } if (c->isize > ITEM_LIST_HIGHWAT) { item **newbuf = (item**) realloc((void *)c->ilist, ITEM_LIST_INITIAL * sizeof(c->ilist[0])); if (newbuf) { c->ilist = newbuf; c->isize = ITEM_LIST_INITIAL; } /* TODO check error condition? */ } if (c->msgsize > MSG_LIST_HIGHWAT) { struct msghdr *newbuf = (struct msghdr *) realloc((void *)c->msglist, MSG_LIST_INITIAL * sizeof(c->msglist[0])); if (newbuf) { c->msglist = newbuf; c->msgsize = MSG_LIST_INITIAL; } /* TODO check error condition? */ } if (c->iovsize > IOV_LIST_HIGHWAT) { struct iovec *newbuf = (struct iovec *) realloc((void *)c->iov, IOV_LIST_INITIAL * sizeof(c->iov[0])); if (newbuf) { c->iov = newbuf; c->iovsize = IOV_LIST_INITIAL; } /* TODO check return value */ } } /** * Convert a state name to a human readable form. */ static const char *state_text(enum conn_states state) { const char* const statenames[] = { "conn_listening", "conn_new_cmd", "conn_waiting", "conn_read", "conn_parse_cmd", "conn_write", "conn_nread", "conn_swallow", "conn_closing", "conn_mwrite" }; return statenames[state]; } /* * Sets a connection's current state in the state machine. Any special * processing that needs to happen on certain state transitions can * happen here. */ static void conn_set_state(conn *c, enum conn_states state) { assert(c != NULL); assert(state >= conn_listening && state < conn_max_state); if (state != c->state) { if (settings.verbose > 2) { fprintf(stderr, "%d: going from %s to %s\n", c->sfd, state_text(c->state), state_text(state)); } if (state == conn_write || state == conn_mwrite) { MEMCACHED_PROCESS_COMMAND_END(c->sfd, c->wbuf, c->wbytes); } c->state = state; } } /* * Ensures that there is room for another struct iovec in a connection's * iov list. * * Returns 0 on success, -1 on out-of-memory. */ static int ensure_iov_space(conn *c) { assert(c != NULL); if (c->iovused >= c->iovsize) { int i, iovnum; struct iovec *new_iov = (struct iovec *)realloc(c->iov, (c->iovsize * 2) * sizeof(struct iovec)); if (! new_iov) return -1; c->iov = new_iov; c->iovsize *= 2; /* Point all the msghdr structures at the new list. */ for (i = 0, iovnum = 0; i < c->msgused; i++) { c->msglist[i].msg_iov = &c->iov[iovnum]; iovnum += c->msglist[i].msg_iovlen; } } return 0; } /* * Adds data to the list of pending data that will be written out to a * connection. * * Returns 0 on success, -1 on out-of-memory. */ static int add_iov(conn *c, const void *buf, int len) { struct msghdr *m; int leftover; bool limit_to_mtu; assert(c != NULL); do { m = &c->msglist[c->msgused - 1]; /* * Limit UDP packets, and the first payloads of TCP replies, to * UDP_MAX_PAYLOAD_SIZE bytes. */ limit_to_mtu = IS_UDP(c->transport) || (1 == c->msgused); /* We may need to start a new msghdr if this one is full. */ if (m->msg_iovlen == IOV_MAX || (limit_to_mtu && c->msgbytes >= UDP_MAX_PAYLOAD_SIZE)) { add_msghdr(c); m = &c->msglist[c->msgused - 1]; } if (ensure_iov_space(c) != 0) return -1; /* If the fragment is too big to fit in the datagram, split it up */ if (limit_to_mtu && len + c->msgbytes > UDP_MAX_PAYLOAD_SIZE) { leftover = len + c->msgbytes - UDP_MAX_PAYLOAD_SIZE; len -= leftover; } else { leftover = 0; } m = &c->msglist[c->msgused - 1]; m->msg_iov[m->msg_iovlen].iov_base = (void *)buf; m->msg_iov[m->msg_iovlen].iov_len = len; c->msgbytes += len; c->iovused++; m->msg_iovlen++; buf = ((char *)buf) + len; len = leftover; } while (leftover > 0); return 0; } /* * Constructs a set of UDP headers and attaches them to the outgoing messages. */ static int build_udp_headers(conn *c) { int i; unsigned char *hdr; assert(c != NULL); if (c->msgused > c->hdrsize) { void *new_hdrbuf; if (c->hdrbuf) new_hdrbuf = realloc(c->hdrbuf, c->msgused * 2 * UDP_HEADER_SIZE); else new_hdrbuf = malloc(c->msgused * 2 * UDP_HEADER_SIZE); if (! new_hdrbuf) return -1; c->hdrbuf = (unsigned char *)new_hdrbuf; c->hdrsize = c->msgused * 2; } hdr = c->hdrbuf; for (i = 0; i < c->msgused; i++) { c->msglist[i].msg_iov[0].iov_base = (void*)hdr; c->msglist[i].msg_iov[0].iov_len = UDP_HEADER_SIZE; *hdr++ = c->request_id / 256; *hdr++ = c->request_id % 256; *hdr++ = i / 256; *hdr++ = i % 256; *hdr++ = c->msgused / 256; *hdr++ = c->msgused % 256; *hdr++ = 0; *hdr++ = 0; assert((void *) hdr == (caddr_t)c->msglist[i].msg_iov[0].iov_base + UDP_HEADER_SIZE); } return 0; } static void out_string(conn *c, const char *str) { size_t len; assert(c != NULL); if (c->noreply) { if (settings.verbose > 1) fprintf(stderr, ">%d NOREPLY %s\n", c->sfd, str); c->noreply = false; conn_set_state(c, conn_new_cmd); return; } if (settings.verbose > 1) fprintf(stderr, ">%d %s\n", c->sfd, str); /* Nuke a partial output... */ c->msgcurr = 0; c->msgused = 0; c->iovused = 0; add_msghdr(c); len = strlen(str); if ((len + 2) > c->wsize) { /* ought to be always enough. just fail for simplicity */ str = "SERVER_ERROR output line too long"; len = strlen(str); } memcpy(c->wbuf, str, len); memcpy(c->wbuf + len, "\r\n", 2); c->wbytes = len + 2; c->wcurr = c->wbuf; conn_set_state(c, conn_write); c->write_and_go = conn_new_cmd; return; } /* * we get here after reading the value in set/add/replace commands. The command * has been stored in c->cmd, and the item is ready in c->item. */ static void complete_nread_ascii(conn *c) { assert(c != NULL); item *it = c->item; int comm = c->cmd; enum store_item_type ret; pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].set_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0) { out_string(c, "CLIENT_ERROR bad data chunk"); } else { ret = store_item(it, comm, c); #ifdef ENABLE_DTRACE uint64_t cas = ITEM_get_cas(it); switch (c->cmd) { case NREAD_ADD: MEMCACHED_COMMAND_ADD(c->sfd, ITEM_key(it), it->nkey, (ret == 1) ? it->nbytes : -1, cas); break; case NREAD_REPLACE: MEMCACHED_COMMAND_REPLACE(c->sfd, ITEM_key(it), it->nkey, (ret == 1) ? it->nbytes : -1, cas); break; case NREAD_APPEND: MEMCACHED_COMMAND_APPEND(c->sfd, ITEM_key(it), it->nkey, (ret == 1) ? it->nbytes : -1, cas); break; case NREAD_PREPEND: MEMCACHED_COMMAND_PREPEND(c->sfd, ITEM_key(it), it->nkey, (ret == 1) ? it->nbytes : -1, cas); break; case NREAD_SET: MEMCACHED_COMMAND_SET(c->sfd, ITEM_key(it), it->nkey, (ret == 1) ? it->nbytes : -1, cas); break; case NREAD_CAS: MEMCACHED_COMMAND_CAS(c->sfd, ITEM_key(it), it->nkey, it->nbytes, cas); break; } #endif switch (ret) { case STORED: out_string(c, "STORED"); break; case EXISTS: out_string(c, "EXISTS"); break; case NOT_FOUND: out_string(c, "NOT_FOUND"); break; case NOT_STORED: out_string(c, "NOT_STORED"); break; default: out_string(c, "SERVER_ERROR Unhandled storage type."); } } item_remove(c->item); /* release the c->item reference */ c->item = 0; } /** * get a pointer to the start of the request struct for the current command */ static void* binary_get_request(conn *c) { char *ret = c->rcurr; ret -= (sizeof(c->binary_header) + c->binary_header.request.keylen + c->binary_header.request.extlen); assert(ret >= c->rbuf); return ret; } /** * get a pointer to the key in this request */ static char* binary_get_key(conn *c) { return c->rcurr - (c->binary_header.request.keylen); } static void add_bin_header(conn *c, uint16_t err, uint8_t hdr_len, uint16_t key_len, uint32_t body_len) { protocol_binary_response_header* header; assert(c); c->msgcurr = 0; c->msgused = 0; c->iovused = 0; if (add_msghdr(c) != 0) { /* XXX: out_string is inappropriate here */ out_string(c, "SERVER_ERROR out of memory"); return; } header = (protocol_binary_response_header *)c->wbuf; header->response.magic = (uint8_t)PROTOCOL_BINARY_RES; header->response.opcode = c->binary_header.request.opcode; header->response.keylen = (uint16_t)htons(key_len); header->response.extlen = (uint8_t)hdr_len; header->response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES; header->response.status = (uint16_t)htons(err); header->response.bodylen = htonl(body_len); header->response.opaque = c->opaque; header->response.cas = htonll(c->cas); if (settings.verbose > 1) { int ii; fprintf(stderr, ">%d Writing bin response:", c->sfd); for (ii = 0; ii < sizeof(header->bytes); ++ii) { if (ii % 4 == 0) { fprintf(stderr, "\n>%d ", c->sfd); } fprintf(stderr, " 0x%02x", header->bytes[ii]); } fprintf(stderr, "\n"); } add_iov(c, c->wbuf, sizeof(header->response)); } static void write_bin_error(conn *c, protocol_binary_response_status err, int swallow) { const char *errstr = "Unknown error"; size_t len; switch (err) { case PROTOCOL_BINARY_RESPONSE_ENOMEM: errstr = "Out of memory"; break; case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND: errstr = "Unknown command"; break; case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT: errstr = "Not found"; break; case PROTOCOL_BINARY_RESPONSE_EINVAL: errstr = "Invalid arguments"; break; case PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS: errstr = "Data exists for key."; break; case PROTOCOL_BINARY_RESPONSE_E2BIG: errstr = "Too large."; break; case PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL: errstr = "Non-numeric server-side value for incr or decr"; break; case PROTOCOL_BINARY_RESPONSE_NOT_STORED: errstr = "Not stored."; break; case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR: errstr = "Auth failure."; break; default: assert(false); errstr = "UNHANDLED ERROR"; fprintf(stderr, ">%d UNHANDLED ERROR: %d\n", c->sfd, err); } if (settings.verbose > 1) { fprintf(stderr, ">%d Writing an error: %s\n", c->sfd, errstr); } len = strlen(errstr); add_bin_header(c, err, 0, 0, len); if (len > 0) { add_iov(c, errstr, len); } conn_set_state(c, conn_mwrite); if(swallow > 0) { c->sbytes = swallow; c->write_and_go = conn_swallow; } else { c->write_and_go = conn_new_cmd; } } /* Form and send a response to a command over the binary protocol */ static void write_bin_response(conn *c, void *d, int hlen, int keylen, int dlen) { if (!c->noreply || c->cmd == PROTOCOL_BINARY_CMD_GET || c->cmd == PROTOCOL_BINARY_CMD_GETK) { add_bin_header(c, 0, hlen, keylen, dlen); if(dlen > 0) { add_iov(c, d, dlen); } conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; } else { conn_set_state(c, conn_new_cmd); } } static void complete_incr_bin(conn *c) { item *it; char *key; size_t nkey; /* Weird magic in add_delta forces me to pad here */ char tmpbuf[INCR_MAX_STORAGE_LEN]; uint64_t cas = 0; protocol_binary_response_incr* rsp = (protocol_binary_response_incr*)c->wbuf; protocol_binary_request_incr* req = binary_get_request(c); assert(c != NULL); assert(c->wsize >= sizeof(*rsp)); /* fix byteorder in the request */ req->message.body.delta = ntohll(req->message.body.delta); req->message.body.initial = ntohll(req->message.body.initial); req->message.body.expiration = ntohl(req->message.body.expiration); key = binary_get_key(c); nkey = c->binary_header.request.keylen; if (settings.verbose > 1) { int i; fprintf(stderr, "incr "); for (i = 0; i < nkey; i++) { fprintf(stderr, "%c", key[i]); } fprintf(stderr, " %lld, %llu, %d\n", (long long)req->message.body.delta, (long long)req->message.body.initial, req->message.body.expiration); } if (c->binary_header.request.cas != 0) { cas = c->binary_header.request.cas; } switch(add_delta(c, key, nkey, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT, req->message.body.delta, tmpbuf, &cas)) { case OK: rsp->message.body.value = htonll(strtoull(tmpbuf, NULL, 10)); if (cas) { c->cas = cas; } write_bin_response(c, &rsp->message.body, 0, 0, sizeof(rsp->message.body.value)); break; case NON_NUMERIC: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL, 0); break; case EOM: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); break; case DELTA_ITEM_NOT_FOUND: if (req->message.body.expiration != 0xffffffff) { /* Save some room for the response */ rsp->message.body.value = htonll(req->message.body.initial); it = item_alloc(key, nkey, 0, realtime(req->message.body.expiration), INCR_MAX_STORAGE_LEN); if (it != NULL) { snprintf(ITEM_data(it), INCR_MAX_STORAGE_LEN, "%llu", (unsigned long long)req->message.body.initial); if (store_item(it, NREAD_ADD, c)) { c->cas = ITEM_get_cas(it); write_bin_response(c, &rsp->message.body, 0, 0, sizeof(rsp->message.body.value)); } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_NOT_STORED, 0); } item_remove(it); /* release our reference */ } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); } } else { pthread_mutex_lock(&c->thread->stats.mutex); if (c->cmd == PROTOCOL_BINARY_CMD_INCREMENT) { c->thread->stats.incr_misses++; } else { c->thread->stats.decr_misses++; } pthread_mutex_unlock(&c->thread->stats.mutex); write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); } break; case DELTA_ITEM_CAS_MISMATCH: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0); break; } } static void complete_update_bin(conn *c) { protocol_binary_response_status eno = PROTOCOL_BINARY_RESPONSE_EINVAL; enum store_item_type ret = NOT_STORED; assert(c != NULL); item *it = c->item; pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].set_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); /* We don't actually receive the trailing two characters in the bin * protocol, so we're going to just set them here */ *(ITEM_data(it) + it->nbytes - 2) = '\r'; *(ITEM_data(it) + it->nbytes - 1) = '\n'; ret = store_item(it, c->cmd, c); #ifdef ENABLE_DTRACE uint64_t cas = ITEM_get_cas(it); switch (c->cmd) { case NREAD_ADD: MEMCACHED_COMMAND_ADD(c->sfd, ITEM_key(it), it->nkey, (ret == STORED) ? it->nbytes : -1, cas); break; case NREAD_REPLACE: MEMCACHED_COMMAND_REPLACE(c->sfd, ITEM_key(it), it->nkey, (ret == STORED) ? it->nbytes : -1, cas); break; case NREAD_APPEND: MEMCACHED_COMMAND_APPEND(c->sfd, ITEM_key(it), it->nkey, (ret == STORED) ? it->nbytes : -1, cas); break; case NREAD_PREPEND: MEMCACHED_COMMAND_PREPEND(c->sfd, ITEM_key(it), it->nkey, (ret == STORED) ? it->nbytes : -1, cas); break; case NREAD_SET: MEMCACHED_COMMAND_SET(c->sfd, ITEM_key(it), it->nkey, (ret == STORED) ? it->nbytes : -1, cas); break; } #endif switch (ret) { case STORED: /* Stored */ write_bin_response(c, NULL, 0, 0, 0); break; case EXISTS: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0); break; case NOT_FOUND: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); break; case NOT_STORED: if (c->cmd == NREAD_ADD) { eno = PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; } else if(c->cmd == NREAD_REPLACE) { eno = PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; } else { eno = PROTOCOL_BINARY_RESPONSE_NOT_STORED; } write_bin_error(c, eno, 0); } item_remove(c->item); /* release the c->item reference */ c->item = 0; } static void process_bin_touch(conn *c) { item *it; protocol_binary_response_get* rsp = (protocol_binary_response_get*)c->wbuf; char* key = binary_get_key(c); size_t nkey = c->binary_header.request.keylen; protocol_binary_request_touch *t = binary_get_request(c); time_t exptime = ntohl(t->message.body.expiration); if (settings.verbose > 1) { int ii; /* May be GAT/GATQ/etc */ fprintf(stderr, "<%d TOUCH ", c->sfd); for (ii = 0; ii < nkey; ++ii) { fprintf(stderr, "%c", key[ii]); } fprintf(stderr, "\n"); } it = item_touch(key, nkey, realtime(exptime)); if (it) { /* the length has two unnecessary bytes ("\r\n") */ uint16_t keylen = 0; uint32_t bodylen = sizeof(rsp->message.body) + (it->nbytes - 2); item_update(it); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.touch_cmds++; c->thread->stats.slab_stats[it->slabs_clsid].touch_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_TOUCH(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); if (c->cmd == PROTOCOL_BINARY_CMD_TOUCH) { bodylen -= it->nbytes - 2; } else if (c->cmd == PROTOCOL_BINARY_CMD_GATK) { bodylen += nkey; keylen = nkey; } add_bin_header(c, 0, sizeof(rsp->message.body), keylen, bodylen); rsp->message.header.response.cas = htonll(ITEM_get_cas(it)); // add the flags rsp->message.body.flags = htonl(strtoul(ITEM_suffix(it), NULL, 10)); add_iov(c, &rsp->message.body, sizeof(rsp->message.body)); if (c->cmd == PROTOCOL_BINARY_CMD_GATK) { add_iov(c, ITEM_key(it), nkey); } /* Add the data minus the CRLF */ if (c->cmd != PROTOCOL_BINARY_CMD_TOUCH) { add_iov(c, ITEM_data(it), it->nbytes - 2); } conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; /* Remember this command so we can garbage collect it later */ c->item = it; } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.touch_cmds++; c->thread->stats.touch_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_TOUCH(c->sfd, key, nkey, -1, 0); if (c->noreply) { conn_set_state(c, conn_new_cmd); } else { if (c->cmd == PROTOCOL_BINARY_CMD_GATK) { char *ofs = c->wbuf + sizeof(protocol_binary_response_header); add_bin_header(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0, nkey, nkey); memcpy(ofs, key, nkey); add_iov(c, ofs, nkey); conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); } } } if (settings.detail_enabled) { stats_prefix_record_get(key, nkey, NULL != it); } } static void process_bin_get(conn *c) { item *it; protocol_binary_response_get* rsp = (protocol_binary_response_get*)c->wbuf; char* key = binary_get_key(c); size_t nkey = c->binary_header.request.keylen; if (settings.verbose > 1) { int ii; fprintf(stderr, "<%d GET ", c->sfd); for (ii = 0; ii < nkey; ++ii) { fprintf(stderr, "%c", key[ii]); } fprintf(stderr, "\n"); } it = item_get(key, nkey); if (it) { /* the length has two unnecessary bytes ("\r\n") */ uint16_t keylen = 0; uint32_t bodylen = sizeof(rsp->message.body) + (it->nbytes - 2); item_update(it); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.get_cmds++; c->thread->stats.slab_stats[it->slabs_clsid].get_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); if (c->cmd == PROTOCOL_BINARY_CMD_GETK) { bodylen += nkey; keylen = nkey; } add_bin_header(c, 0, sizeof(rsp->message.body), keylen, bodylen); rsp->message.header.response.cas = htonll(ITEM_get_cas(it)); // add the flags rsp->message.body.flags = htonl(strtoul(ITEM_suffix(it), NULL, 10)); add_iov(c, &rsp->message.body, sizeof(rsp->message.body)); if (c->cmd == PROTOCOL_BINARY_CMD_GETK) { add_iov(c, ITEM_key(it), nkey); } /* Add the data minus the CRLF */ add_iov(c, ITEM_data(it), it->nbytes - 2); conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; /* Remember this command so we can garbage collect it later */ c->item = it; } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.get_cmds++; c->thread->stats.get_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_GET(c->sfd, key, nkey, -1, 0); if (c->noreply) { conn_set_state(c, conn_new_cmd); } else { if (c->cmd == PROTOCOL_BINARY_CMD_GETK) { char *ofs = c->wbuf + sizeof(protocol_binary_response_header); add_bin_header(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0, nkey, nkey); memcpy(ofs, key, nkey); add_iov(c, ofs, nkey); conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); } } } if (settings.detail_enabled) { stats_prefix_record_get(key, nkey, NULL != it); } } static void append_bin_stats(const char *key, const uint16_t klen, const char *val, const uint32_t vlen, conn *c) { char *buf = c->stats.buffer + c->stats.offset; uint32_t bodylen = klen + vlen; protocol_binary_response_header header = { .response.magic = (uint8_t)PROTOCOL_BINARY_RES, .response.opcode = PROTOCOL_BINARY_CMD_STAT, .response.keylen = (uint16_t)htons(klen), .response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES, .response.bodylen = htonl(bodylen), .response.opaque = c->opaque }; memcpy(buf, header.bytes, sizeof(header.response)); buf += sizeof(header.response); if (klen > 0) { memcpy(buf, key, klen); buf += klen; if (vlen > 0) { memcpy(buf, val, vlen); } } c->stats.offset += sizeof(header.response) + bodylen; } static void append_ascii_stats(const char *key, const uint16_t klen, const char *val, const uint32_t vlen, conn *c) { char *pos = c->stats.buffer + c->stats.offset; uint32_t nbytes = 0; int remaining = c->stats.size - c->stats.offset; int room = remaining - 1; if (klen == 0 && vlen == 0) { nbytes = snprintf(pos, room, "END\r\n"); } else if (vlen == 0) { nbytes = snprintf(pos, room, "STAT %s\r\n", key); } else { nbytes = snprintf(pos, room, "STAT %s %s\r\n", key, val); } c->stats.offset += nbytes; } static bool grow_stats_buf(conn *c, size_t needed) { size_t nsize = c->stats.size; size_t available = nsize - c->stats.offset; bool rv = true; /* Special case: No buffer -- need to allocate fresh */ if (c->stats.buffer == NULL) { nsize = 1024; available = c->stats.size = c->stats.offset = 0; } while (needed > available) { assert(nsize > 0); nsize = nsize << 1; available = nsize - c->stats.offset; } if (nsize != c->stats.size) { char *ptr = realloc(c->stats.buffer, nsize); if (ptr) { c->stats.buffer = ptr; c->stats.size = nsize; } else { rv = false; } } return rv; } static void append_stats(const char *key, const uint16_t klen, const char *val, const uint32_t vlen, const void *cookie) { /* value without a key is invalid */ if (klen == 0 && vlen > 0) { return ; } conn *c = (conn*)cookie; if (c->protocol == binary_prot) { size_t needed = vlen + klen + sizeof(protocol_binary_response_header); if (!grow_stats_buf(c, needed)) { return ; } append_bin_stats(key, klen, val, vlen, c); } else { size_t needed = vlen + klen + 10; // 10 == "STAT = \r\n" if (!grow_stats_buf(c, needed)) { return ; } append_ascii_stats(key, klen, val, vlen, c); } assert(c->stats.offset <= c->stats.size); } static void process_bin_stat(conn *c) { char *subcommand = binary_get_key(c); size_t nkey = c->binary_header.request.keylen; if (settings.verbose > 1) { int ii; fprintf(stderr, "<%d STATS ", c->sfd); for (ii = 0; ii < nkey; ++ii) { fprintf(stderr, "%c", subcommand[ii]); } fprintf(stderr, "\n"); } if (nkey == 0) { /* request all statistics */ server_stats(&append_stats, c); (void)get_stats(NULL, 0, &append_stats, c); } else if (strncmp(subcommand, "reset", 5) == 0) { stats_reset(); } else if (strncmp(subcommand, "settings", 8) == 0) { process_stat_settings(&append_stats, c); } else if (strncmp(subcommand, "detail", 6) == 0) { char *subcmd_pos = subcommand + 6; if (strncmp(subcmd_pos, " dump", 5) == 0) { int len; char *dump_buf = stats_prefix_dump(&len); if (dump_buf == NULL || len <= 0) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); return ; } else { append_stats("detailed", strlen("detailed"), dump_buf, len, c); free(dump_buf); } } else if (strncmp(subcmd_pos, " on", 3) == 0) { settings.detail_enabled = 1; } else if (strncmp(subcmd_pos, " off", 4) == 0) { settings.detail_enabled = 0; } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); return; } } else { if (get_stats(subcommand, nkey, &append_stats, c)) { if (c->stats.buffer == NULL) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); } else { write_and_free(c, c->stats.buffer, c->stats.offset); c->stats.buffer = NULL; } } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); } return; } /* Append termination package and start the transfer */ append_stats(NULL, 0, NULL, 0, c); if (c->stats.buffer == NULL) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); } else { write_and_free(c, c->stats.buffer, c->stats.offset); c->stats.buffer = NULL; } } static void bin_read_key(conn *c, enum bin_substates next_substate, int extra) { assert(c); c->substate = next_substate; c->rlbytes = c->keylen + extra; /* Ok... do we have room for the extras and the key in the input buffer? */ ptrdiff_t offset = c->rcurr + sizeof(protocol_binary_request_header) - c->rbuf; if (c->rlbytes > c->rsize - offset) { size_t nsize = c->rsize; size_t size = c->rlbytes + sizeof(protocol_binary_request_header); while (size > nsize) { nsize *= 2; } if (nsize != c->rsize) { if (settings.verbose > 1) { fprintf(stderr, "%d: Need to grow buffer from %lu to %lu\n", c->sfd, (unsigned long)c->rsize, (unsigned long)nsize); } char *newm = realloc(c->rbuf, nsize); if (newm == NULL) { if (settings.verbose) { fprintf(stderr, "%d: Failed to grow buffer.. closing connection\n", c->sfd); } conn_set_state(c, conn_closing); return; } c->rbuf= newm; /* rcurr should point to the same offset in the packet */ c->rcurr = c->rbuf + offset - sizeof(protocol_binary_request_header); c->rsize = nsize; } if (c->rbuf != c->rcurr) { memmove(c->rbuf, c->rcurr, c->rbytes); c->rcurr = c->rbuf; if (settings.verbose > 1) { fprintf(stderr, "%d: Repack input buffer\n", c->sfd); } } } /* preserve the header in the buffer.. */ c->ritem = c->rcurr + sizeof(protocol_binary_request_header); conn_set_state(c, conn_nread); } /* Just write an error message and disconnect the client */ static void handle_binary_protocol_error(conn *c) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_EINVAL, 0); if (settings.verbose) { fprintf(stderr, "Protocol error (opcode %02x), close connection %d\n", c->binary_header.request.opcode, c->sfd); } c->write_and_go = conn_closing; } static void init_sasl_conn(conn *c) { assert(c); /* should something else be returned? */ if (!settings.sasl) return; if (!c->sasl_conn) { int result=sasl_server_new("memcached", NULL, my_sasl_hostname[0] ? my_sasl_hostname : NULL, NULL, NULL, NULL, 0, &c->sasl_conn); if (result != SASL_OK) { if (settings.verbose) { fprintf(stderr, "Failed to initialize SASL conn.\n"); } c->sasl_conn = NULL; } } } static void bin_list_sasl_mechs(conn *c) { // Guard against a disabled SASL. if (!settings.sasl) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND, c->binary_header.request.bodylen - c->binary_header.request.keylen); return; } init_sasl_conn(c); const char *result_string = NULL; unsigned int string_length = 0; int result=sasl_listmech(c->sasl_conn, NULL, "", /* What to prepend the string with */ " ", /* What to separate mechanisms with */ "", /* What to append to the string */ &result_string, &string_length, NULL); if (result != SASL_OK) { /* Perhaps there's a better error for this... */ if (settings.verbose) { fprintf(stderr, "Failed to list SASL mechanisms.\n"); } write_bin_error(c, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR, 0); return; } write_bin_response(c, (char*)result_string, 0, 0, string_length); } static void process_bin_sasl_auth(conn *c) { // Guard for handling disabled SASL on the server. if (!settings.sasl) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND, c->binary_header.request.bodylen - c->binary_header.request.keylen); return; } assert(c->binary_header.request.extlen == 0); int nkey = c->binary_header.request.keylen; int vlen = c->binary_header.request.bodylen - nkey; if (nkey > MAX_SASL_MECH_LEN) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_EINVAL, vlen); c->write_and_go = conn_swallow; return; } char *key = binary_get_key(c); assert(key); item *it = item_alloc(key, nkey, 0, 0, vlen); if (it == 0) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen); c->write_and_go = conn_swallow; return; } c->item = it; c->ritem = ITEM_data(it); c->rlbytes = vlen; conn_set_state(c, conn_nread); c->substate = bin_reading_sasl_auth_data; } static void process_bin_complete_sasl_auth(conn *c) { assert(settings.sasl); const char *out = NULL; unsigned int outlen = 0; assert(c->item); init_sasl_conn(c); int nkey = c->binary_header.request.keylen; int vlen = c->binary_header.request.bodylen - nkey; char mech[nkey+1]; memcpy(mech, ITEM_key((item*)c->item), nkey); mech[nkey] = 0x00; if (settings.verbose) fprintf(stderr, "mech: ``%s'' with %d bytes of data\n", mech, vlen); const char *challenge = vlen == 0 ? NULL : ITEM_data((item*) c->item); int result=-1; switch (c->cmd) { case PROTOCOL_BINARY_CMD_SASL_AUTH: result = sasl_server_start(c->sasl_conn, mech, challenge, vlen, &out, &outlen); break; case PROTOCOL_BINARY_CMD_SASL_STEP: result = sasl_server_step(c->sasl_conn, challenge, vlen, &out, &outlen); break; default: assert(false); /* CMD should be one of the above */ /* This code is pretty much impossible, but makes the compiler happier */ if (settings.verbose) { fprintf(stderr, "Unhandled command %d with challenge %s\n", c->cmd, challenge); } break; } item_unlink(c->item); if (settings.verbose) { fprintf(stderr, "sasl result code: %d\n", result); } switch(result) { case SASL_OK: write_bin_response(c, "Authenticated", 0, 0, strlen("Authenticated")); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.auth_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); break; case SASL_CONTINUE: add_bin_header(c, PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE, 0, 0, outlen); if(outlen > 0) { add_iov(c, out, outlen); } conn_set_state(c, conn_mwrite); c->write_and_go = conn_new_cmd; break; default: if (settings.verbose) fprintf(stderr, "Unknown sasl response: %d\n", result); write_bin_error(c, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR, 0); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.auth_cmds++; c->thread->stats.auth_errors++; pthread_mutex_unlock(&c->thread->stats.mutex); } } static bool authenticated(conn *c) { assert(settings.sasl); bool rv = false; switch (c->cmd) { case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_SASL_AUTH: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_SASL_STEP: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_VERSION: /* FALLTHROUGH */ rv = true; break; default: if (c->sasl_conn) { const void *uname = NULL; sasl_getprop(c->sasl_conn, SASL_USERNAME, &uname); rv = uname != NULL; } } if (settings.verbose > 1) { fprintf(stderr, "authenticated() in cmd 0x%02x is %s\n", c->cmd, rv ? "true" : "false"); } return rv; } static void dispatch_bin_command(conn *c) { int protocol_error = 0; int extlen = c->binary_header.request.extlen; int keylen = c->binary_header.request.keylen; uint32_t bodylen = c->binary_header.request.bodylen; if (settings.sasl && !authenticated(c)) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR, 0); c->write_and_go = conn_closing; return; } MEMCACHED_PROCESS_COMMAND_START(c->sfd, c->rcurr, c->rbytes); c->noreply = true; /* binprot supports 16bit keys, but internals are still 8bit */ if (keylen > KEY_MAX_LENGTH) { handle_binary_protocol_error(c); return; } switch (c->cmd) { case PROTOCOL_BINARY_CMD_SETQ: c->cmd = PROTOCOL_BINARY_CMD_SET; break; case PROTOCOL_BINARY_CMD_ADDQ: c->cmd = PROTOCOL_BINARY_CMD_ADD; break; case PROTOCOL_BINARY_CMD_REPLACEQ: c->cmd = PROTOCOL_BINARY_CMD_REPLACE; break; case PROTOCOL_BINARY_CMD_DELETEQ: c->cmd = PROTOCOL_BINARY_CMD_DELETE; break; case PROTOCOL_BINARY_CMD_INCREMENTQ: c->cmd = PROTOCOL_BINARY_CMD_INCREMENT; break; case PROTOCOL_BINARY_CMD_DECREMENTQ: c->cmd = PROTOCOL_BINARY_CMD_DECREMENT; break; case PROTOCOL_BINARY_CMD_QUITQ: c->cmd = PROTOCOL_BINARY_CMD_QUIT; break; case PROTOCOL_BINARY_CMD_FLUSHQ: c->cmd = PROTOCOL_BINARY_CMD_FLUSH; break; case PROTOCOL_BINARY_CMD_APPENDQ: c->cmd = PROTOCOL_BINARY_CMD_APPEND; break; case PROTOCOL_BINARY_CMD_PREPENDQ: c->cmd = PROTOCOL_BINARY_CMD_PREPEND; break; case PROTOCOL_BINARY_CMD_GETQ: c->cmd = PROTOCOL_BINARY_CMD_GET; break; case PROTOCOL_BINARY_CMD_GETKQ: c->cmd = PROTOCOL_BINARY_CMD_GETK; break; case PROTOCOL_BINARY_CMD_GATQ: c->cmd = PROTOCOL_BINARY_CMD_GAT; break; case PROTOCOL_BINARY_CMD_GATKQ: c->cmd = PROTOCOL_BINARY_CMD_GAT; break; default: c->noreply = false; } switch (c->cmd) { case PROTOCOL_BINARY_CMD_VERSION: if (extlen == 0 && keylen == 0 && bodylen == 0) { write_bin_response(c, VERSION, 0, 0, strlen(VERSION)); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_FLUSH: if (keylen == 0 && bodylen == extlen && (extlen == 0 || extlen == 4)) { bin_read_key(c, bin_read_flush_exptime, extlen); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_NOOP: if (extlen == 0 && keylen == 0 && bodylen == 0) { write_bin_response(c, NULL, 0, 0, 0); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_SET: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_ADD: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_REPLACE: if (extlen == 8 && keylen != 0 && bodylen >= (keylen + 8)) { bin_read_key(c, bin_reading_set_header, 8); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_GETQ: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_GET: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_GETKQ: /* FALLTHROUGH */ case PROTOCOL_BINARY_CMD_GETK: if (extlen == 0 && bodylen == keylen && keylen > 0) { bin_read_key(c, bin_reading_get_key, 0); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_DELETE: if (keylen > 0 && extlen == 0 && bodylen == keylen) { bin_read_key(c, bin_reading_del_header, extlen); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_INCREMENT: case PROTOCOL_BINARY_CMD_DECREMENT: if (keylen > 0 && extlen == 20 && bodylen == (keylen + extlen)) { bin_read_key(c, bin_reading_incr_header, 20); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_PREPEND: if (keylen > 0 && extlen == 0) { bin_read_key(c, bin_reading_set_header, 0); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_STAT: if (extlen == 0) { bin_read_key(c, bin_reading_stat, 0); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_QUIT: if (keylen == 0 && extlen == 0 && bodylen == 0) { write_bin_response(c, NULL, 0, 0, 0); c->write_and_go = conn_closing; if (c->noreply) { conn_set_state(c, conn_closing); } } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: if (extlen == 0 && keylen == 0 && bodylen == 0) { bin_list_sasl_mechs(c); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_SASL_AUTH: case PROTOCOL_BINARY_CMD_SASL_STEP: if (extlen == 0 && keylen != 0) { bin_read_key(c, bin_reading_sasl_auth, 0); } else { protocol_error = 1; } break; case PROTOCOL_BINARY_CMD_TOUCH: case PROTOCOL_BINARY_CMD_GAT: case PROTOCOL_BINARY_CMD_GATQ: case PROTOCOL_BINARY_CMD_GATK: case PROTOCOL_BINARY_CMD_GATKQ: if (extlen == 4 && keylen != 0) { bin_read_key(c, bin_reading_touch_key, 4); } else { protocol_error = 1; } break; default: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND, bodylen); } if (protocol_error) handle_binary_protocol_error(c); } static void process_bin_update(conn *c) { char *key; int nkey; int vlen; item *it; protocol_binary_request_set* req = binary_get_request(c); assert(c != NULL); key = binary_get_key(c); nkey = c->binary_header.request.keylen; /* fix byteorder in the request */ req->message.body.flags = ntohl(req->message.body.flags); req->message.body.expiration = ntohl(req->message.body.expiration); vlen = c->binary_header.request.bodylen - (nkey + c->binary_header.request.extlen); if (settings.verbose > 1) { int ii; if (c->cmd == PROTOCOL_BINARY_CMD_ADD) { fprintf(stderr, "<%d ADD ", c->sfd); } else if (c->cmd == PROTOCOL_BINARY_CMD_SET) { fprintf(stderr, "<%d SET ", c->sfd); } else { fprintf(stderr, "<%d REPLACE ", c->sfd); } for (ii = 0; ii < nkey; ++ii) { fprintf(stderr, "%c", key[ii]); } fprintf(stderr, " Value len is %d", vlen); fprintf(stderr, "\n"); } if (settings.detail_enabled) { stats_prefix_record_set(key, nkey); } it = item_alloc(key, nkey, req->message.body.flags, realtime(req->message.body.expiration), vlen+2); if (it == 0) { if (! item_size_ok(nkey, req->message.body.flags, vlen + 2)) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_E2BIG, vlen); } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen); } /* Avoid stale data persisting in cache because we failed alloc. * Unacceptable for SET. Anywhere else too? */ if (c->cmd == PROTOCOL_BINARY_CMD_SET) { it = item_get(key, nkey); if (it) { item_unlink(it); item_remove(it); } } /* swallow the data line */ c->write_and_go = conn_swallow; return; } ITEM_set_cas(it, c->binary_header.request.cas); switch (c->cmd) { case PROTOCOL_BINARY_CMD_ADD: c->cmd = NREAD_ADD; break; case PROTOCOL_BINARY_CMD_SET: c->cmd = NREAD_SET; break; case PROTOCOL_BINARY_CMD_REPLACE: c->cmd = NREAD_REPLACE; break; default: assert(0); } if (ITEM_get_cas(it) != 0) { c->cmd = NREAD_CAS; } c->item = it; c->ritem = ITEM_data(it); c->rlbytes = vlen; conn_set_state(c, conn_nread); c->substate = bin_read_set_value; } static void process_bin_append_prepend(conn *c) { char *key; int nkey; int vlen; item *it; assert(c != NULL); key = binary_get_key(c); nkey = c->binary_header.request.keylen; vlen = c->binary_header.request.bodylen - nkey; if (settings.verbose > 1) { fprintf(stderr, "Value len is %d\n", vlen); } if (settings.detail_enabled) { stats_prefix_record_set(key, nkey); } it = item_alloc(key, nkey, 0, 0, vlen+2); if (it == 0) { if (! item_size_ok(nkey, 0, vlen + 2)) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_E2BIG, vlen); } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, vlen); } /* swallow the data line */ c->write_and_go = conn_swallow; return; } ITEM_set_cas(it, c->binary_header.request.cas); switch (c->cmd) { case PROTOCOL_BINARY_CMD_APPEND: c->cmd = NREAD_APPEND; break; case PROTOCOL_BINARY_CMD_PREPEND: c->cmd = NREAD_PREPEND; break; default: assert(0); } c->item = it; c->ritem = ITEM_data(it); c->rlbytes = vlen; conn_set_state(c, conn_nread); c->substate = bin_read_set_value; } static void process_bin_flush(conn *c) { time_t exptime = 0; protocol_binary_request_flush* req = binary_get_request(c); if (c->binary_header.request.extlen == sizeof(req->message.body)) { exptime = ntohl(req->message.body.expiration); } if (exptime > 0) { settings.oldest_live = realtime(exptime) - 1; } else { settings.oldest_live = current_time - 1; } item_flush_expired(); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.flush_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); write_bin_response(c, NULL, 0, 0, 0); } static void process_bin_delete(conn *c) { item *it; protocol_binary_request_delete* req = binary_get_request(c); char* key = binary_get_key(c); size_t nkey = c->binary_header.request.keylen; assert(c != NULL); if (settings.verbose > 1) { fprintf(stderr, "Deleting %s\n", key); } if (settings.detail_enabled) { stats_prefix_record_delete(key, nkey); } it = item_get(key, nkey); if (it) { uint64_t cas = ntohll(req->message.header.request.cas); if (cas == 0 || cas == ITEM_get_cas(it)) { MEMCACHED_COMMAND_DELETE(c->sfd, ITEM_key(it), it->nkey); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].delete_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); item_unlink(it); write_bin_response(c, NULL, 0, 0, 0); } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0); } item_remove(it); /* release our reference */ } else { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.delete_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); } } static void complete_nread_binary(conn *c) { assert(c != NULL); assert(c->cmd >= 0); switch(c->substate) { case bin_reading_set_header: if (c->cmd == PROTOCOL_BINARY_CMD_APPEND || c->cmd == PROTOCOL_BINARY_CMD_PREPEND) { process_bin_append_prepend(c); } else { process_bin_update(c); } break; case bin_read_set_value: complete_update_bin(c); break; case bin_reading_get_key: process_bin_get(c); break; case bin_reading_touch_key: process_bin_touch(c); break; case bin_reading_stat: process_bin_stat(c); break; case bin_reading_del_header: process_bin_delete(c); break; case bin_reading_incr_header: complete_incr_bin(c); break; case bin_read_flush_exptime: process_bin_flush(c); break; case bin_reading_sasl_auth: process_bin_sasl_auth(c); break; case bin_reading_sasl_auth_data: process_bin_complete_sasl_auth(c); break; default: fprintf(stderr, "Not handling substate %d\n", c->substate); assert(0); } } static void reset_cmd_handler(conn *c) { c->cmd = -1; c->substate = bin_no_state; if(c->item != NULL) { item_remove(c->item); c->item = NULL; } conn_shrink(c); if (c->rbytes > 0) { conn_set_state(c, conn_parse_cmd); } else { conn_set_state(c, conn_waiting); } } static void complete_nread(conn *c) { assert(c != NULL); assert(c->protocol == ascii_prot || c->protocol == binary_prot); if (c->protocol == ascii_prot) { complete_nread_ascii(c); } else if (c->protocol == binary_prot) { complete_nread_binary(c); } } /* * Stores an item in the cache according to the semantics of one of the set * commands. In threaded mode, this is protected by the cache lock. * * Returns the state of storage. */ enum store_item_type do_store_item(item *it, int comm, conn *c, const uint32_t hv) { char *key = ITEM_key(it); item *old_it = do_item_get(key, it->nkey, hv); enum store_item_type stored = NOT_STORED; item *new_it = NULL; int flags; if (old_it != NULL && comm == NREAD_ADD) { /* add only adds a nonexistent item, but promote to head of LRU */ do_item_update(old_it); } else if (!old_it && (comm == NREAD_REPLACE || comm == NREAD_APPEND || comm == NREAD_PREPEND)) { /* replace only replaces an existing value; don't store */ } else if (comm == NREAD_CAS) { /* validate cas operation */ if(old_it == NULL) { // LRU expired stored = NOT_FOUND; pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.cas_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); } else if (ITEM_get_cas(it) == ITEM_get_cas(old_it)) { // cas validates // it and old_it may belong to different classes. // I'm updating the stats for the one that's getting pushed out pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[old_it->slabs_clsid].cas_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); item_replace(old_it, it, hv); stored = STORED; } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[old_it->slabs_clsid].cas_badval++; pthread_mutex_unlock(&c->thread->stats.mutex); if(settings.verbose > 1) { fprintf(stderr, "CAS: failure: expected %llu, got %llu\n", (unsigned long long)ITEM_get_cas(old_it), (unsigned long long)ITEM_get_cas(it)); } stored = EXISTS; } } else { /* * Append - combine new and old record into single one. Here it's * atomic and thread-safe. */ if (comm == NREAD_APPEND || comm == NREAD_PREPEND) { /* * Validate CAS */ if (ITEM_get_cas(it) != 0) { // CAS much be equal if (ITEM_get_cas(it) != ITEM_get_cas(old_it)) { stored = EXISTS; } } if (stored == NOT_STORED) { /* we have it and old_it here - alloc memory to hold both */ /* flags was already lost - so recover them from ITEM_suffix(it) */ flags = (int) strtol(ITEM_suffix(old_it), (char **) NULL, 10); new_it = item_alloc(key, it->nkey, flags, old_it->exptime, it->nbytes + old_it->nbytes - 2 /* CRLF */); if (new_it == NULL) { /* SERVER_ERROR out of memory */ if (old_it != NULL) do_item_remove(old_it); return NOT_STORED; } /* copy data from it and old_it to new_it */ if (comm == NREAD_APPEND) { memcpy(ITEM_data(new_it), ITEM_data(old_it), old_it->nbytes); memcpy(ITEM_data(new_it) + old_it->nbytes - 2 /* CRLF */, ITEM_data(it), it->nbytes); } else { /* NREAD_PREPEND */ memcpy(ITEM_data(new_it), ITEM_data(it), it->nbytes); memcpy(ITEM_data(new_it) + it->nbytes - 2 /* CRLF */, ITEM_data(old_it), old_it->nbytes); } it = new_it; } } if (stored == NOT_STORED) { if (old_it != NULL) item_replace(old_it, it, hv); else do_item_link(it, hv); c->cas = ITEM_get_cas(it); stored = STORED; } } if (old_it != NULL) do_item_remove(old_it); /* release our reference */ if (new_it != NULL) do_item_remove(new_it); if (stored == STORED) { c->cas = ITEM_get_cas(it); } return stored; } typedef struct token_s { char *value; size_t length; } token_t; #define COMMAND_TOKEN 0 #define SUBCOMMAND_TOKEN 1 #define KEY_TOKEN 1 #define MAX_TOKENS 8 /* * Tokenize the command string by replacing whitespace with '\0' and update * the token array tokens with pointer to start of each token and length. * Returns total number of tokens. The last valid token is the terminal * token (value points to the first unprocessed character of the string and * length zero). * * Usage example: * * while(tokenize_command(command, ncommand, tokens, max_tokens) > 0) { * for(int ix = 0; tokens[ix].length != 0; ix++) { * ... * } * ncommand = tokens[ix].value - command; * command = tokens[ix].value; * } */ static size_t tokenize_command(char *command, token_t *tokens, const size_t max_tokens) { char *s, *e; size_t ntokens = 0; size_t len = strlen(command); unsigned int i = 0; assert(command != NULL && tokens != NULL && max_tokens > 1); s = e = command; for (i = 0; i < len; i++) { if (*e == ' ') { if (s != e) { tokens[ntokens].value = s; tokens[ntokens].length = e - s; ntokens++; *e = '\0'; if (ntokens == max_tokens - 1) { e++; s = e; /* so we don't add an extra token */ break; } } s = e + 1; } e++; } if (s != e) { tokens[ntokens].value = s; tokens[ntokens].length = e - s; ntokens++; } /* * If we scanned the whole string, the terminal value pointer is null, * otherwise it is the first unprocessed character. */ tokens[ntokens].value = *e == '\0' ? NULL : e; tokens[ntokens].length = 0; ntokens++; return ntokens; } /* set up a connection to write a buffer then free it, used for stats */ static void write_and_free(conn *c, char *buf, int bytes) { if (buf) { c->write_and_free = buf; c->wcurr = buf; c->wbytes = bytes; conn_set_state(c, conn_write); c->write_and_go = conn_new_cmd; } else { out_string(c, "SERVER_ERROR out of memory writing stats"); } } static inline bool set_noreply_maybe(conn *c, token_t *tokens, size_t ntokens) { int noreply_index = ntokens - 2; /* NOTE: this function is not the first place where we are going to send the reply. We could send it instead from process_command() if the request line has wrong number of tokens. However parsing malformed line for "noreply" option is not reliable anyway, so it can't be helped. */ if (tokens[noreply_index].value && strcmp(tokens[noreply_index].value, "noreply") == 0) { c->noreply = true; } return c->noreply; } void append_stat(const char *name, ADD_STAT add_stats, conn *c, const char *fmt, ...) { char val_str[STAT_VAL_LEN]; int vlen; va_list ap; assert(name); assert(add_stats); assert(c); assert(fmt); va_start(ap, fmt); vlen = vsnprintf(val_str, sizeof(val_str) - 1, fmt, ap); va_end(ap); add_stats(name, strlen(name), val_str, vlen, c); } inline static void process_stats_detail(conn *c, const char *command) { assert(c != NULL); if (strcmp(command, "on") == 0) { settings.detail_enabled = 1; out_string(c, "OK"); } else if (strcmp(command, "off") == 0) { settings.detail_enabled = 0; out_string(c, "OK"); } else if (strcmp(command, "dump") == 0) { int len; char *stats = stats_prefix_dump(&len); write_and_free(c, stats, len); } else { out_string(c, "CLIENT_ERROR usage: stats detail on|off|dump"); } } /* return server specific stats only */ static void server_stats(ADD_STAT add_stats, conn *c) { pid_t pid = getpid(); rel_time_t now = current_time; struct thread_stats thread_stats; threadlocal_stats_aggregate(&thread_stats); struct slab_stats slab_stats; slab_stats_aggregate(&thread_stats, &slab_stats); #ifndef WIN32 struct rusage usage; getrusage(RUSAGE_SELF, &usage); #endif /* !WIN32 */ STATS_LOCK(); APPEND_STAT("pid", "%lu", (long)pid); APPEND_STAT("uptime", "%u", now); APPEND_STAT("time", "%ld", now + (long)process_started); APPEND_STAT("version", "%s", VERSION); APPEND_STAT("libevent", "%s", event_get_version()); APPEND_STAT("pointer_size", "%d", (int)(8 * sizeof(void *))); #ifndef WIN32 append_stat("rusage_user", add_stats, c, "%ld.%06ld", (long)usage.ru_utime.tv_sec, (long)usage.ru_utime.tv_usec); append_stat("rusage_system", add_stats, c, "%ld.%06ld", (long)usage.ru_stime.tv_sec, (long)usage.ru_stime.tv_usec); #endif /* !WIN32 */ APPEND_STAT("curr_connections", "%u", stats.curr_conns - 1); APPEND_STAT("total_connections", "%u", stats.total_conns); if (settings.maxconns_fast) { APPEND_STAT("rejected_connections", "%llu", (unsigned long long)stats.rejected_conns); } APPEND_STAT("connection_structures", "%u", stats.conn_structs); APPEND_STAT("reserved_fds", "%u", stats.reserved_fds); APPEND_STAT("cmd_get", "%llu", (unsigned long long)thread_stats.get_cmds); APPEND_STAT("cmd_set", "%llu", (unsigned long long)slab_stats.set_cmds); APPEND_STAT("cmd_flush", "%llu", (unsigned long long)thread_stats.flush_cmds); APPEND_STAT("cmd_touch", "%llu", (unsigned long long)thread_stats.touch_cmds); APPEND_STAT("get_hits", "%llu", (unsigned long long)slab_stats.get_hits); APPEND_STAT("get_misses", "%llu", (unsigned long long)thread_stats.get_misses); APPEND_STAT("delete_misses", "%llu", (unsigned long long)thread_stats.delete_misses); APPEND_STAT("delete_hits", "%llu", (unsigned long long)slab_stats.delete_hits); APPEND_STAT("incr_misses", "%llu", (unsigned long long)thread_stats.incr_misses); APPEND_STAT("incr_hits", "%llu", (unsigned long long)slab_stats.incr_hits); APPEND_STAT("decr_misses", "%llu", (unsigned long long)thread_stats.decr_misses); APPEND_STAT("decr_hits", "%llu", (unsigned long long)slab_stats.decr_hits); APPEND_STAT("cas_misses", "%llu", (unsigned long long)thread_stats.cas_misses); APPEND_STAT("cas_hits", "%llu", (unsigned long long)slab_stats.cas_hits); APPEND_STAT("cas_badval", "%llu", (unsigned long long)slab_stats.cas_badval); APPEND_STAT("touch_hits", "%llu", (unsigned long long)slab_stats.touch_hits); APPEND_STAT("touch_misses", "%llu", (unsigned long long)thread_stats.touch_misses); APPEND_STAT("auth_cmds", "%llu", (unsigned long long)thread_stats.auth_cmds); APPEND_STAT("auth_errors", "%llu", (unsigned long long)thread_stats.auth_errors); APPEND_STAT("bytes_read", "%llu", (unsigned long long)thread_stats.bytes_read); APPEND_STAT("bytes_written", "%llu", (unsigned long long)thread_stats.bytes_written); APPEND_STAT("limit_maxbytes", "%llu", (unsigned long long)settings.maxbytes); APPEND_STAT("accepting_conns", "%u", stats.accepting_conns); APPEND_STAT("listen_disabled_num", "%llu", (unsigned long long)stats.listen_disabled_num); APPEND_STAT("threads", "%d", settings.num_threads); APPEND_STAT("conn_yields", "%llu", (unsigned long long)thread_stats.conn_yields); APPEND_STAT("hash_power_level", "%u", stats.hash_power_level); APPEND_STAT("hash_bytes", "%llu", (unsigned long long)stats.hash_bytes); APPEND_STAT("hash_is_expanding", "%u", stats.hash_is_expanding); APPEND_STAT("expired_unfetched", "%llu", stats.expired_unfetched); APPEND_STAT("evicted_unfetched", "%llu", stats.evicted_unfetched); if (settings.slab_reassign) { APPEND_STAT("slab_reassign_running", "%u", stats.slab_reassign_running); APPEND_STAT("slabs_moved", "%llu", stats.slabs_moved); } STATS_UNLOCK(); } static void process_stat_settings(ADD_STAT add_stats, void *c) { assert(add_stats); APPEND_STAT("maxbytes", "%u", (unsigned int)settings.maxbytes); APPEND_STAT("maxconns", "%d", settings.maxconns); APPEND_STAT("tcpport", "%d", settings.port); APPEND_STAT("udpport", "%d", settings.udpport); APPEND_STAT("inter", "%s", settings.inter ? settings.inter : "NULL"); APPEND_STAT("verbosity", "%d", settings.verbose); APPEND_STAT("oldest", "%lu", (unsigned long)settings.oldest_live); APPEND_STAT("evictions", "%s", settings.evict_to_free ? "on" : "off"); APPEND_STAT("domain_socket", "%s", settings.socketpath ? settings.socketpath : "NULL"); APPEND_STAT("umask", "%o", settings.access); APPEND_STAT("growth_factor", "%.2f", settings.factor); APPEND_STAT("chunk_size", "%d", settings.chunk_size); APPEND_STAT("num_threads", "%d", settings.num_threads); APPEND_STAT("num_threads_per_udp", "%d", settings.num_threads_per_udp); APPEND_STAT("stat_key_prefix", "%c", settings.prefix_delimiter); APPEND_STAT("detail_enabled", "%s", settings.detail_enabled ? "yes" : "no"); APPEND_STAT("reqs_per_event", "%d", settings.reqs_per_event); APPEND_STAT("cas_enabled", "%s", settings.use_cas ? "yes" : "no"); APPEND_STAT("tcp_backlog", "%d", settings.backlog); APPEND_STAT("binding_protocol", "%s", prot_text(settings.binding_protocol)); APPEND_STAT("auth_enabled_sasl", "%s", settings.sasl ? "yes" : "no"); APPEND_STAT("item_size_max", "%d", settings.item_size_max); APPEND_STAT("maxconns_fast", "%s", settings.maxconns_fast ? "yes" : "no"); APPEND_STAT("hashpower_init", "%d", settings.hashpower_init); APPEND_STAT("slab_reassign", "%s", settings.slab_reassign ? "yes" : "no"); APPEND_STAT("slab_automove", "%d", settings.slab_automove); } static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { const char *subcommand = tokens[SUBCOMMAND_TOKEN].value; assert(c != NULL); if (ntokens < 2) { out_string(c, "CLIENT_ERROR bad command line"); return; } if (ntokens == 2) { server_stats(&append_stats, c); (void)get_stats(NULL, 0, &append_stats, c); } else if (strcmp(subcommand, "reset") == 0) { stats_reset(); out_string(c, "RESET"); return ; } else if (strcmp(subcommand, "detail") == 0) { /* NOTE: how to tackle detail with binary? */ if (ntokens < 4) process_stats_detail(c, ""); /* outputs the error message */ else process_stats_detail(c, tokens[2].value); /* Output already generated */ return ; } else if (strcmp(subcommand, "settings") == 0) { process_stat_settings(&append_stats, c); } else if (strcmp(subcommand, "cachedump") == 0) { char *buf; unsigned int bytes, id, limit = 0; if (ntokens < 5) { out_string(c, "CLIENT_ERROR bad command line"); return; } if (!safe_strtoul(tokens[2].value, &id) || !safe_strtoul(tokens[3].value, &limit)) { out_string(c, "CLIENT_ERROR bad command line format"); return; } if (id >= POWER_LARGEST) { out_string(c, "CLIENT_ERROR Illegal slab id"); return; } buf = item_cachedump(id, limit, &bytes); write_and_free(c, buf, bytes); return ; } else { /* getting here means that the subcommand is either engine specific or is invalid. query the engine and see. */ if (get_stats(subcommand, strlen(subcommand), &append_stats, c)) { if (c->stats.buffer == NULL) { out_string(c, "SERVER_ERROR out of memory writing stats"); } else { write_and_free(c, c->stats.buffer, c->stats.offset); c->stats.buffer = NULL; } } else { out_string(c, "ERROR"); } return ; } /* append terminator and start the transfer */ append_stats(NULL, 0, NULL, 0, c); if (c->stats.buffer == NULL) { out_string(c, "SERVER_ERROR out of memory writing stats"); } else { write_and_free(c, c->stats.buffer, c->stats.offset); c->stats.buffer = NULL; } } /* ntokens is overwritten here... shrug.. */ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, bool return_cas) { char *key; size_t nkey; int i = 0; item *it; token_t *key_token = &tokens[KEY_TOKEN]; char *suffix; assert(c != NULL); do { while(key_token->length != 0) { key = key_token->value; nkey = key_token->length; if(nkey > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } it = item_get(key, nkey); if (settings.detail_enabled) { stats_prefix_record_get(key, nkey, NULL != it); } if (it) { if (i >= c->isize) { item **new_list = realloc(c->ilist, sizeof(item *) * c->isize * 2); if (new_list) { c->isize *= 2; c->ilist = new_list; } else { item_remove(it); break; } } /* * Construct the response. Each hit adds three elements to the * outgoing data list: * "VALUE " * key * " " + flags + " " + data length + "\r\n" + data (with \r\n) */ if (return_cas) { MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); /* Goofy mid-flight realloc. */ if (i >= c->suffixsize) { char **new_suffix_list = realloc(c->suffixlist, sizeof(char *) * c->suffixsize * 2); if (new_suffix_list) { c->suffixsize *= 2; c->suffixlist = new_suffix_list; } else { item_remove(it); break; } } suffix = cache_alloc(c->thread->suffix_cache); if (suffix == NULL) { out_string(c, "SERVER_ERROR out of memory making CAS suffix"); item_remove(it); return; } *(c->suffixlist + i) = suffix; int suffix_len = snprintf(suffix, SUFFIX_SIZE, " %llu\r\n", (unsigned long long)ITEM_get_cas(it)); if (add_iov(c, "VALUE ", 6) != 0 || add_iov(c, ITEM_key(it), it->nkey) != 0 || add_iov(c, ITEM_suffix(it), it->nsuffix - 2) != 0 || add_iov(c, suffix, suffix_len) != 0 || add_iov(c, ITEM_data(it), it->nbytes) != 0) { item_remove(it); break; } } else { MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); if (add_iov(c, "VALUE ", 6) != 0 || add_iov(c, ITEM_key(it), it->nkey) != 0 || add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) { item_remove(it); break; } } if (settings.verbose > 1) fprintf(stderr, ">%d sending key %s\n", c->sfd, ITEM_key(it)); /* item_get() has incremented it->refcount for us */ pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].get_hits++; c->thread->stats.get_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); item_update(it); *(c->ilist + i) = it; i++; } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.get_misses++; c->thread->stats.get_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_GET(c->sfd, key, nkey, -1, 0); } key_token++; } /* * If the command string hasn't been fully processed, get the next set * of tokens. */ if(key_token->value != NULL) { ntokens = tokenize_command(key_token->value, tokens, MAX_TOKENS); key_token = tokens; } } while(key_token->value != NULL); c->icurr = c->ilist; c->ileft = i; if (return_cas) { c->suffixcurr = c->suffixlist; c->suffixleft = i; } if (settings.verbose > 1) fprintf(stderr, ">%d END\n", c->sfd); /* If the loop was terminated because of out-of-memory, it is not reliable to add END\r\n to the buffer, because it might not end in \r\n. So we send SERVER_ERROR instead. */ if (key_token->value != NULL || add_iov(c, "END\r\n", 5) != 0 || (IS_UDP(c->transport) && build_udp_headers(c) != 0)) { out_string(c, "SERVER_ERROR out of memory writing get response"); } else { conn_set_state(c, conn_mwrite); c->msgcurr = 0; } return; } static void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm, bool handle_cas) { char *key; size_t nkey; unsigned int flags; int32_t exptime_int = 0; time_t exptime; int vlen; uint64_t req_cas_id=0; item *it; assert(c != NULL); set_noreply_maybe(c, tokens, ntokens); if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } key = tokens[KEY_TOKEN].value; nkey = tokens[KEY_TOKEN].length; if (! (safe_strtoul(tokens[2].value, (uint32_t *)&flags) && safe_strtol(tokens[3].value, &exptime_int) && safe_strtol(tokens[4].value, (int32_t *)&vlen))) { out_string(c, "CLIENT_ERROR bad command line format"); return; } /* Ubuntu 8.04 breaks when I pass exptime to safe_strtol */ exptime = exptime_int; /* Negative exptimes can underflow and end up immortal. realtime() will immediately expire values that are greater than REALTIME_MAXDELTA, but less than process_started, so lets aim for that. */ if (exptime < 0) exptime = REALTIME_MAXDELTA + 1; // does cas value exist? if (handle_cas) { if (!safe_strtoull(tokens[5].value, &req_cas_id)) { out_string(c, "CLIENT_ERROR bad command line format"); return; } } vlen += 2; if (vlen < 0 || vlen - 2 < 0) { out_string(c, "CLIENT_ERROR bad command line format"); return; } if (settings.detail_enabled) { stats_prefix_record_set(key, nkey); } it = item_alloc(key, nkey, flags, realtime(exptime), vlen); if (it == 0) { if (! item_size_ok(nkey, flags, vlen)) out_string(c, "SERVER_ERROR object too large for cache"); else out_string(c, "SERVER_ERROR out of memory storing object"); /* swallow the data line */ c->write_and_go = conn_swallow; c->sbytes = vlen; /* Avoid stale data persisting in cache because we failed alloc. * Unacceptable for SET. Anywhere else too? */ if (comm == NREAD_SET) { it = item_get(key, nkey); if (it) { item_unlink(it); item_remove(it); } } return; } ITEM_set_cas(it, req_cas_id); c->item = it; c->ritem = ITEM_data(it); c->rlbytes = it->nbytes; c->cmd = comm; conn_set_state(c, conn_nread); } static void process_touch_command(conn *c, token_t *tokens, const size_t ntokens) { char *key; size_t nkey; int32_t exptime_int = 0; item *it; assert(c != NULL); set_noreply_maybe(c, tokens, ntokens); if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } key = tokens[KEY_TOKEN].value; nkey = tokens[KEY_TOKEN].length; if (!safe_strtol(tokens[2].value, &exptime_int)) { out_string(c, "CLIENT_ERROR invalid exptime argument"); return; } it = item_touch(key, nkey, realtime(exptime_int)); if (it) { item_update(it); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.touch_cmds++; c->thread->stats.slab_stats[it->slabs_clsid].touch_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); out_string(c, "TOUCHED"); item_remove(it); } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.touch_cmds++; c->thread->stats.touch_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); out_string(c, "NOT_FOUND"); } } static void process_arithmetic_command(conn *c, token_t *tokens, const size_t ntokens, const bool incr) { char temp[INCR_MAX_STORAGE_LEN]; uint64_t delta; char *key; size_t nkey; assert(c != NULL); set_noreply_maybe(c, tokens, ntokens); if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } key = tokens[KEY_TOKEN].value; nkey = tokens[KEY_TOKEN].length; if (!safe_strtoull(tokens[2].value, &delta)) { out_string(c, "CLIENT_ERROR invalid numeric delta argument"); return; } switch(add_delta(c, key, nkey, incr, delta, temp, NULL)) { case OK: out_string(c, temp); break; case NON_NUMERIC: out_string(c, "CLIENT_ERROR cannot increment or decrement non-numeric value"); break; case EOM: out_string(c, "SERVER_ERROR out of memory"); break; case DELTA_ITEM_NOT_FOUND: pthread_mutex_lock(&c->thread->stats.mutex); if (incr) { c->thread->stats.incr_misses++; } else { c->thread->stats.decr_misses++; } pthread_mutex_unlock(&c->thread->stats.mutex); out_string(c, "NOT_FOUND"); break; case DELTA_ITEM_CAS_MISMATCH: break; /* Should never get here */ } } /* * adds a delta value to a numeric item. * * c connection requesting the operation * it item to adjust * incr true to increment value, false to decrement * delta amount to adjust value by * buf buffer for response string * * returns a response string to send back to the client. */ enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey, const bool incr, const int64_t delta, char *buf, uint64_t *cas, const uint32_t hv) { char *ptr; uint64_t value; int res; item *it; it = do_item_get(key, nkey, hv); if (!it) { return DELTA_ITEM_NOT_FOUND; } if (cas != NULL && *cas != 0 && ITEM_get_cas(it) != *cas) { do_item_remove(it); return DELTA_ITEM_CAS_MISMATCH; } ptr = ITEM_data(it); if (!safe_strtoull(ptr, &value)) { do_item_remove(it); return NON_NUMERIC; } if (incr) { value += delta; MEMCACHED_COMMAND_INCR(c->sfd, ITEM_key(it), it->nkey, value); } else { if(delta > value) { value = 0; } else { value -= delta; } MEMCACHED_COMMAND_DECR(c->sfd, ITEM_key(it), it->nkey, value); } pthread_mutex_lock(&c->thread->stats.mutex); if (incr) { c->thread->stats.slab_stats[it->slabs_clsid].incr_hits++; } else { c->thread->stats.slab_stats[it->slabs_clsid].decr_hits++; } pthread_mutex_unlock(&c->thread->stats.mutex); snprintf(buf, INCR_MAX_STORAGE_LEN, "%llu", (unsigned long long)value); res = strlen(buf); if (res + 2 > it->nbytes || it->refcount != 1) { /* need to realloc */ item *new_it; new_it = item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 ); if (new_it == 0) { do_item_remove(it); return EOM; } memcpy(ITEM_data(new_it), buf, res); memcpy(ITEM_data(new_it) + res, "\r\n", 2); item_replace(it, new_it, hv); // Overwrite the older item's CAS with our new CAS since we're // returning the CAS of the old item below. ITEM_set_cas(it, (settings.use_cas) ? ITEM_get_cas(new_it) : 0); do_item_remove(new_it); /* release our reference */ } else { /* replace in-place */ /* When changing the value without replacing the item, we need to update the CAS on the existing item. */ mutex_lock(&cache_lock); /* FIXME */ ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0); mutex_unlock(&cache_lock); memcpy(ITEM_data(it), buf, res); memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2); do_item_update(it); } if (cas) { *cas = ITEM_get_cas(it); /* swap the incoming CAS value */ } do_item_remove(it); /* release our reference */ return OK; } static void process_delete_command(conn *c, token_t *tokens, const size_t ntokens) { char *key; size_t nkey; item *it; assert(c != NULL); if (ntokens > 3) { bool hold_is_zero = strcmp(tokens[KEY_TOKEN+1].value, "0") == 0; bool sets_noreply = set_noreply_maybe(c, tokens, ntokens); bool valid = (ntokens == 4 && (hold_is_zero || sets_noreply)) || (ntokens == 5 && hold_is_zero && sets_noreply); if (!valid) { out_string(c, "CLIENT_ERROR bad command line format. " "Usage: delete [noreply]"); return; } } key = tokens[KEY_TOKEN].value; nkey = tokens[KEY_TOKEN].length; if(nkey > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } if (settings.detail_enabled) { stats_prefix_record_delete(key, nkey); } it = item_get(key, nkey); if (it) { MEMCACHED_COMMAND_DELETE(c->sfd, ITEM_key(it), it->nkey); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].delete_hits++; pthread_mutex_unlock(&c->thread->stats.mutex); item_unlink(it); item_remove(it); /* release our reference */ out_string(c, "DELETED"); } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.delete_misses++; pthread_mutex_unlock(&c->thread->stats.mutex); out_string(c, "NOT_FOUND"); } } static void process_verbosity_command(conn *c, token_t *tokens, const size_t ntokens) { unsigned int level; assert(c != NULL); set_noreply_maybe(c, tokens, ntokens); level = strtoul(tokens[1].value, NULL, 10); settings.verbose = level > MAX_VERBOSITY_LEVEL ? MAX_VERBOSITY_LEVEL : level; out_string(c, "OK"); return; } static void process_slabs_automove_command(conn *c, token_t *tokens, const size_t ntokens) { unsigned int level; assert(c != NULL); set_noreply_maybe(c, tokens, ntokens); level = strtoul(tokens[2].value, NULL, 10); if (level == 0) { settings.slab_automove = 0; } else if (level == 1 || level == 2) { settings.slab_automove = level; } else { out_string(c, "ERROR"); return; } out_string(c, "OK"); return; } static void process_command(conn *c, char *command) { token_t tokens[MAX_TOKENS]; size_t ntokens; int comm; assert(c != NULL); MEMCACHED_PROCESS_COMMAND_START(c->sfd, c->rcurr, c->rbytes); if (settings.verbose > 1) fprintf(stderr, "<%d %s\n", c->sfd, command); /* * for commands set/add/replace, we build an item and read the data * directly into it, then continue in nread_complete(). */ c->msgcurr = 0; c->msgused = 0; c->iovused = 0; if (add_msghdr(c) != 0) { out_string(c, "SERVER_ERROR out of memory preparing response"); return; } ntokens = tokenize_command(command, tokens, MAX_TOKENS); if (ntokens >= 3 && ((strcmp(tokens[COMMAND_TOKEN].value, "get") == 0) || (strcmp(tokens[COMMAND_TOKEN].value, "bget") == 0))) { process_get_command(c, tokens, ntokens, false); } else if ((ntokens == 6 || ntokens == 7) && ((strcmp(tokens[COMMAND_TOKEN].value, "add") == 0 && (comm = NREAD_ADD)) || (strcmp(tokens[COMMAND_TOKEN].value, "set") == 0 && (comm = NREAD_SET)) || (strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)) || (strcmp(tokens[COMMAND_TOKEN].value, "prepend") == 0 && (comm = NREAD_PREPEND)) || (strcmp(tokens[COMMAND_TOKEN].value, "append") == 0 && (comm = NREAD_APPEND)) )) { process_update_command(c, tokens, ntokens, comm, false); } else if ((ntokens == 7 || ntokens == 8) && (strcmp(tokens[COMMAND_TOKEN].value, "cas") == 0 && (comm = NREAD_CAS))) { process_update_command(c, tokens, ntokens, comm, true); } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) { process_arithmetic_command(c, tokens, ntokens, 1); } else if (ntokens >= 3 && (strcmp(tokens[COMMAND_TOKEN].value, "gets") == 0)) { process_get_command(c, tokens, ntokens, true); } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) { process_arithmetic_command(c, tokens, ntokens, 0); } else if (ntokens >= 3 && ntokens <= 5 && (strcmp(tokens[COMMAND_TOKEN].value, "delete") == 0)) { process_delete_command(c, tokens, ntokens); } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "touch") == 0)) { process_touch_command(c, tokens, ntokens); } else if (ntokens >= 2 && (strcmp(tokens[COMMAND_TOKEN].value, "stats") == 0)) { process_stat(c, tokens, ntokens); } else if (ntokens >= 2 && ntokens <= 4 && (strcmp(tokens[COMMAND_TOKEN].value, "flush_all") == 0)) { time_t exptime = 0; set_noreply_maybe(c, tokens, ntokens); pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.flush_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); if(ntokens == (c->noreply ? 3 : 2)) { settings.oldest_live = current_time - 1; item_flush_expired(); out_string(c, "OK"); return; } exptime = strtol(tokens[1].value, NULL, 10); if(errno == ERANGE) { out_string(c, "CLIENT_ERROR bad command line format"); return; } /* If exptime is zero realtime() would return zero too, and realtime(exptime) - 1 would overflow to the max unsigned value. So we process exptime == 0 the same way we do when no delay is given at all. */ if (exptime > 0) settings.oldest_live = realtime(exptime) - 1; else /* exptime == 0 */ settings.oldest_live = current_time - 1; item_flush_expired(); out_string(c, "OK"); return; } else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "version") == 0)) { out_string(c, "VERSION " VERSION); } else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "quit") == 0)) { conn_set_state(c, conn_closing); } else if (ntokens > 1 && strcmp(tokens[COMMAND_TOKEN].value, "slabs") == 0) { if (ntokens == 5 && strcmp(tokens[COMMAND_TOKEN + 1].value, "reassign") == 0) { int src, dst, rv; if (settings.slab_reassign == false) { out_string(c, "CLIENT_ERROR slab reassignment disabled"); return; } src = strtol(tokens[2].value, NULL, 10); dst = strtol(tokens[3].value, NULL, 10); if (errno == ERANGE) { out_string(c, "CLIENT_ERROR bad command line format"); return; } rv = slabs_reassign(src, dst); switch (rv) { case REASSIGN_OK: out_string(c, "OK"); break; case REASSIGN_RUNNING: out_string(c, "BUSY currently processing reassign request"); break; case REASSIGN_BADCLASS: out_string(c, "BADCLASS invalid src or dst class id"); break; case REASSIGN_NOSPARE: out_string(c, "NOSPARE source class has no spare pages"); break; case REASSIGN_SRC_DST_SAME: out_string(c, "SAME src and dst class are identical"); break; } return; } else if (ntokens == 4 && (strcmp(tokens[COMMAND_TOKEN + 1].value, "automove") == 0)) { process_slabs_automove_command(c, tokens, ntokens); } else { out_string(c, "ERROR"); } } else if ((ntokens == 3 || ntokens == 4) && (strcmp(tokens[COMMAND_TOKEN].value, "verbosity") == 0)) { process_verbosity_command(c, tokens, ntokens); } else { out_string(c, "ERROR"); } return; } /* * if we have a complete line in the buffer, process it. */ static int try_read_command(conn *c) { assert(c != NULL); assert(c->rcurr <= (c->rbuf + c->rsize)); assert(c->rbytes > 0); if (c->protocol == negotiating_prot || c->transport == udp_transport) { if ((unsigned char)c->rbuf[0] == (unsigned char)PROTOCOL_BINARY_REQ) { c->protocol = binary_prot; } else { c->protocol = ascii_prot; } if (settings.verbose > 1) { fprintf(stderr, "%d: Client using the %s protocol\n", c->sfd, prot_text(c->protocol)); } } if (c->protocol == binary_prot) { /* Do we have the complete packet header? */ if (c->rbytes < sizeof(c->binary_header)) { /* need more data! */ return 0; } else { #ifdef NEED_ALIGN if (((long)(c->rcurr)) % 8 != 0) { /* must realign input buffer */ memmove(c->rbuf, c->rcurr, c->rbytes); c->rcurr = c->rbuf; if (settings.verbose > 1) { fprintf(stderr, "%d: Realign input buffer\n", c->sfd); } } #endif protocol_binary_request_header* req; req = (protocol_binary_request_header*)c->rcurr; if (settings.verbose > 1) { /* Dump the packet before we convert it to host order */ int ii; fprintf(stderr, "<%d Read binary protocol data:", c->sfd); for (ii = 0; ii < sizeof(req->bytes); ++ii) { if (ii % 4 == 0) { fprintf(stderr, "\n<%d ", c->sfd); } fprintf(stderr, " 0x%02x", req->bytes[ii]); } fprintf(stderr, "\n"); } c->binary_header = *req; c->binary_header.request.keylen = ntohs(req->request.keylen); c->binary_header.request.bodylen = ntohl(req->request.bodylen); c->binary_header.request.cas = ntohll(req->request.cas); if (c->binary_header.request.magic != PROTOCOL_BINARY_REQ) { if (settings.verbose) { fprintf(stderr, "Invalid magic: %x\n", c->binary_header.request.magic); } conn_set_state(c, conn_closing); return -1; } c->msgcurr = 0; c->msgused = 0; c->iovused = 0; if (add_msghdr(c) != 0) { out_string(c, "SERVER_ERROR out of memory"); return 0; } c->cmd = c->binary_header.request.opcode; c->keylen = c->binary_header.request.keylen; c->opaque = c->binary_header.request.opaque; /* clear the returned cas value */ c->cas = 0; dispatch_bin_command(c); c->rbytes -= sizeof(c->binary_header); c->rcurr += sizeof(c->binary_header); } } else { char *el, *cont; if (c->rbytes == 0) return 0; el = memchr(c->rcurr, '\n', c->rbytes); if (!el) { if (c->rbytes > 1024) { /* * We didn't have a '\n' in the first k. This _has_ to be a * large multiget, if not we should just nuke the connection. */ char *ptr = c->rcurr; while (*ptr == ' ') { /* ignore leading whitespaces */ ++ptr; } if (ptr - c->rcurr > 100 || (strncmp(ptr, "get ", 4) && strncmp(ptr, "gets ", 5))) { conn_set_state(c, conn_closing); return 1; } } return 0; } cont = el + 1; if ((el - c->rcurr) > 1 && *(el - 1) == '\r') { el--; } *el = '\0'; assert(cont <= (c->rcurr + c->rbytes)); process_command(c, c->rcurr); c->rbytes -= (cont - c->rcurr); c->rcurr = cont; assert(c->rcurr <= (c->rbuf + c->rsize)); } return 1; } /* * read a UDP request. */ static enum try_read_result try_read_udp(conn *c) { int res; assert(c != NULL); c->request_addr_size = sizeof(c->request_addr); res = recvfrom(c->sfd, c->rbuf, c->rsize, 0, &c->request_addr, &c->request_addr_size); if (res > 8) { unsigned char *buf = (unsigned char *)c->rbuf; pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.bytes_read += res; pthread_mutex_unlock(&c->thread->stats.mutex); /* Beginning of UDP packet is the request ID; save it. */ c->request_id = buf[0] * 256 + buf[1]; /* If this is a multi-packet request, drop it. */ if (buf[4] != 0 || buf[5] != 1) { out_string(c, "SERVER_ERROR multi-packet request not supported"); return READ_NO_DATA_RECEIVED; } /* Don't care about any of the rest of the header. */ res -= 8; memmove(c->rbuf, c->rbuf + 8, res); c->rbytes = res; c->rcurr = c->rbuf; return READ_DATA_RECEIVED; } return READ_NO_DATA_RECEIVED; } /* * read from network as much as we can, handle buffer overflow and connection * close. * before reading, move the remaining incomplete fragment of a command * (if any) to the beginning of the buffer. * * To protect us from someone flooding a connection with bogus data causing * the connection to eat up all available memory, break out and start looking * at the data I've got after a number of reallocs... * * @return enum try_read_result */ static enum try_read_result try_read_network(conn *c) { enum try_read_result gotdata = READ_NO_DATA_RECEIVED; int res; int num_allocs = 0; assert(c != NULL); if (c->rcurr != c->rbuf) { if (c->rbytes != 0) /* otherwise there's nothing to copy */ memmove(c->rbuf, c->rcurr, c->rbytes); c->rcurr = c->rbuf; } while (1) { if (c->rbytes >= c->rsize) { if (num_allocs == 4) { return gotdata; } ++num_allocs; char *new_rbuf = realloc(c->rbuf, c->rsize * 2); if (!new_rbuf) { if (settings.verbose > 0) fprintf(stderr, "Couldn't realloc input buffer\n"); c->rbytes = 0; /* ignore what we read */ out_string(c, "SERVER_ERROR out of memory reading request"); c->write_and_go = conn_closing; return READ_MEMORY_ERROR; } c->rcurr = c->rbuf = new_rbuf; c->rsize *= 2; } int avail = c->rsize - c->rbytes; res = read(c->sfd, c->rbuf + c->rbytes, avail); if (res > 0) { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.bytes_read += res; pthread_mutex_unlock(&c->thread->stats.mutex); gotdata = READ_DATA_RECEIVED; c->rbytes += res; if (res == avail) { continue; } else { break; } } if (res == 0) { return READ_ERROR; } if (res == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { break; } return READ_ERROR; } } return gotdata; } static bool update_event(conn *c, const int new_flags) { assert(c != NULL); struct event_base *base = c->event.ev_base; if (c->ev_flags == new_flags) return true; if (event_del(&c->event) == -1) return false; event_set(&c->event, c->sfd, new_flags, event_handler, (void *)c); event_base_set(base, &c->event); c->ev_flags = new_flags; if (event_add(&c->event, 0) == -1) return false; return true; } /* * Sets whether we are listening for new connections or not. */ void do_accept_new_conns(const bool do_accept) { conn *next; for (next = listen_conn; next; next = next->next) { if (do_accept) { update_event(next, EV_READ | EV_PERSIST); if (listen(next->sfd, settings.backlog) != 0) { perror("listen"); } } else { update_event(next, 0); if (listen(next->sfd, 0) != 0) { perror("listen"); } } } if (do_accept) { STATS_LOCK(); stats.accepting_conns = true; STATS_UNLOCK(); } else { STATS_LOCK(); stats.accepting_conns = false; stats.listen_disabled_num++; STATS_UNLOCK(); allow_new_conns = false; maxconns_handler(-42, 0, 0); } } /* * Transmit the next chunk of data from our list of msgbuf structures. * * Returns: * TRANSMIT_COMPLETE All done writing. * TRANSMIT_INCOMPLETE More data remaining to write. * TRANSMIT_SOFT_ERROR Can't write any more right now. * TRANSMIT_HARD_ERROR Can't write (c->state is set to conn_closing) */ static enum transmit_result transmit(conn *c) { assert(c != NULL); if (c->msgcurr < c->msgused && c->msglist[c->msgcurr].msg_iovlen == 0) { /* Finished writing the current msg; advance to the next. */ c->msgcurr++; } if (c->msgcurr < c->msgused) { ssize_t res; struct msghdr *m = &c->msglist[c->msgcurr]; res = sendmsg(c->sfd, m, 0); if (res > 0) { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.bytes_written += res; pthread_mutex_unlock(&c->thread->stats.mutex); /* We've written some of the data. Remove the completed iovec entries from the list of pending writes. */ while (m->msg_iovlen > 0 && res >= m->msg_iov->iov_len) { res -= m->msg_iov->iov_len; m->msg_iovlen--; m->msg_iov++; } /* Might have written just part of the last iovec entry; adjust it so the next write will do the rest. */ if (res > 0) { m->msg_iov->iov_base = (caddr_t)m->msg_iov->iov_base + res; m->msg_iov->iov_len -= res; } return TRANSMIT_INCOMPLETE; } if (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { if (!update_event(c, EV_WRITE | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); return TRANSMIT_HARD_ERROR; } return TRANSMIT_SOFT_ERROR; } /* if res == 0 or res == -1 and error is not EAGAIN or EWOULDBLOCK, we have a real error, on which we close the connection */ if (settings.verbose > 0) perror("Failed to write, and not due to blocking"); if (IS_UDP(c->transport)) conn_set_state(c, conn_read); else conn_set_state(c, conn_closing); return TRANSMIT_HARD_ERROR; } else { return TRANSMIT_COMPLETE; } } static void drive_machine(conn *c) { bool stop = false; int sfd, flags = 1; socklen_t addrlen; struct sockaddr_storage addr; int nreqs = settings.reqs_per_event; int res; const char *str; assert(c != NULL); while (!stop) { switch(c->state) { case conn_listening: addrlen = sizeof(addr); if ((sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen)) == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { /* these are transient, so don't log anything */ stop = true; } else if (errno == EMFILE) { if (settings.verbose > 0) fprintf(stderr, "Too many open connections\n"); accept_new_conns(false); stop = true; } else { perror("accept()"); stop = true; } break; } if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("setting O_NONBLOCK"); close(sfd); break; } if (settings.maxconns_fast && stats.curr_conns + stats.reserved_fds >= settings.maxconns - 1) { str = "ERROR Too many open connections\r\n"; res = write(sfd, str, strlen(str)); close(sfd); STATS_LOCK(); stats.rejected_conns++; STATS_UNLOCK(); } else { dispatch_conn_new(sfd, conn_new_cmd, EV_READ | EV_PERSIST, DATA_BUFFER_SIZE, tcp_transport); } stop = true; break; case conn_waiting: if (!update_event(c, EV_READ | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); break; } conn_set_state(c, conn_read); stop = true; break; case conn_read: res = IS_UDP(c->transport) ? try_read_udp(c) : try_read_network(c); switch (res) { case READ_NO_DATA_RECEIVED: conn_set_state(c, conn_waiting); break; case READ_DATA_RECEIVED: conn_set_state(c, conn_parse_cmd); break; case READ_ERROR: conn_set_state(c, conn_closing); break; case READ_MEMORY_ERROR: /* Failed to allocate more memory */ /* State already set by try_read_network */ break; } break; case conn_parse_cmd : if (try_read_command(c) == 0) { /* wee need more data! */ conn_set_state(c, conn_waiting); } break; case conn_new_cmd: /* Only process nreqs at a time to avoid starving other connections */ --nreqs; if (nreqs >= 0) { reset_cmd_handler(c); } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.conn_yields++; pthread_mutex_unlock(&c->thread->stats.mutex); if (c->rbytes > 0) { /* We have already read in data into the input buffer, so libevent will most likely not signal read events on the socket (unless more data is available. As a hack we should just put in a request to write data, because that should be possible ;-) */ if (!update_event(c, EV_WRITE | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); } } stop = true; } break; case conn_nread: if (c->rlbytes == 0) { complete_nread(c); break; } /* first check if we have leftovers in the conn_read buffer */ if (c->rbytes > 0) { int tocopy = c->rbytes > c->rlbytes ? c->rlbytes : c->rbytes; if (c->ritem != c->rcurr) { memmove(c->ritem, c->rcurr, tocopy); } c->ritem += tocopy; c->rlbytes -= tocopy; c->rcurr += tocopy; c->rbytes -= tocopy; if (c->rlbytes == 0) { break; } } /* now try reading from the socket */ res = read(c->sfd, c->ritem, c->rlbytes); if (res > 0) { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.bytes_read += res; pthread_mutex_unlock(&c->thread->stats.mutex); if (c->rcurr == c->ritem) { c->rcurr += res; } c->ritem += res; c->rlbytes -= res; break; } if (res == 0) { /* end of stream */ conn_set_state(c, conn_closing); break; } if (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { if (!update_event(c, EV_READ | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); break; } stop = true; break; } /* otherwise we have a real error, on which we close the connection */ if (settings.verbose > 0) { fprintf(stderr, "Failed to read, and not due to blocking:\n" "errno: %d %s \n" "rcurr=%lx ritem=%lx rbuf=%lx rlbytes=%d rsize=%d\n", errno, strerror(errno), (long)c->rcurr, (long)c->ritem, (long)c->rbuf, (int)c->rlbytes, (int)c->rsize); } conn_set_state(c, conn_closing); break; case conn_swallow: /* we are reading sbytes and throwing them away */ if (c->sbytes == 0) { conn_set_state(c, conn_new_cmd); break; } /* first check if we have leftovers in the conn_read buffer */ if (c->rbytes > 0) { int tocopy = c->rbytes > c->sbytes ? c->sbytes : c->rbytes; c->sbytes -= tocopy; c->rcurr += tocopy; c->rbytes -= tocopy; break; } /* now try reading from the socket */ res = read(c->sfd, c->rbuf, c->rsize > c->sbytes ? c->sbytes : c->rsize); if (res > 0) { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.bytes_read += res; pthread_mutex_unlock(&c->thread->stats.mutex); c->sbytes -= res; break; } if (res == 0) { /* end of stream */ conn_set_state(c, conn_closing); break; } if (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { if (!update_event(c, EV_READ | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); break; } stop = true; break; } /* otherwise we have a real error, on which we close the connection */ if (settings.verbose > 0) fprintf(stderr, "Failed to read, and not due to blocking\n"); conn_set_state(c, conn_closing); break; case conn_write: /* * We want to write out a simple response. If we haven't already, * assemble it into a msgbuf list (this will be a single-entry * list for TCP or a two-entry list for UDP). */ if (c->iovused == 0 || (IS_UDP(c->transport) && c->iovused == 1)) { if (add_iov(c, c->wcurr, c->wbytes) != 0) { if (settings.verbose > 0) fprintf(stderr, "Couldn't build response\n"); conn_set_state(c, conn_closing); break; } } /* fall through... */ case conn_mwrite: if (IS_UDP(c->transport) && c->msgcurr == 0 && build_udp_headers(c) != 0) { if (settings.verbose > 0) fprintf(stderr, "Failed to build UDP headers\n"); conn_set_state(c, conn_closing); break; } switch (transmit(c)) { case TRANSMIT_COMPLETE: if (c->state == conn_mwrite) { while (c->ileft > 0) { item *it = *(c->icurr); assert((it->it_flags & ITEM_SLABBED) == 0); item_remove(it); c->icurr++; c->ileft--; } while (c->suffixleft > 0) { char *suffix = *(c->suffixcurr); cache_free(c->thread->suffix_cache, suffix); c->suffixcurr++; c->suffixleft--; } /* XXX: I don't know why this wasn't the general case */ if(c->protocol == binary_prot) { conn_set_state(c, c->write_and_go); } else { conn_set_state(c, conn_new_cmd); } } else if (c->state == conn_write) { if (c->write_and_free) { free(c->write_and_free); c->write_and_free = 0; } conn_set_state(c, c->write_and_go); } else { if (settings.verbose > 0) fprintf(stderr, "Unexpected state %d\n", c->state); conn_set_state(c, conn_closing); } break; case TRANSMIT_INCOMPLETE: case TRANSMIT_HARD_ERROR: break; /* Continue in state machine. */ case TRANSMIT_SOFT_ERROR: stop = true; break; } break; case conn_closing: if (IS_UDP(c->transport)) conn_cleanup(c); else conn_close(c); stop = true; break; case conn_max_state: assert(false); break; } } return; } void event_handler(const int fd, const short which, void *arg) { conn *c; c = (conn *)arg; assert(c != NULL); c->which = which; /* sanity */ if (fd != c->sfd) { if (settings.verbose > 0) fprintf(stderr, "Catastrophic: event fd doesn't match conn fd!\n"); conn_close(c); return; } drive_machine(c); /* wait for next event */ return; } static int new_socket(struct addrinfo *ai) { int sfd; int flags; if ((sfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) { return -1; } if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("setting O_NONBLOCK"); close(sfd); return -1; } return sfd; } /* * Sets a socket's send buffer size to the maximum allowed by the system. */ static void maximize_sndbuf(const int sfd) { socklen_t intsize = sizeof(int); int last_good = 0; int min, max, avg; int old_size; /* Start with the default size. */ if (getsockopt(sfd, SOL_SOCKET, SO_SNDBUF, &old_size, &intsize) != 0) { if (settings.verbose > 0) perror("getsockopt(SO_SNDBUF)"); return; } /* Binary-search for the real maximum. */ min = old_size; max = MAX_SENDBUF_SIZE; while (min <= max) { avg = ((unsigned int)(min + max)) / 2; if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void *)&avg, intsize) == 0) { last_good = avg; min = avg + 1; } else { max = avg - 1; } } if (settings.verbose > 1) fprintf(stderr, "<%d send buffer was %d, now %d\n", sfd, old_size, last_good); } /** * Create a socket and bind it to a specific port number * @param interface the interface to bind to * @param port the port number to bind to * @param transport the transport protocol (TCP / UDP) * @param portnumber_file A filepointer to write the port numbers to * when they are successfully added to the list of ports we * listen on. */ static int server_socket(const char *interface, int port, enum network_transport transport, FILE *portnumber_file) { int sfd; struct linger ling = {0, 0}; struct addrinfo *ai; struct addrinfo *next; struct addrinfo hints = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC }; char port_buf[NI_MAXSERV]; int error; int success = 0; int flags =1; hints.ai_socktype = IS_UDP(transport) ? SOCK_DGRAM : SOCK_STREAM; if (port == -1) { port = 0; } snprintf(port_buf, sizeof(port_buf), "%d", port); error= getaddrinfo(interface, port_buf, &hints, &ai); if (error != 0) { if (error != EAI_SYSTEM) fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error)); else perror("getaddrinfo()"); return 1; } for (next= ai; next; next= next->ai_next) { conn *listen_conn_add; if ((sfd = new_socket(next)) == -1) { /* getaddrinfo can return "junk" addresses, * we make sure at least one works before erroring. */ if (errno == EMFILE) { /* ...unless we're out of fds */ perror("server_socket"); exit(EX_OSERR); } continue; } #ifdef IPV6_V6ONLY if (next->ai_family == AF_INET6) { error = setsockopt(sfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags)); if (error != 0) { perror("setsockopt"); close(sfd); continue; } } #endif setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); if (IS_UDP(transport)) { maximize_sndbuf(sfd); } else { error = setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); if (error != 0) perror("setsockopt"); error = setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); if (error != 0) perror("setsockopt"); error = setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); if (error != 0) perror("setsockopt"); } if (bind(sfd, next->ai_addr, next->ai_addrlen) == -1) { if (errno != EADDRINUSE) { perror("bind()"); close(sfd); freeaddrinfo(ai); return 1; } close(sfd); continue; } else { success++; if (!IS_UDP(transport) && listen(sfd, settings.backlog) == -1) { perror("listen()"); close(sfd); freeaddrinfo(ai); return 1; } if (portnumber_file != NULL && (next->ai_addr->sa_family == AF_INET || next->ai_addr->sa_family == AF_INET6)) { union { struct sockaddr_in in; struct sockaddr_in6 in6; } my_sockaddr; socklen_t len = sizeof(my_sockaddr); if (getsockname(sfd, (struct sockaddr*)&my_sockaddr, &len)==0) { if (next->ai_addr->sa_family == AF_INET) { fprintf(portnumber_file, "%s INET: %u\n", IS_UDP(transport) ? "UDP" : "TCP", ntohs(my_sockaddr.in.sin_port)); } else { fprintf(portnumber_file, "%s INET6: %u\n", IS_UDP(transport) ? "UDP" : "TCP", ntohs(my_sockaddr.in6.sin6_port)); } } } } if (IS_UDP(transport)) { int c; for (c = 0; c < settings.num_threads_per_udp; c++) { /* this is guaranteed to hit all threads because we round-robin */ dispatch_conn_new(sfd, conn_read, EV_READ | EV_PERSIST, UDP_READ_BUFFER_SIZE, transport); } } else { if (!(listen_conn_add = conn_new(sfd, conn_listening, EV_READ | EV_PERSIST, 1, transport, main_base))) { fprintf(stderr, "failed to create listening connection\n"); exit(EXIT_FAILURE); } listen_conn_add->next = listen_conn; listen_conn = listen_conn_add; } } freeaddrinfo(ai); /* Return zero iff we detected no errors in starting up connections */ return success == 0; } static int server_sockets(int port, enum network_transport transport, FILE *portnumber_file) { if (settings.inter == NULL) { return server_socket(settings.inter, port, transport, portnumber_file); } else { // tokenize them and bind to each one of them.. char *b; int ret = 0; char *list = strdup(settings.inter); if (list == NULL) { fprintf(stderr, "Failed to allocate memory for parsing server interface string\n"); return 1; } for (char *p = strtok_r(list, ";,", &b); p != NULL; p = strtok_r(NULL, ";,", &b)) { int the_port = port; char *s = strchr(p, ':'); if (s != NULL) { *s = '\0'; ++s; if (!safe_strtol(s, &the_port)) { fprintf(stderr, "Invalid port number: \"%s\"", s); return 1; } } if (strcmp(p, "*") == 0) { p = NULL; } ret |= server_socket(p, the_port, transport, portnumber_file); } free(list); return ret; } } static int new_socket_unix(void) { int sfd; int flags; if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("socket()"); return -1; } if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("setting O_NONBLOCK"); close(sfd); return -1; } return sfd; } static int server_socket_unix(const char *path, int access_mask) { int sfd; struct linger ling = {0, 0}; struct sockaddr_un addr; struct stat tstat; int flags =1; int old_umask; if (!path) { return 1; } if ((sfd = new_socket_unix()) == -1) { return 1; } /* * Clean up a previous socket file if we left it around */ if (lstat(path, &tstat) == 0) { if (S_ISSOCK(tstat.st_mode)) unlink(path); } setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); /* * the memset call clears nonstandard fields in some impementations * that otherwise mess things up. */ memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); assert(strcmp(addr.sun_path, path) == 0); old_umask = umask( ~(access_mask&0777)); if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { perror("bind()"); close(sfd); umask(old_umask); return 1; } umask(old_umask); if (listen(sfd, settings.backlog) == -1) { perror("listen()"); close(sfd); return 1; } if (!(listen_conn = conn_new(sfd, conn_listening, EV_READ | EV_PERSIST, 1, local_transport, main_base))) { fprintf(stderr, "failed to create listening connection\n"); exit(EXIT_FAILURE); } return 0; } /* * We keep the current time of day in a global variable that's updated by a * timer event. This saves us a bunch of time() system calls (we really only * need to get the time once a second, whereas there can be tens of thousands * of requests a second) and allows us to use server-start-relative timestamps * rather than absolute UNIX timestamps, a space savings on systems where * sizeof(time_t) > sizeof(unsigned int). */ volatile rel_time_t current_time; static struct event clockevent; /* libevent uses a monotonic clock when available for event scheduling. Aside * from jitter, simply ticking our internal timer here is accurate enough. * Note that users who are setting explicit dates for expiration times *must* * ensure their clocks are correct before starting memcached. */ static void clock_handler(const int fd, const short which, void *arg) { struct timeval t = {.tv_sec = 1, .tv_usec = 0}; static bool initialized = false; #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) static bool monotonic = false; static time_t monotonic_start; #endif if (initialized) { /* only delete the event if it's actually there. */ evtimer_del(&clockevent); } else { initialized = true; /* process_started is initialized to time() - 2. We initialize to 1 so * flush_all won't underflow during tests. */ #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { monotonic = true; monotonic_start = ts.tv_sec - 2; } #endif } evtimer_set(&clockevent, clock_handler, 0); event_base_set(main_base, &clockevent); evtimer_add(&clockevent, &t); #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) if (monotonic) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) return; current_time = (rel_time_t) (ts.tv_sec - monotonic_start); return; } #endif { struct timeval tv; gettimeofday(&tv, NULL); current_time = (rel_time_t) (tv.tv_sec - process_started); } } static void usage(void) { printf(PACKAGE " " VERSION "\n"); printf("-p TCP port number to listen on (default: 11211)\n" "-U UDP port number to listen on (default: 11211, 0 is off)\n" "-s UNIX socket path to listen on (disables network support)\n" "-a access mask for UNIX socket, in octal (default: 0700)\n" "-l interface to listen on (default: INADDR_ANY, all addresses)\n" " may be specified as host:port. If you don't specify\n" " a port number, the value you specified with -p or -U is\n" " used. You may specify multiple addresses separated by comma\n" " or by using -l multiple times\n" "-d run as a daemon\n" "-r maximize core file limit\n" "-u assume identity of (only when run as root)\n" "-m max memory to use for items in megabytes (default: 64 MB)\n" "-M return error on memory exhausted (rather than removing items)\n" "-c max simultaneous connections (default: 1024)\n" "-k lock down all paged memory. Note that there is a\n" " limit on how much memory you may lock. Trying to\n" " allocate more than that would fail, so be sure you\n" " set the limit correctly for the user you started\n" " the daemon with (not for -u user;\n" " under sh this is done with 'ulimit -S -l NUM_KB').\n" "-v verbose (print errors/warnings while in event loop)\n" "-vv very verbose (also print client commands/reponses)\n" "-vvv extremely verbose (also print internal state transitions)\n" "-h print this help and exit\n" "-i print memcached and libevent license\n" "-P save PID in , only used with -d option\n" "-f chunk size growth factor (default: 1.25)\n" "-n minimum space allocated for key+value+flags (default: 48)\n"); printf("-L Try to use large memory pages (if available). Increasing\n" " the memory page size could reduce the number of TLB misses\n" " and improve the performance. In order to get large pages\n" " from the OS, memcached will allocate the total item-cache\n" " in one large chunk.\n"); printf("-D Use as the delimiter between key prefixes and IDs.\n" " This is used for per-prefix stats reporting. The default is\n" " \":\" (colon). If this option is specified, stats collection\n" " is turned on automatically; if not, then it may be turned on\n" " by sending the \"stats detail on\" command to the server.\n"); printf("-t number of threads to use (default: 4)\n"); printf("-R Maximum number of requests per event, limits the number of\n" " requests process for a given connection to prevent \n" " starvation (default: 20)\n"); printf("-C Disable use of CAS\n"); printf("-b Set the backlog queue limit (default: 1024)\n"); printf("-B Binding protocol - one of ascii, binary, or auto (default)\n"); printf("-I Override the size of each slab page. Adjusts max item size\n" " (default: 1mb, min: 1k, max: 128m)\n"); #ifdef ENABLE_SASL printf("-S Turn on Sasl authentication\n"); #endif printf("-o Comma separated list of extended or experimental options\n" " - (EXPERIMENTAL) maxconns_fast: immediately close new\n" " connections if over maxconns limit\n" " - hashpower: An integer multiplier for how large the hash\n" " table should be. Can be grown at runtime if not big enough.\n" " Set this based on \"STAT hash_power_level\" before a \n" " restart.\n" ); return; } static void usage_license(void) { printf(PACKAGE " " VERSION "\n\n"); printf( "Copyright (c) 2003, Danga Interactive, Inc. \n" "All rights reserved.\n" "\n" "Redistribution and use in source and binary forms, with or without\n" "modification, are permitted provided that the following conditions are\n" "met:\n" "\n" " * Redistributions of source code must retain the above copyright\n" "notice, this list of conditions and the following disclaimer.\n" "\n" " * Redistributions in binary form must reproduce the above\n" "copyright notice, this list of conditions and the following disclaimer\n" "in the documentation and/or other materials provided with the\n" "distribution.\n" "\n" " * Neither the name of the Danga Interactive nor the names of its\n" "contributors may be used to endorse or promote products derived from\n" "this software without specific prior written permission.\n" "\n" "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" "\n" "\n" "This product includes software developed by Niels Provos.\n" "\n" "[ libevent ]\n" "\n" "Copyright 2000-2003 Niels Provos \n" "All rights reserved.\n" "\n" "Redistribution and use in source and binary forms, with or without\n" "modification, are permitted provided that the following conditions\n" "are met:\n" "1. Redistributions of source code must retain the above copyright\n" " notice, this list of conditions and the following disclaimer.\n" "2. Redistributions in binary form must reproduce the above copyright\n" " notice, this list of conditions and the following disclaimer in the\n" " documentation and/or other materials provided with the distribution.\n" "3. All advertising materials mentioning features or use of this software\n" " must display the following acknowledgement:\n" " This product includes software developed by Niels Provos.\n" "4. The name of the author may not be used to endorse or promote products\n" " derived from this software without specific prior written permission.\n" "\n" "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n" "IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n" "OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n" "IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n" "INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n" "NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n" "THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" ); return; } static void save_pid(const char *pid_file) { FILE *fp; if (access(pid_file, F_OK) == 0) { if ((fp = fopen(pid_file, "r")) != NULL) { char buffer[1024]; if (fgets(buffer, sizeof(buffer), fp) != NULL) { unsigned int pid; if (safe_strtoul(buffer, &pid) && kill((pid_t)pid, 0) == 0) { fprintf(stderr, "WARNING: The pid file contained the following (running) pid: %u\n", pid); } } fclose(fp); } } if ((fp = fopen(pid_file, "w")) == NULL) { vperror("Could not open the pid file %s for writing", pid_file); return; } fprintf(fp,"%ld\n", (long)getpid()); if (fclose(fp) == -1) { vperror("Could not close the pid file %s", pid_file); } } static void remove_pidfile(const char *pid_file) { if (pid_file == NULL) return; if (unlink(pid_file) != 0) { vperror("Could not remove the pid file %s", pid_file); } } static void sig_handler(const int sig) { printf("SIGINT handled.\n"); exit(EXIT_SUCCESS); } #ifndef HAVE_SIGIGNORE static int sigignore(int sig) { struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = 0 }; if (sigemptyset(&sa.sa_mask) == -1 || sigaction(sig, &sa, 0) == -1) { return -1; } return 0; } #endif /* * On systems that supports multiple page sizes we may reduce the * number of TLB-misses by using the biggest available page size */ static int enable_large_pages(void) { #if defined(HAVE_GETPAGESIZES) && defined(HAVE_MEMCNTL) int ret = -1; size_t sizes[32]; int avail = getpagesizes(sizes, 32); if (avail != -1) { size_t max = sizes[0]; struct memcntl_mha arg = {0}; int ii; for (ii = 1; ii < avail; ++ii) { if (max < sizes[ii]) { max = sizes[ii]; } } arg.mha_flags = 0; arg.mha_pagesize = max; arg.mha_cmd = MHA_MAPSIZE_BSSBRK; if (memcntl(0, 0, MC_HAT_ADVISE, (caddr_t)&arg, 0, 0) == -1) { fprintf(stderr, "Failed to set large pages: %s\n", strerror(errno)); fprintf(stderr, "Will use default page size\n"); } else { ret = 0; } } else { fprintf(stderr, "Failed to get supported pagesizes: %s\n", strerror(errno)); fprintf(stderr, "Will use default page size\n"); } return ret; #else return -1; #endif } /** * Do basic sanity check of the runtime environment * @return true if no errors found, false if we can't use this env */ static bool sanitycheck(void) { /* One of our biggest problems is old and bogus libevents */ const char *ever = event_get_version(); if (ever != NULL) { if (strncmp(ever, "1.", 2) == 0) { /* Require at least 1.3 (that's still a couple of years old) */ if ((ever[2] == '1' || ever[2] == '2') && !isdigit(ever[3])) { fprintf(stderr, "You are using libevent %s.\nPlease upgrade to" " a more recent version (1.3 or newer)\n", event_get_version()); return false; } } } return true; } int main (int argc, char **argv) { int c; bool lock_memory = false; bool do_daemonize = false; bool preallocate = false; int maxcore = 0; char *username = NULL; char *pid_file = NULL; struct passwd *pw; struct rlimit rlim; char unit = '\0'; int size_max = 0; int retval = EXIT_SUCCESS; /* listening sockets */ static int *l_socket = NULL; /* udp socket */ static int *u_socket = NULL; bool protocol_specified = false; bool tcp_specified = false; bool udp_specified = false; char *subopts; char *subopts_value; enum { MAXCONNS_FAST = 0, HASHPOWER_INIT, SLAB_REASSIGN, SLAB_AUTOMOVE }; char *const subopts_tokens[] = { [MAXCONNS_FAST] = "maxconns_fast", [HASHPOWER_INIT] = "hashpower", [SLAB_REASSIGN] = "slab_reassign", [SLAB_AUTOMOVE] = "slab_automove", NULL }; if (!sanitycheck()) { return EX_OSERR; } /* handle SIGINT */ signal(SIGINT, sig_handler); /* init settings */ settings_init(); /* set stderr non-buffering (for running under, say, daemontools) */ setbuf(stderr, NULL); /* process arguments */ while (-1 != (c = getopt(argc, argv, "a:" /* access mask for unix socket */ "p:" /* TCP port number to listen on */ "s:" /* unix socket path to listen on */ "U:" /* UDP port number to listen on */ "m:" /* max memory to use for items in megabytes */ "M" /* return error on memory exhausted */ "c:" /* max simultaneous connections */ "k" /* lock down all paged memory */ "hi" /* help, licence info */ "r" /* maximize core file limit */ "v" /* verbose */ "d" /* daemon mode */ "l:" /* interface to listen on */ "u:" /* user identity to run as */ "P:" /* save PID in file */ "f:" /* factor? */ "n:" /* minimum space allocated for key+value+flags */ "t:" /* threads */ "D:" /* prefix delimiter? */ "L" /* Large memory pages */ "R:" /* max requests per event */ "C" /* Disable use of CAS */ "b:" /* backlog queue limit */ "B:" /* Binding protocol */ "I:" /* Max item size */ "S" /* Sasl ON */ "o:" /* Extended generic options */ ))) { switch (c) { case 'a': /* access for unix domain socket, as octal mask (like chmod)*/ settings.access= strtol(optarg,NULL,8); break; case 'U': settings.udpport = atoi(optarg); udp_specified = true; break; case 'p': settings.port = atoi(optarg); tcp_specified = true; break; case 's': settings.socketpath = optarg; break; case 'm': settings.maxbytes = ((size_t)atoi(optarg)) * 1024 * 1024; break; case 'M': settings.evict_to_free = 0; break; case 'c': settings.maxconns = atoi(optarg); break; case 'h': usage(); exit(EXIT_SUCCESS); case 'i': usage_license(); exit(EXIT_SUCCESS); case 'k': lock_memory = true; break; case 'v': settings.verbose++; break; case 'l': if (settings.inter != NULL) { size_t len = strlen(settings.inter) + strlen(optarg) + 2; char *p = malloc(len); if (p == NULL) { fprintf(stderr, "Failed to allocate memory\n"); return 1; } snprintf(p, len, "%s,%s", settings.inter, optarg); free(settings.inter); settings.inter = p; } else { settings.inter= strdup(optarg); } break; case 'd': do_daemonize = true; break; case 'r': maxcore = 1; break; case 'R': settings.reqs_per_event = atoi(optarg); if (settings.reqs_per_event == 0) { fprintf(stderr, "Number of requests per event must be greater than 0\n"); return 1; } break; case 'u': username = optarg; break; case 'P': pid_file = optarg; break; case 'f': settings.factor = atof(optarg); if (settings.factor <= 1.0) { fprintf(stderr, "Factor must be greater than 1\n"); return 1; } break; case 'n': settings.chunk_size = atoi(optarg); if (settings.chunk_size == 0) { fprintf(stderr, "Chunk size must be greater than 0\n"); return 1; } break; case 't': settings.num_threads = atoi(optarg); if (settings.num_threads <= 0) { fprintf(stderr, "Number of threads must be greater than 0\n"); return 1; } /* There're other problems when you get above 64 threads. * In the future we should portably detect # of cores for the * default. */ if (settings.num_threads > 64) { fprintf(stderr, "WARNING: Setting a high number of worker" "threads is not recommended.\n" " Set this value to the number of cores in" " your machine or less.\n"); } break; case 'D': if (! optarg || ! optarg[0]) { fprintf(stderr, "No delimiter specified\n"); return 1; } settings.prefix_delimiter = optarg[0]; settings.detail_enabled = 1; break; case 'L' : if (enable_large_pages() == 0) { preallocate = true; } else { fprintf(stderr, "Cannot enable large pages on this system\n" "(There is no Linux support as of this version)\n"); return 1; } break; case 'C' : settings.use_cas = false; break; case 'b' : settings.backlog = atoi(optarg); break; case 'B': protocol_specified = true; if (strcmp(optarg, "auto") == 0) { settings.binding_protocol = negotiating_prot; } else if (strcmp(optarg, "binary") == 0) { settings.binding_protocol = binary_prot; } else if (strcmp(optarg, "ascii") == 0) { settings.binding_protocol = ascii_prot; } else { fprintf(stderr, "Invalid value for binding protocol: %s\n" " -- should be one of auto, binary, or ascii\n", optarg); exit(EX_USAGE); } break; case 'I': unit = optarg[strlen(optarg)-1]; if (unit == 'k' || unit == 'm' || unit == 'K' || unit == 'M') { optarg[strlen(optarg)-1] = '\0'; size_max = atoi(optarg); if (unit == 'k' || unit == 'K') size_max *= 1024; if (unit == 'm' || unit == 'M') size_max *= 1024 * 1024; settings.item_size_max = size_max; } else { settings.item_size_max = atoi(optarg); } if (settings.item_size_max < 1024) { fprintf(stderr, "Item max size cannot be less than 1024 bytes.\n"); return 1; } if (settings.item_size_max > 1024 * 1024 * 128) { fprintf(stderr, "Cannot set item size limit higher than 128 mb.\n"); return 1; } if (settings.item_size_max > 1024 * 1024) { fprintf(stderr, "WARNING: Setting item max size above 1MB is not" " recommended!\n" " Raising this limit increases the minimum memory requirements\n" " and will decrease your memory efficiency.\n" ); } break; case 'S': /* set Sasl authentication to true. Default is false */ #ifndef ENABLE_SASL fprintf(stderr, "This server is not built with SASL support.\n"); exit(EX_USAGE); #endif settings.sasl = true; break; case 'o': /* It's sub-opts time! */ subopts = optarg; while (*subopts != '\0') { switch (getsubopt(&subopts, subopts_tokens, &subopts_value)) { case MAXCONNS_FAST: settings.maxconns_fast = true; break; case HASHPOWER_INIT: if (subopts_value == NULL) { fprintf(stderr, "Missing numeric argument for hashpower\n"); return 1; } settings.hashpower_init = atoi(subopts_value); if (settings.hashpower_init < 12) { fprintf(stderr, "Initial hashtable multiplier of %d is too low\n", settings.hashpower_init); return 1; } else if (settings.hashpower_init > 64) { fprintf(stderr, "Initial hashtable multiplier of %d is too high\n" "Choose a value based on \"STAT hash_power_level\" from a running instance\n", settings.hashpower_init); return 1; } break; case SLAB_REASSIGN: settings.slab_reassign = true; break; case SLAB_AUTOMOVE: if (subopts_value == NULL) { settings.slab_automove = 1; break; } settings.slab_automove = atoi(subopts_value); if (settings.slab_automove < 0 || settings.slab_automove > 2) { fprintf(stderr, "slab_automove must be between 0 and 2\n"); return 1; } break; default: printf("Illegal suboption \"%s\"\n", subopts_value); return 1; } } break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } /* * Use one workerthread to serve each UDP port if the user specified * multiple ports */ if (settings.inter != NULL && strchr(settings.inter, ',')) { settings.num_threads_per_udp = 1; } else { settings.num_threads_per_udp = settings.num_threads; } if (settings.sasl) { if (!protocol_specified) { settings.binding_protocol = binary_prot; } else { if (settings.binding_protocol != binary_prot) { fprintf(stderr, "ERROR: You cannot allow the ASCII protocol while using SASL.\n"); exit(EX_USAGE); } } } if (tcp_specified && !udp_specified) { settings.udpport = settings.port; } else if (udp_specified && !tcp_specified) { settings.port = settings.udpport; } if (maxcore != 0) { struct rlimit rlim_new; /* * First try raising to infinity; if that fails, try bringing * the soft limit to the hard. */ if (getrlimit(RLIMIT_CORE, &rlim) == 0) { rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rlim_new)!= 0) { /* failed. try raising just to the old max */ rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max; (void)setrlimit(RLIMIT_CORE, &rlim_new); } } /* * getrlimit again to see what we ended up with. Only fail if * the soft limit ends up 0, because then no core files will be * created at all. */ if ((getrlimit(RLIMIT_CORE, &rlim) != 0) || rlim.rlim_cur == 0) { fprintf(stderr, "failed to ensure corefile creation\n"); exit(EX_OSERR); } } /* * If needed, increase rlimits to allow as many connections * as needed. */ if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to getrlimit number of files\n"); exit(EX_OSERR); } else { rlim.rlim_cur = settings.maxconns; rlim.rlim_max = settings.maxconns; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to set rlimit for open files. Try starting as root or requesting smaller maxconns value.\n"); exit(EX_OSERR); } } /* lose root privileges if we have them */ if (getuid() == 0 || geteuid() == 0) { if (username == 0 || *username == '\0') { fprintf(stderr, "can't run as root without the -u switch\n"); exit(EX_USAGE); } if ((pw = getpwnam(username)) == 0) { fprintf(stderr, "can't find the user %s to switch to\n", username); exit(EX_NOUSER); } if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) { fprintf(stderr, "failed to assume identity of user %s\n", username); exit(EX_OSERR); } } /* Initialize Sasl if -S was specified */ if (settings.sasl) { init_sasl(); } /* daemonize if requested */ /* if we want to ensure our ability to dump core, don't chdir to / */ if (do_daemonize) { if (sigignore(SIGHUP) == -1) { perror("Failed to ignore SIGHUP"); } if (daemonize(maxcore, settings.verbose) == -1) { fprintf(stderr, "failed to daemon() in order to daemonize\n"); exit(EXIT_FAILURE); } } /* lock paged memory if needed */ if (lock_memory) { #ifdef HAVE_MLOCKALL int res = mlockall(MCL_CURRENT | MCL_FUTURE); if (res != 0) { fprintf(stderr, "warning: -k invalid, mlockall() failed: %s\n", strerror(errno)); } #else fprintf(stderr, "warning: -k invalid, mlockall() not supported on this platform. proceeding without.\n"); #endif } /* initialize main thread libevent instance */ main_base = event_init(); /* initialize other stuff */ stats_init(); assoc_init(settings.hashpower_init); conn_init(); slabs_init(settings.maxbytes, settings.factor, preallocate); /* * ignore SIGPIPE signals; we can use errno == EPIPE if we * need that information */ if (sigignore(SIGPIPE) == -1) { perror("failed to ignore SIGPIPE; sigaction"); exit(EX_OSERR); } /* start up worker threads if MT mode */ thread_init(settings.num_threads, main_base); if (start_assoc_maintenance_thread() == -1) { exit(EXIT_FAILURE); } if (settings.slab_reassign && start_slab_maintenance_thread() == -1) { exit(EXIT_FAILURE); } /* initialise clock event */ clock_handler(0, 0, 0); /* create unix mode sockets after dropping privileges */ if (settings.socketpath != NULL) { errno = 0; if (server_socket_unix(settings.socketpath,settings.access)) { vperror("failed to listen on UNIX socket: %s", settings.socketpath); exit(EX_OSERR); } } /* create the listening socket, bind it, and init */ if (settings.socketpath == NULL) { const char *portnumber_filename = getenv("MEMCACHED_PORT_FILENAME"); char temp_portnumber_filename[PATH_MAX]; FILE *portnumber_file = NULL; if (portnumber_filename != NULL) { snprintf(temp_portnumber_filename, sizeof(temp_portnumber_filename), "%s.lck", portnumber_filename); portnumber_file = fopen(temp_portnumber_filename, "a"); if (portnumber_file == NULL) { fprintf(stderr, "Failed to open \"%s\": %s\n", temp_portnumber_filename, strerror(errno)); } } errno = 0; if (settings.port && server_sockets(settings.port, tcp_transport, portnumber_file)) { vperror("failed to listen on TCP port %d", settings.port); exit(EX_OSERR); } /* * initialization order: first create the listening sockets * (may need root on low ports), then drop root if needed, * then daemonise if needed, then init libevent (in some cases * descriptors created by libevent wouldn't survive forking). */ /* create the UDP listening socket and bind it */ errno = 0; if (settings.udpport && server_sockets(settings.udpport, udp_transport, portnumber_file)) { vperror("failed to listen on UDP port %d", settings.udpport); exit(EX_OSERR); } if (portnumber_file) { fclose(portnumber_file); rename(temp_portnumber_filename, portnumber_filename); } } /* Give the sockets a moment to open. I know this is dumb, but the error * is only an advisory. */ usleep(1000); if (stats.curr_conns + stats.reserved_fds >= settings.maxconns - 1) { fprintf(stderr, "Maxconns setting is too low, use -c to increase.\n"); exit(EXIT_FAILURE); } if (pid_file != NULL) { save_pid(pid_file); } /* Drop privileges no longer needed */ drop_privileges(); /* enter the event loop */ if (event_base_loop(main_base, 0) != 0) { retval = EXIT_FAILURE; } stop_assoc_maintenance_thread(); /* remove the PID file if we're a daemon */ if (do_daemonize) remove_pidfile(pid_file); /* Clean up strdup() call for bind() address */ if (settings.inter) free(settings.inter); if (l_socket) free(l_socket); if (u_socket) free(u_socket); return retval; } memcached-1.4.14/version.m40000644000175000017500000000004612005572430012355 00000000000000m4_define([VERSION_NUMBER], [1.4.14]) memcached-1.4.14/items.c0000644000175000017500000004526512005566511011732 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "memcached.h" #include #include #include #include #include #include #include #include #include #include #include #include /* Forward Declarations */ static void item_link_q(item *it); static void item_unlink_q(item *it); /* * We only reposition items in the LRU queue if they haven't been repositioned * in this many seconds. That saves us from churning on frequently-accessed * items. */ #define ITEM_UPDATE_INTERVAL 60 #define LARGEST_ID POWER_LARGEST typedef struct { uint64_t evicted; uint64_t evicted_nonzero; rel_time_t evicted_time; uint64_t reclaimed; uint64_t outofmemory; uint64_t tailrepairs; uint64_t expired_unfetched; uint64_t evicted_unfetched; } itemstats_t; static item *heads[LARGEST_ID]; static item *tails[LARGEST_ID]; static itemstats_t itemstats[LARGEST_ID]; static unsigned int sizes[LARGEST_ID]; void item_stats_reset(void) { mutex_lock(&cache_lock); memset(itemstats, 0, sizeof(itemstats)); mutex_unlock(&cache_lock); } /* Get the next CAS id for a new item. */ uint64_t get_cas_id(void) { static uint64_t cas_id = 0; return ++cas_id; } /* Enable this for reference-count debugging. */ #if 0 # define DEBUG_REFCNT(it,op) \ fprintf(stderr, "item %x refcnt(%c) %d %c%c%c\n", \ it, op, it->refcount, \ (it->it_flags & ITEM_LINKED) ? 'L' : ' ', \ (it->it_flags & ITEM_SLABBED) ? 'S' : ' ') #else # define DEBUG_REFCNT(it,op) while(0) #endif /** * Generates the variable-sized part of the header for an object. * * key - The key * nkey - The length of the key * flags - key flags * nbytes - Number of bytes to hold value and addition CRLF terminator * suffix - Buffer for the "VALUE" line suffix (flags, size). * nsuffix - The length of the suffix is stored here. * * Returns the total size of the header. */ static size_t item_make_header(const uint8_t nkey, const int flags, const int nbytes, char *suffix, uint8_t *nsuffix) { /* suffix is defined at 40 chars elsewhere.. */ *nsuffix = (uint8_t) snprintf(suffix, 40, " %d %d\r\n", flags, nbytes - 2); return sizeof(item) + nkey + *nsuffix + nbytes; } /*@null@*/ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes) { uint8_t nsuffix; item *it = NULL; char suffix[40]; size_t ntotal = item_make_header(nkey + 1, flags, nbytes, suffix, &nsuffix); if (settings.use_cas) { ntotal += sizeof(uint64_t); } unsigned int id = slabs_clsid(ntotal); if (id == 0) return 0; mutex_lock(&cache_lock); /* do a quick check if we have any expired items in the tail.. */ item *search; rel_time_t oldest_live = settings.oldest_live; search = tails[id]; if (search != NULL && (refcount_incr(&search->refcount) == 2)) { if ((search->exptime != 0 && search->exptime < current_time) || (search->time <= oldest_live && oldest_live <= current_time)) { // dead by flush STATS_LOCK(); stats.reclaimed++; STATS_UNLOCK(); itemstats[id].reclaimed++; if ((search->it_flags & ITEM_FETCHED) == 0) { STATS_LOCK(); stats.expired_unfetched++; STATS_UNLOCK(); itemstats[id].expired_unfetched++; } it = search; slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); /* Initialize the item block: */ it->slabs_clsid = 0; } else if ((it = slabs_alloc(ntotal, id)) == NULL) { if (settings.evict_to_free == 0) { itemstats[id].outofmemory++; mutex_unlock(&cache_lock); return NULL; } itemstats[id].evicted++; itemstats[id].evicted_time = current_time - search->time; if (search->exptime != 0) itemstats[id].evicted_nonzero++; if ((search->it_flags & ITEM_FETCHED) == 0) { STATS_LOCK(); stats.evicted_unfetched++; STATS_UNLOCK(); itemstats[id].evicted_unfetched++; } STATS_LOCK(); stats.evictions++; STATS_UNLOCK(); it = search; slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); /* Initialize the item block: */ it->slabs_clsid = 0; /* If we've just evicted an item, and the automover is set to * angry bird mode, attempt to rip memory into this slab class. * TODO: Move valid object detection into a function, and on a * "successful" memory pull, look behind and see if the next alloc * would be an eviction. Then kick off the slab mover before the * eviction happens. */ if (settings.slab_automove == 2) slabs_reassign(-1, id); } else { refcount_decr(&search->refcount); } } else { /* If the LRU is empty or locked, attempt to allocate memory */ it = slabs_alloc(ntotal, id); if (search != NULL) refcount_decr(&search->refcount); } if (it == NULL) { itemstats[id].outofmemory++; /* Last ditch effort. There was a very rare bug which caused * refcount leaks. We leave this just in case they ever happen again. * We can reasonably assume no item can stay locked for more than * three hours, so if we find one in the tail which is that old, * free it anyway. */ if (search != NULL && search->refcount != 2 && search->time + TAIL_REPAIR_TIME < current_time) { itemstats[id].tailrepairs++; search->refcount = 1; do_item_unlink_nolock(search, hash(ITEM_key(search), search->nkey, 0)); } mutex_unlock(&cache_lock); return NULL; } assert(it->slabs_clsid == 0); assert(it != heads[id]); /* Item initialization can happen outside of the lock; the item's already * been removed from the slab LRU. */ it->refcount = 1; /* the caller will have a reference */ mutex_unlock(&cache_lock); it->next = it->prev = it->h_next = 0; it->slabs_clsid = id; DEBUG_REFCNT(it, '*'); it->it_flags = settings.use_cas ? ITEM_CAS : 0; it->nkey = nkey; it->nbytes = nbytes; memcpy(ITEM_key(it), key, nkey); it->exptime = exptime; memcpy(ITEM_suffix(it), suffix, (size_t)nsuffix); it->nsuffix = nsuffix; return it; } void item_free(item *it) { size_t ntotal = ITEM_ntotal(it); unsigned int clsid; assert((it->it_flags & ITEM_LINKED) == 0); assert(it != heads[it->slabs_clsid]); assert(it != tails[it->slabs_clsid]); assert(it->refcount == 0); /* so slab size changer can tell later if item is already free or not */ clsid = it->slabs_clsid; it->slabs_clsid = 0; DEBUG_REFCNT(it, 'F'); slabs_free(it, ntotal, clsid); } /** * Returns true if an item will fit in the cache (its size does not exceed * the maximum for a cache entry.) */ bool item_size_ok(const size_t nkey, const int flags, const int nbytes) { char prefix[40]; uint8_t nsuffix; size_t ntotal = item_make_header(nkey + 1, flags, nbytes, prefix, &nsuffix); if (settings.use_cas) { ntotal += sizeof(uint64_t); } return slabs_clsid(ntotal) != 0; } static void item_link_q(item *it) { /* item is the new head */ item **head, **tail; assert(it->slabs_clsid < LARGEST_ID); assert((it->it_flags & ITEM_SLABBED) == 0); head = &heads[it->slabs_clsid]; tail = &tails[it->slabs_clsid]; assert(it != *head); assert((*head && *tail) || (*head == 0 && *tail == 0)); it->prev = 0; it->next = *head; if (it->next) it->next->prev = it; *head = it; if (*tail == 0) *tail = it; sizes[it->slabs_clsid]++; return; } static void item_unlink_q(item *it) { item **head, **tail; assert(it->slabs_clsid < LARGEST_ID); head = &heads[it->slabs_clsid]; tail = &tails[it->slabs_clsid]; if (*head == it) { assert(it->prev == 0); *head = it->next; } if (*tail == it) { assert(it->next == 0); *tail = it->prev; } assert(it->next != it); assert(it->prev != it); if (it->next) it->next->prev = it->prev; if (it->prev) it->prev->next = it->next; sizes[it->slabs_clsid]--; return; } int do_item_link(item *it, const uint32_t hv) { MEMCACHED_ITEM_LINK(ITEM_key(it), it->nkey, it->nbytes); assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0); mutex_lock(&cache_lock); it->it_flags |= ITEM_LINKED; it->time = current_time; STATS_LOCK(); stats.curr_bytes += ITEM_ntotal(it); stats.curr_items += 1; stats.total_items += 1; STATS_UNLOCK(); /* Allocate a new CAS ID on link. */ ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0); assoc_insert(it, hv); item_link_q(it); refcount_incr(&it->refcount); mutex_unlock(&cache_lock); return 1; } void do_item_unlink(item *it, const uint32_t hv) { MEMCACHED_ITEM_UNLINK(ITEM_key(it), it->nkey, it->nbytes); mutex_lock(&cache_lock); if ((it->it_flags & ITEM_LINKED) != 0) { it->it_flags &= ~ITEM_LINKED; STATS_LOCK(); stats.curr_bytes -= ITEM_ntotal(it); stats.curr_items -= 1; STATS_UNLOCK(); assoc_delete(ITEM_key(it), it->nkey, hv); item_unlink_q(it); do_item_remove(it); } mutex_unlock(&cache_lock); } /* FIXME: Is it necessary to keep this copy/pasted code? */ void do_item_unlink_nolock(item *it, const uint32_t hv) { MEMCACHED_ITEM_UNLINK(ITEM_key(it), it->nkey, it->nbytes); if ((it->it_flags & ITEM_LINKED) != 0) { it->it_flags &= ~ITEM_LINKED; STATS_LOCK(); stats.curr_bytes -= ITEM_ntotal(it); stats.curr_items -= 1; STATS_UNLOCK(); assoc_delete(ITEM_key(it), it->nkey, hv); item_unlink_q(it); do_item_remove(it); } } void do_item_remove(item *it) { MEMCACHED_ITEM_REMOVE(ITEM_key(it), it->nkey, it->nbytes); assert((it->it_flags & ITEM_SLABBED) == 0); if (refcount_decr(&it->refcount) == 0) { item_free(it); } } void do_item_update(item *it) { MEMCACHED_ITEM_UPDATE(ITEM_key(it), it->nkey, it->nbytes); if (it->time < current_time - ITEM_UPDATE_INTERVAL) { assert((it->it_flags & ITEM_SLABBED) == 0); mutex_lock(&cache_lock); if ((it->it_flags & ITEM_LINKED) != 0) { item_unlink_q(it); it->time = current_time; item_link_q(it); } mutex_unlock(&cache_lock); } } int do_item_replace(item *it, item *new_it, const uint32_t hv) { MEMCACHED_ITEM_REPLACE(ITEM_key(it), it->nkey, it->nbytes, ITEM_key(new_it), new_it->nkey, new_it->nbytes); assert((it->it_flags & ITEM_SLABBED) == 0); do_item_unlink(it, hv); return do_item_link(new_it, hv); } /*@null@*/ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes) { unsigned int memlimit = 2 * 1024 * 1024; /* 2MB max response size */ char *buffer; unsigned int bufcurr; item *it; unsigned int len; unsigned int shown = 0; char key_temp[KEY_MAX_LENGTH + 1]; char temp[512]; it = heads[slabs_clsid]; buffer = malloc((size_t)memlimit); if (buffer == 0) return NULL; bufcurr = 0; while (it != NULL && (limit == 0 || shown < limit)) { assert(it->nkey <= KEY_MAX_LENGTH); /* Copy the key since it may not be null-terminated in the struct */ strncpy(key_temp, ITEM_key(it), it->nkey); key_temp[it->nkey] = 0x00; /* terminate */ len = snprintf(temp, sizeof(temp), "ITEM %s [%d b; %lu s]\r\n", key_temp, it->nbytes - 2, (unsigned long)it->exptime + process_started); if (bufcurr + len + 6 > memlimit) /* 6 is END\r\n\0 */ break; memcpy(buffer + bufcurr, temp, len); bufcurr += len; shown++; it = it->next; } memcpy(buffer + bufcurr, "END\r\n", 6); bufcurr += 5; *bytes = bufcurr; return buffer; } void item_stats_evictions(uint64_t *evicted) { int i; mutex_lock(&cache_lock); for (i = 0; i < LARGEST_ID; i++) { evicted[i] = itemstats[i].evicted; } mutex_unlock(&cache_lock); } void do_item_stats(ADD_STAT add_stats, void *c) { int i; for (i = 0; i < LARGEST_ID; i++) { if (tails[i] != NULL) { const char *fmt = "items:%d:%s"; char key_str[STAT_KEY_LEN]; char val_str[STAT_VAL_LEN]; int klen = 0, vlen = 0; if (tails[i] == NULL) { /* We removed all of the items in this slab class */ continue; } APPEND_NUM_FMT_STAT(fmt, i, "number", "%u", sizes[i]); APPEND_NUM_FMT_STAT(fmt, i, "age", "%u", current_time - tails[i]->time); APPEND_NUM_FMT_STAT(fmt, i, "evicted", "%llu", (unsigned long long)itemstats[i].evicted); APPEND_NUM_FMT_STAT(fmt, i, "evicted_nonzero", "%llu", (unsigned long long)itemstats[i].evicted_nonzero); APPEND_NUM_FMT_STAT(fmt, i, "evicted_time", "%u", itemstats[i].evicted_time); APPEND_NUM_FMT_STAT(fmt, i, "outofmemory", "%llu", (unsigned long long)itemstats[i].outofmemory); APPEND_NUM_FMT_STAT(fmt, i, "tailrepairs", "%llu", (unsigned long long)itemstats[i].tailrepairs); APPEND_NUM_FMT_STAT(fmt, i, "reclaimed", "%llu", (unsigned long long)itemstats[i].reclaimed); APPEND_NUM_FMT_STAT(fmt, i, "expired_unfetched", "%llu", (unsigned long long)itemstats[i].expired_unfetched); APPEND_NUM_FMT_STAT(fmt, i, "evicted_unfetched", "%llu", (unsigned long long)itemstats[i].evicted_unfetched); } } /* getting here means both ascii and binary terminators fit */ add_stats(NULL, 0, NULL, 0, c); } /** dumps out a list of objects of each size, with granularity of 32 bytes */ /*@null@*/ void do_item_stats_sizes(ADD_STAT add_stats, void *c) { /* max 1MB object, divided into 32 bytes size buckets */ const int num_buckets = 32768; unsigned int *histogram = calloc(num_buckets, sizeof(int)); if (histogram != NULL) { int i; /* build the histogram */ for (i = 0; i < LARGEST_ID; i++) { item *iter = heads[i]; while (iter) { int ntotal = ITEM_ntotal(iter); int bucket = ntotal / 32; if ((ntotal % 32) != 0) bucket++; if (bucket < num_buckets) histogram[bucket]++; iter = iter->next; } } /* write the buffer */ for (i = 0; i < num_buckets; i++) { if (histogram[i] != 0) { char key[8]; snprintf(key, sizeof(key), "%d", i * 32); APPEND_STAT(key, "%u", histogram[i]); } } free(histogram); } add_stats(NULL, 0, NULL, 0, c); } /** wrapper around assoc_find which does the lazy expiration logic */ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { mutex_lock(&cache_lock); item *it = assoc_find(key, nkey, hv); if (it != NULL) { refcount_incr(&it->refcount); /* Optimization for slab reassignment. prevents popular items from * jamming in busy wait. Can only do this here to satisfy lock order * of item_lock, cache_lock, slabs_lock. */ if (slab_rebalance_signal && ((void *)it >= slab_rebal.slab_start && (void *)it < slab_rebal.slab_end)) { do_item_unlink_nolock(it, hv); do_item_remove(it); it = NULL; } } mutex_unlock(&cache_lock); int was_found = 0; if (settings.verbose > 2) { if (it == NULL) { fprintf(stderr, "> NOT FOUND %s", key); } else { fprintf(stderr, "> FOUND KEY %s", ITEM_key(it)); was_found++; } } if (it != NULL) { if (settings.oldest_live != 0 && settings.oldest_live <= current_time && it->time <= settings.oldest_live) { do_item_unlink(it, hv); do_item_remove(it); it = NULL; if (was_found) { fprintf(stderr, " -nuked by flush"); } } else if (it->exptime != 0 && it->exptime <= current_time) { do_item_unlink(it, hv); do_item_remove(it); it = NULL; if (was_found) { fprintf(stderr, " -nuked by expire"); } } else { it->it_flags |= ITEM_FETCHED; DEBUG_REFCNT(it, '+'); } } if (settings.verbose > 2) fprintf(stderr, "\n"); return it; } item *do_item_touch(const char *key, size_t nkey, uint32_t exptime, const uint32_t hv) { item *it = do_item_get(key, nkey, hv); if (it != NULL) { it->exptime = exptime; } return it; } /* expires items that are more recent than the oldest_live setting. */ void do_item_flush_expired(void) { int i; item *iter, *next; if (settings.oldest_live == 0) return; for (i = 0; i < LARGEST_ID; i++) { /* The LRU is sorted in decreasing time order, and an item's timestamp * is never newer than its last access time, so we only need to walk * back until we hit an item older than the oldest_live time. * The oldest_live checking will auto-expire the remaining items. */ for (iter = heads[i]; iter != NULL; iter = next) { if (iter->time >= settings.oldest_live) { next = iter->next; if ((iter->it_flags & ITEM_SLABBED) == 0) { do_item_unlink_nolock(iter, hash(ITEM_key(iter), iter->nkey, 0)); } } else { /* We've hit the first old item. Continue to the next queue. */ break; } } } } memcached-1.4.14/depcomp0000755000175000017500000004426711331674343012027 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2009-04-28.21; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free # Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: memcached-1.4.14/slabs.h0000644000175000017500000000302712005172303011700 00000000000000/* slabs memory allocation */ #ifndef SLABS_H #define SLABS_H /** Init the subsystem. 1st argument is the limit on no. of bytes to allocate, 0 if no limit. 2nd argument is the growth factor; each slab will use a chunk size equal to the previous slab's chunk size times this factor. 3rd argument specifies if the slab allocator should allocate all memory up front (if true), or allocate memory in chunks as it is needed (if false) */ void slabs_init(const size_t limit, const double factor, const bool prealloc); /** * Given object size, return id to use when allocating/freeing memory for object * 0 means error: can't store such a large object */ unsigned int slabs_clsid(const size_t size); /** Allocate object of given length. 0 on error */ /*@null@*/ void *slabs_alloc(const size_t size, unsigned int id); /** Free previously allocated object */ void slabs_free(void *ptr, size_t size, unsigned int id); /** Adjust the stats for memory requested */ void slabs_adjust_mem_requested(unsigned int id, size_t old, size_t ntotal); /** Return a datum for stats in binary protocol */ bool get_stats(const char *stat_type, int nkey, ADD_STAT add_stats, void *c); /** Fill buffer with stats */ /*@null@*/ void slabs_stats(ADD_STAT add_stats, void *c); int start_slab_maintenance_thread(void); void stop_slab_maintenance_thread(void); enum reassign_result_type { REASSIGN_OK=0, REASSIGN_RUNNING, REASSIGN_BADCLASS, REASSIGN_NOSPARE, REASSIGN_SRC_DST_SAME }; enum reassign_result_type slabs_reassign(int src, int dst); #endif memcached-1.4.14/config.sub0000755000175000017500000010242511274160642012422 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. timestamp='2009-06-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: memcached-1.4.14/slabs.c0000644000175000017500000006477512005404351011715 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Slabs memory allocation, based on powers-of-N. Slabs are up to 1MB in size * and are divided into chunks. The chunk sizes start off at the size of the * "item" structure plus space for a small key and value. They increase by * a multiplier factor from there, up to half the maximum slab size. The last * slab size is always 1MB, since that's the maximum item size allowed by the * memcached protocol. */ #include "memcached.h" #include #include #include #include #include #include #include #include #include #include #include #include /* powers-of-N allocation structures */ typedef struct { unsigned int size; /* sizes of items */ unsigned int perslab; /* how many items per slab */ void *slots; /* list of item ptrs */ unsigned int sl_curr; /* total free items in list */ unsigned int slabs; /* how many slabs were allocated for this class */ void **slab_list; /* array of slab pointers */ unsigned int list_size; /* size of prev array */ unsigned int killing; /* index+1 of dying slab, or zero if none */ size_t requested; /* The number of requested bytes */ } slabclass_t; static slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES]; static size_t mem_limit = 0; static size_t mem_malloced = 0; static int power_largest; static void *mem_base = NULL; static void *mem_current = NULL; static size_t mem_avail = 0; /** * Access to the slab allocator is protected by this lock */ static pthread_mutex_t slabs_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t slabs_rebalance_lock = PTHREAD_MUTEX_INITIALIZER; /* * Forward Declarations */ static int do_slabs_newslab(const unsigned int id); static void *memory_allocate(size_t size); static void do_slabs_free(void *ptr, const size_t size, unsigned int id); /* Preallocate as many slab pages as possible (called from slabs_init) on start-up, so users don't get confused out-of-memory errors when they do have free (in-slab) space, but no space to make new slabs. if maxslabs is 18 (POWER_LARGEST - POWER_SMALLEST + 1), then all slab types can be made. if max memory is less than 18 MB, only the smaller ones will be made. */ static void slabs_preallocate (const unsigned int maxslabs); /* * Figures out which slab class (chunk size) is required to store an item of * a given size. * * Given object size, return id to use when allocating/freeing memory for object * 0 means error: can't store such a large object */ unsigned int slabs_clsid(const size_t size) { int res = POWER_SMALLEST; if (size == 0) return 0; while (size > slabclass[res].size) if (res++ == power_largest) /* won't fit in the biggest slab */ return 0; return res; } /** * Determines the chunk sizes and initializes the slab class descriptors * accordingly. */ void slabs_init(const size_t limit, const double factor, const bool prealloc) { int i = POWER_SMALLEST - 1; unsigned int size = sizeof(item) + settings.chunk_size; mem_limit = limit; if (prealloc) { /* Allocate everything in a big chunk with malloc */ mem_base = malloc(mem_limit); if (mem_base != NULL) { mem_current = mem_base; mem_avail = mem_limit; } else { fprintf(stderr, "Warning: Failed to allocate requested memory in" " one large chunk.\nWill allocate in smaller chunks\n"); } } memset(slabclass, 0, sizeof(slabclass)); while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) { /* Make sure items are always n-byte aligned */ if (size % CHUNK_ALIGN_BYTES) size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES); slabclass[i].size = size; slabclass[i].perslab = settings.item_size_max / slabclass[i].size; size *= factor; if (settings.verbose > 1) { fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n", i, slabclass[i].size, slabclass[i].perslab); } } power_largest = i; slabclass[power_largest].size = settings.item_size_max; slabclass[power_largest].perslab = 1; if (settings.verbose > 1) { fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n", i, slabclass[i].size, slabclass[i].perslab); } /* for the test suite: faking of how much we've already malloc'd */ { char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC"); if (t_initial_malloc) { mem_malloced = (size_t)atol(t_initial_malloc); } } if (prealloc) { slabs_preallocate(power_largest); } } static void slabs_preallocate (const unsigned int maxslabs) { int i; unsigned int prealloc = 0; /* pre-allocate a 1MB slab in every size class so people don't get confused by non-intuitive "SERVER_ERROR out of memory" messages. this is the most common question on the mailing list. if you really don't want this, you can rebuild without these three lines. */ for (i = POWER_SMALLEST; i <= POWER_LARGEST; i++) { if (++prealloc > maxslabs) return; if (do_slabs_newslab(i) == 0) { fprintf(stderr, "Error while preallocating slab memory!\n" "If using -L or other prealloc options, max memory must be " "at least %d megabytes.\n", power_largest); exit(1); } } } static int grow_slab_list (const unsigned int id) { slabclass_t *p = &slabclass[id]; if (p->slabs == p->list_size) { size_t new_size = (p->list_size != 0) ? p->list_size * 2 : 16; void *new_list = realloc(p->slab_list, new_size * sizeof(void *)); if (new_list == 0) return 0; p->list_size = new_size; p->slab_list = new_list; } return 1; } static void split_slab_page_into_freelist(char *ptr, const unsigned int id) { slabclass_t *p = &slabclass[id]; int x; for (x = 0; x < p->perslab; x++) { do_slabs_free(ptr, 0, id); ptr += p->size; } } static int do_slabs_newslab(const unsigned int id) { slabclass_t *p = &slabclass[id]; int len = settings.slab_reassign ? settings.item_size_max : p->size * p->perslab; char *ptr; if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) || (grow_slab_list(id) == 0) || ((ptr = memory_allocate((size_t)len)) == 0)) { MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id); return 0; } memset(ptr, 0, (size_t)len); split_slab_page_into_freelist(ptr, id); p->slab_list[p->slabs++] = ptr; mem_malloced += len; MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id); return 1; } /*@null@*/ static void *do_slabs_alloc(const size_t size, unsigned int id) { slabclass_t *p; void *ret = NULL; item *it = NULL; if (id < POWER_SMALLEST || id > power_largest) { MEMCACHED_SLABS_ALLOCATE_FAILED(size, 0); return NULL; } p = &slabclass[id]; assert(p->sl_curr == 0 || ((item *)p->slots)->slabs_clsid == 0); /* fail unless we have space at the end of a recently allocated page, we have something on our freelist, or we could allocate a new page */ if (! (p->sl_curr != 0 || do_slabs_newslab(id) != 0)) { /* We don't have more memory available */ ret = NULL; } else if (p->sl_curr != 0) { /* return off our freelist */ it = (item *)p->slots; p->slots = it->next; if (it->next) it->next->prev = 0; p->sl_curr--; ret = (void *)it; } if (ret) { p->requested += size; MEMCACHED_SLABS_ALLOCATE(size, id, p->size, ret); } else { MEMCACHED_SLABS_ALLOCATE_FAILED(size, id); } return ret; } static void do_slabs_free(void *ptr, const size_t size, unsigned int id) { slabclass_t *p; item *it; assert(((item *)ptr)->slabs_clsid == 0); assert(id >= POWER_SMALLEST && id <= power_largest); if (id < POWER_SMALLEST || id > power_largest) return; MEMCACHED_SLABS_FREE(size, id, ptr); p = &slabclass[id]; it = (item *)ptr; it->it_flags |= ITEM_SLABBED; it->prev = 0; it->next = p->slots; if (it->next) it->next->prev = it; p->slots = it; p->sl_curr++; p->requested -= size; return; } static int nz_strcmp(int nzlength, const char *nz, const char *z) { int zlength=strlen(z); return (zlength == nzlength) && (strncmp(nz, z, zlength) == 0) ? 0 : -1; } bool get_stats(const char *stat_type, int nkey, ADD_STAT add_stats, void *c) { bool ret = true; if (add_stats != NULL) { if (!stat_type) { /* prepare general statistics for the engine */ STATS_LOCK(); APPEND_STAT("bytes", "%llu", (unsigned long long)stats.curr_bytes); APPEND_STAT("curr_items", "%u", stats.curr_items); APPEND_STAT("total_items", "%u", stats.total_items); APPEND_STAT("evictions", "%llu", (unsigned long long)stats.evictions); APPEND_STAT("reclaimed", "%llu", (unsigned long long)stats.reclaimed); STATS_UNLOCK(); } else if (nz_strcmp(nkey, stat_type, "items") == 0) { item_stats(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "slabs") == 0) { slabs_stats(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "sizes") == 0) { item_stats_sizes(add_stats, c); } else { ret = false; } } else { ret = false; } return ret; } /*@null@*/ static void do_slabs_stats(ADD_STAT add_stats, void *c) { int i, total; /* Get the per-thread stats which contain some interesting aggregates */ struct thread_stats thread_stats; threadlocal_stats_aggregate(&thread_stats); total = 0; for(i = POWER_SMALLEST; i <= power_largest; i++) { slabclass_t *p = &slabclass[i]; if (p->slabs != 0) { uint32_t perslab, slabs; slabs = p->slabs; perslab = p->perslab; char key_str[STAT_KEY_LEN]; char val_str[STAT_VAL_LEN]; int klen = 0, vlen = 0; APPEND_NUM_STAT(i, "chunk_size", "%u", p->size); APPEND_NUM_STAT(i, "chunks_per_page", "%u", perslab); APPEND_NUM_STAT(i, "total_pages", "%u", slabs); APPEND_NUM_STAT(i, "total_chunks", "%u", slabs * perslab); APPEND_NUM_STAT(i, "used_chunks", "%u", slabs*perslab - p->sl_curr); APPEND_NUM_STAT(i, "free_chunks", "%u", p->sl_curr); /* Stat is dead, but displaying zero instead of removing it. */ APPEND_NUM_STAT(i, "free_chunks_end", "%u", 0); APPEND_NUM_STAT(i, "mem_requested", "%llu", (unsigned long long)p->requested); APPEND_NUM_STAT(i, "get_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].get_hits); APPEND_NUM_STAT(i, "cmd_set", "%llu", (unsigned long long)thread_stats.slab_stats[i].set_cmds); APPEND_NUM_STAT(i, "delete_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].delete_hits); APPEND_NUM_STAT(i, "incr_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].incr_hits); APPEND_NUM_STAT(i, "decr_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].decr_hits); APPEND_NUM_STAT(i, "cas_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].cas_hits); APPEND_NUM_STAT(i, "cas_badval", "%llu", (unsigned long long)thread_stats.slab_stats[i].cas_badval); APPEND_NUM_STAT(i, "touch_hits", "%llu", (unsigned long long)thread_stats.slab_stats[i].touch_hits); total++; } } /* add overall slab stats and append terminator */ APPEND_STAT("active_slabs", "%d", total); APPEND_STAT("total_malloced", "%llu", (unsigned long long)mem_malloced); add_stats(NULL, 0, NULL, 0, c); } static void *memory_allocate(size_t size) { void *ret; if (mem_base == NULL) { /* We are not using a preallocated large memory chunk */ ret = malloc(size); } else { ret = mem_current; if (size > mem_avail) { return NULL; } /* mem_current pointer _must_ be aligned!!! */ if (size % CHUNK_ALIGN_BYTES) { size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES); } mem_current = ((char*)mem_current) + size; if (size < mem_avail) { mem_avail -= size; } else { mem_avail = 0; } } return ret; } void *slabs_alloc(size_t size, unsigned int id) { void *ret; pthread_mutex_lock(&slabs_lock); ret = do_slabs_alloc(size, id); pthread_mutex_unlock(&slabs_lock); return ret; } void slabs_free(void *ptr, size_t size, unsigned int id) { pthread_mutex_lock(&slabs_lock); do_slabs_free(ptr, size, id); pthread_mutex_unlock(&slabs_lock); } void slabs_stats(ADD_STAT add_stats, void *c) { pthread_mutex_lock(&slabs_lock); do_slabs_stats(add_stats, c); pthread_mutex_unlock(&slabs_lock); } void slabs_adjust_mem_requested(unsigned int id, size_t old, size_t ntotal) { pthread_mutex_lock(&slabs_lock); slabclass_t *p; if (id < POWER_SMALLEST || id > power_largest) { fprintf(stderr, "Internal error! Invalid slab class\n"); abort(); } p = &slabclass[id]; p->requested = p->requested - old + ntotal; pthread_mutex_unlock(&slabs_lock); } static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t slab_rebalance_cond = PTHREAD_COND_INITIALIZER; static volatile int do_run_slab_thread = 1; static volatile int do_run_slab_rebalance_thread = 1; #define DEFAULT_SLAB_BULK_CHECK 1 int slab_bulk_check = DEFAULT_SLAB_BULK_CHECK; static int slab_rebalance_start(void) { slabclass_t *s_cls; int no_go = 0; pthread_mutex_lock(&cache_lock); pthread_mutex_lock(&slabs_lock); if (slab_rebal.s_clsid < POWER_SMALLEST || slab_rebal.s_clsid > power_largest || slab_rebal.d_clsid < POWER_SMALLEST || slab_rebal.d_clsid > power_largest || slab_rebal.s_clsid == slab_rebal.d_clsid) no_go = -2; s_cls = &slabclass[slab_rebal.s_clsid]; if (!grow_slab_list(slab_rebal.d_clsid)) { no_go = -1; } if (s_cls->slabs < 2) no_go = -3; if (no_go != 0) { pthread_mutex_unlock(&slabs_lock); pthread_mutex_unlock(&cache_lock); return no_go; /* Should use a wrapper function... */ } s_cls->killing = 1; slab_rebal.slab_start = s_cls->slab_list[s_cls->killing - 1]; slab_rebal.slab_end = (char *)slab_rebal.slab_start + (s_cls->size * s_cls->perslab); slab_rebal.slab_pos = slab_rebal.slab_start; slab_rebal.done = 0; /* Also tells do_item_get to search for items in this slab */ slab_rebalance_signal = 2; if (settings.verbose > 1) { fprintf(stderr, "Started a slab rebalance\n"); } pthread_mutex_unlock(&slabs_lock); pthread_mutex_unlock(&cache_lock); STATS_LOCK(); stats.slab_reassign_running = true; STATS_UNLOCK(); return 0; } enum move_status { MOVE_PASS=0, MOVE_DONE, MOVE_BUSY }; /* refcount == 0 is safe since nobody can incr while cache_lock is held. * refcount != 0 is impossible since flags/etc can be modified in other * threads. instead, note we found a busy one and bail. logic in do_item_get * will prevent busy items from continuing to be busy */ static int slab_rebalance_move(void) { slabclass_t *s_cls; int x; int was_busy = 0; int refcount = 0; enum move_status status = MOVE_PASS; pthread_mutex_lock(&cache_lock); pthread_mutex_lock(&slabs_lock); s_cls = &slabclass[slab_rebal.s_clsid]; for (x = 0; x < slab_bulk_check; x++) { item *it = slab_rebal.slab_pos; status = MOVE_PASS; if (it->slabs_clsid != 255) { refcount = refcount_incr(&it->refcount); if (refcount == 1) { /* item is unlinked, unused */ if (it->it_flags & ITEM_SLABBED) { /* remove from slab freelist */ if (s_cls->slots == it) { s_cls->slots = it->next; } if (it->next) it->next->prev = it->prev; if (it->prev) it->prev->next = it->next; s_cls->sl_curr--; status = MOVE_DONE; } else { status = MOVE_BUSY; } } else if (refcount == 2) { /* item is linked but not busy */ if ((it->it_flags & ITEM_LINKED) != 0) { do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); status = MOVE_DONE; } else { /* refcount == 1 + !ITEM_LINKED means the item is being * uploaded to, or was just unlinked but hasn't been freed * yet. Let it bleed off on its own and try again later */ status = MOVE_BUSY; } } else { if (settings.verbose > 2) { fprintf(stderr, "Slab reassign hit a busy item: refcount: %d (%d -> %d)\n", it->refcount, slab_rebal.s_clsid, slab_rebal.d_clsid); } status = MOVE_BUSY; } } switch (status) { case MOVE_DONE: it->refcount = 0; it->it_flags = 0; it->slabs_clsid = 255; break; case MOVE_BUSY: slab_rebal.busy_items++; was_busy++; refcount_decr(&it->refcount); break; case MOVE_PASS: break; } slab_rebal.slab_pos = (char *)slab_rebal.slab_pos + s_cls->size; if (slab_rebal.slab_pos >= slab_rebal.slab_end) break; } if (slab_rebal.slab_pos >= slab_rebal.slab_end) { /* Some items were busy, start again from the top */ if (slab_rebal.busy_items) { slab_rebal.slab_pos = slab_rebal.slab_start; slab_rebal.busy_items = 0; } else { slab_rebal.done++; } } pthread_mutex_unlock(&slabs_lock); pthread_mutex_unlock(&cache_lock); return was_busy; } static void slab_rebalance_finish(void) { slabclass_t *s_cls; slabclass_t *d_cls; pthread_mutex_lock(&cache_lock); pthread_mutex_lock(&slabs_lock); s_cls = &slabclass[slab_rebal.s_clsid]; d_cls = &slabclass[slab_rebal.d_clsid]; /* At this point the stolen slab is completely clear */ s_cls->slab_list[s_cls->killing - 1] = s_cls->slab_list[s_cls->slabs - 1]; s_cls->slabs--; s_cls->killing = 0; memset(slab_rebal.slab_start, 0, (size_t)settings.item_size_max); d_cls->slab_list[d_cls->slabs++] = slab_rebal.slab_start; split_slab_page_into_freelist(slab_rebal.slab_start, slab_rebal.d_clsid); slab_rebal.done = 0; slab_rebal.s_clsid = 0; slab_rebal.d_clsid = 0; slab_rebal.slab_start = NULL; slab_rebal.slab_end = NULL; slab_rebal.slab_pos = NULL; slab_rebalance_signal = 0; pthread_mutex_unlock(&slabs_lock); pthread_mutex_unlock(&cache_lock); STATS_LOCK(); stats.slab_reassign_running = false; stats.slabs_moved++; STATS_UNLOCK(); if (settings.verbose > 1) { fprintf(stderr, "finished a slab move\n"); } } /* Return 1 means a decision was reached. * Move to its own thread (created/destroyed as needed) once automover is more * complex. */ static int slab_automove_decision(int *src, int *dst) { static uint64_t evicted_old[POWER_LARGEST]; static unsigned int slab_zeroes[POWER_LARGEST]; static unsigned int slab_winner = 0; static unsigned int slab_wins = 0; uint64_t evicted_new[POWER_LARGEST]; uint64_t evicted_diff = 0; uint64_t evicted_max = 0; unsigned int highest_slab = 0; unsigned int total_pages[POWER_LARGEST]; int i; int source = 0; int dest = 0; static rel_time_t next_run; /* Run less frequently than the slabmove tester. */ if (current_time >= next_run) { next_run = current_time + 10; } else { return 0; } item_stats_evictions(evicted_new); pthread_mutex_lock(&cache_lock); for (i = POWER_SMALLEST; i < power_largest; i++) { total_pages[i] = slabclass[i].slabs; } pthread_mutex_unlock(&cache_lock); /* Find a candidate source; something with zero evicts 3+ times */ for (i = POWER_SMALLEST; i < power_largest; i++) { evicted_diff = evicted_new[i] - evicted_old[i]; if (evicted_diff == 0 && total_pages[i] > 2) { slab_zeroes[i]++; if (source == 0 && slab_zeroes[i] >= 3) source = i; } else { slab_zeroes[i] = 0; if (evicted_diff > evicted_max) { evicted_max = evicted_diff; highest_slab = i; } } evicted_old[i] = evicted_new[i]; } /* Pick a valid destination */ if (slab_winner != 0 && slab_winner == highest_slab) { slab_wins++; if (slab_wins >= 3) dest = slab_winner; } else { slab_wins = 1; slab_winner = highest_slab; } if (source && dest) { *src = source; *dst = dest; return 1; } return 0; } /* Slab rebalancer thread. * Does not use spinlocks since it is not timing sensitive. Burn less CPU and * go to sleep if locks are contended */ static void *slab_maintenance_thread(void *arg) { int src, dest; while (do_run_slab_thread) { if (settings.slab_automove == 1) { if (slab_automove_decision(&src, &dest) == 1) { /* Blind to the return codes. It will retry on its own */ slabs_reassign(src, dest); } sleep(1); } else { /* Don't wake as often if we're not enabled. * This is lazier than setting up a condition right now. */ sleep(5); } } return NULL; } /* Slab mover thread. * Sits waiting for a condition to jump off and shovel some memory about */ static void *slab_rebalance_thread(void *arg) { int was_busy = 0; while (do_run_slab_rebalance_thread) { if (slab_rebalance_signal == 1) { if (slab_rebalance_start() < 0) { /* Handle errors with more specifity as required. */ slab_rebalance_signal = 0; } was_busy = 0; } else if (slab_rebalance_signal && slab_rebal.slab_start != NULL) { was_busy = slab_rebalance_move(); } if (slab_rebal.done) { slab_rebalance_finish(); } else if (was_busy) { /* Stuck waiting for some items to unlock, so slow down a bit * to give them a chance to free up */ usleep(50); } if (slab_rebalance_signal == 0) { /* always hold this lock while we're running */ pthread_cond_wait(&slab_rebalance_cond, &slabs_rebalance_lock); } } return NULL; } /* Iterate at most once through the slab classes and pick a "random" source. * I like this better than calling rand() since rand() is slow enough that we * can just check all of the classes once instead. */ static int slabs_reassign_pick_any(int dst) { static int cur = POWER_SMALLEST - 1; int tries = power_largest - POWER_SMALLEST + 1; for (; tries > 0; tries--) { cur++; if (cur > power_largest) cur = POWER_SMALLEST; if (cur == dst) continue; if (slabclass[cur].slabs > 1) { return cur; } } return -1; } static enum reassign_result_type do_slabs_reassign(int src, int dst) { if (slab_rebalance_signal != 0) return REASSIGN_RUNNING; if (src == dst) return REASSIGN_SRC_DST_SAME; /* Special indicator to choose ourselves. */ if (src == -1) { src = slabs_reassign_pick_any(dst); /* TODO: If we end up back at -1, return a new error type */ } if (src < POWER_SMALLEST || src > power_largest || dst < POWER_SMALLEST || dst > power_largest) return REASSIGN_BADCLASS; if (slabclass[src].slabs < 2) return REASSIGN_NOSPARE; slab_rebal.s_clsid = src; slab_rebal.d_clsid = dst; slab_rebalance_signal = 1; pthread_cond_signal(&slab_rebalance_cond); return REASSIGN_OK; } enum reassign_result_type slabs_reassign(int src, int dst) { enum reassign_result_type ret; if (pthread_mutex_trylock(&slabs_rebalance_lock) != 0) { return REASSIGN_RUNNING; } ret = do_slabs_reassign(src, dst); pthread_mutex_unlock(&slabs_rebalance_lock); return ret; } static pthread_t maintenance_tid; static pthread_t rebalance_tid; int start_slab_maintenance_thread(void) { int ret; slab_rebalance_signal = 0; slab_rebal.slab_start = NULL; char *env = getenv("MEMCACHED_SLAB_BULK_CHECK"); if (env != NULL) { slab_bulk_check = atoi(env); if (slab_bulk_check == 0) { slab_bulk_check = DEFAULT_SLAB_BULK_CHECK; } } if (pthread_cond_init(&slab_rebalance_cond, NULL) != 0) { fprintf(stderr, "Can't intiialize rebalance condition\n"); return -1; } pthread_mutex_init(&slabs_rebalance_lock, NULL); if ((ret = pthread_create(&maintenance_tid, NULL, slab_maintenance_thread, NULL)) != 0) { fprintf(stderr, "Can't create slab maint thread: %s\n", strerror(ret)); return -1; } if ((ret = pthread_create(&rebalance_tid, NULL, slab_rebalance_thread, NULL)) != 0) { fprintf(stderr, "Can't create rebal thread: %s\n", strerror(ret)); return -1; } return 0; } void stop_slab_maintenance_thread(void) { mutex_lock(&cache_lock); do_run_slab_thread = 0; do_run_slab_rebalance_thread = 0; pthread_cond_signal(&maintenance_cond); pthread_mutex_unlock(&cache_lock); /* Wait for the maintenance thread to stop */ pthread_join(maintenance_tid, NULL); pthread_join(rebalance_tid, NULL); } memcached-1.4.14/sizes.c0000644000175000017500000000161511701635506011740 00000000000000#include #include "memcached.h" static void display(const char *name, size_t size) { printf("%s\t%d\n", name, (int)size); } int main(int argc, char **argv) { display("Slab Stats", sizeof(struct slab_stats)); display("Thread stats", sizeof(struct thread_stats) - (200 * sizeof(struct slab_stats))); display("Global stats", sizeof(struct stats)); display("Settings", sizeof(struct settings)); display("Item (no cas)", sizeof(item)); display("Item (cas)", sizeof(item) + sizeof(uint64_t)); display("Libevent thread", sizeof(LIBEVENT_THREAD) - sizeof(struct thread_stats)); display("Connection", sizeof(conn)); printf("----------------------------------------\n"); display("libevent thread cumulative", sizeof(LIBEVENT_THREAD)); display("Thread stats cumulative\t", sizeof(struct thread_stats)); return 0; } memcached-1.4.14/NEWS0000644000175000017500000000005011701635506011126 00000000000000http://www.danga.com/memcached/news.bml memcached-1.4.14/m4/0000755000175000017500000000000012005572440011027 500000000000000memcached-1.4.14/m4/c99-backport.m40000644000175000017500000001210411446413300013413 00000000000000# AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) # ---------------------------------------------------------------- # If the C compiler is not in ISO C99 mode by default, try to add an # option to output variable CC to make it so. This macro tries # various options that select ISO C99 on some system or another. It # considers the compiler to be in ISO C99 mode if it handles _Bool, # // comments, flexible array members, inline, long long int, mixed # code and declarations, named initialization of structs, restrict, # va_copy, varargs macros, variable declarations in for loops and # variable length arrays. AC_DEFUN([AC_PROG_CC_C99], [AC_C_STD_TRY([c99], [[#include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } ]], [[ // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ]], dnl Try dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) dnl AIX -qlanglvl=extc99 (unused restrictive mode: -qlanglvl=stdc99) dnl Intel ICC -c99 dnl IRIX -c99 dnl Solaris (unused because it causes the compiler to assume C99 semantics for dnl library functions, and this is invalid before Solaris 10: -xc99) dnl Tru64 -c99 dnl with extended modes being tried first. [[-std=gnu99 -c99 -qlanglvl=extc99]], [$1], [$2])[]dnl ])# AC_PROG_CC_C99 # AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) # -------------------------------------------------------------- # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') # by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, # try again with each compiler option in the space-separated OPTION-LIST; if one # helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, # else ACTION-IF-UNAVAILABLE. AC_DEFUN([AC_C_STD_TRY], [AC_MSG_CHECKING([for $CC option to accept ISO ]m4_translit($1, [c], [C])) AC_CACHE_VAL(ac_cv_prog_cc_$1, [ac_cv_prog_cc_$1=no ac_save_CC=$CC AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) for ac_arg in '' $4 do CC="$ac_save_CC $ac_arg" _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) test "x$ac_cv_prog_cc_$1" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC ])# AC_CACHE_VAL case "x$ac_cv_prog_cc_$1" in x) AC_MSG_RESULT([none needed]) ;; xno) AC_MSG_RESULT([unsupported]) ;; *) CC="$CC $ac_cv_prog_cc_$1" AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; esac AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) ])# AC_C_STD_TRY memcached-1.4.14/Makefile.in0000644000175000017500000023157012005572432012505 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = memcached$(EXEEXT) noinst_PROGRAMS = memcached-debug$(EXEEXT) sizes$(EXEEXT) \ testapp$(EXEEXT) timedrun$(EXEEXT) @BUILD_CACHE_TRUE@am__append_1 = cache.c @BUILD_CACHE_TRUE@am__append_2 = cache.c @BUILD_SOLARIS_PRIVS_TRUE@am__append_3 = solaris_priv.c @ENABLE_SASL_TRUE@am__append_4 = sasl_defs.c @BUILD_DTRACE_TRUE@am__append_5 = memcached_dtrace.h @BUILD_DTRACE_TRUE@am__append_6 = memcached_dtrace.h @DTRACE_INSTRUMENT_OBJ_TRUE@am__append_7 = memcached_dtrace.o @DTRACE_INSTRUMENT_OBJ_TRUE@am__append_8 = memcached_dtrace.o @DTRACE_INSTRUMENT_OBJ_TRUE@am__append_9 = memcached_debug_dtrace.o @DTRACE_INSTRUMENT_OBJ_TRUE@am__append_10 = memcached_debug_dtrace.o @DTRACE_INSTRUMENT_OBJ_TRUE@am__append_11 = memcached_dtrace.o memcached_debug_dtrace.o subdir = . DIST_COMMON = $(am__configure_deps) $(pkginclude_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \ ChangeLog NEWS compile config.guess config.sub depcomp \ install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/version.m4 \ $(top_srcdir)/m4/c99-backport.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludedir)" PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am__memcached_SOURCES_DIST = memcached.c memcached.h hash.c hash.h \ slabs.c slabs.h items.c items.h assoc.c assoc.h thread.c \ daemon.c stats.c stats.h util.c util.h trace.h cache.h \ sasl_defs.h cache.c solaris_priv.c sasl_defs.c @BUILD_CACHE_TRUE@am__objects_1 = memcached-cache.$(OBJEXT) @BUILD_SOLARIS_PRIVS_TRUE@am__objects_2 = \ @BUILD_SOLARIS_PRIVS_TRUE@ memcached-solaris_priv.$(OBJEXT) @ENABLE_SASL_TRUE@am__objects_3 = memcached-sasl_defs.$(OBJEXT) am_memcached_OBJECTS = memcached-memcached.$(OBJEXT) \ memcached-hash.$(OBJEXT) memcached-slabs.$(OBJEXT) \ memcached-items.$(OBJEXT) memcached-assoc.$(OBJEXT) \ memcached-thread.$(OBJEXT) memcached-daemon.$(OBJEXT) \ memcached-stats.$(OBJEXT) memcached-util.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) memcached_OBJECTS = $(am_memcached_OBJECTS) am__memcached_debug_SOURCES_DIST = memcached.c memcached.h hash.c \ hash.h slabs.c slabs.h items.c items.h assoc.c assoc.h \ thread.c daemon.c stats.c stats.h util.c util.h trace.h \ cache.h sasl_defs.h cache.c solaris_priv.c sasl_defs.c @BUILD_CACHE_TRUE@am__objects_4 = memcached_debug-cache.$(OBJEXT) @BUILD_SOLARIS_PRIVS_TRUE@am__objects_5 = memcached_debug-solaris_priv.$(OBJEXT) @ENABLE_SASL_TRUE@am__objects_6 = memcached_debug-sasl_defs.$(OBJEXT) am__objects_7 = memcached_debug-memcached.$(OBJEXT) \ memcached_debug-hash.$(OBJEXT) memcached_debug-slabs.$(OBJEXT) \ memcached_debug-items.$(OBJEXT) \ memcached_debug-assoc.$(OBJEXT) \ memcached_debug-thread.$(OBJEXT) \ memcached_debug-daemon.$(OBJEXT) \ memcached_debug-stats.$(OBJEXT) memcached_debug-util.$(OBJEXT) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) am_memcached_debug_OBJECTS = $(am__objects_7) memcached_debug_OBJECTS = $(am_memcached_debug_OBJECTS) memcached_debug_LINK = $(CCLD) $(memcached_debug_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ sizes_SOURCES = sizes.c sizes_OBJECTS = sizes.$(OBJEXT) sizes_LDADD = $(LDADD) am__testapp_SOURCES_DIST = testapp.c util.c util.h cache.c @BUILD_CACHE_TRUE@am__objects_8 = cache.$(OBJEXT) am_testapp_OBJECTS = testapp.$(OBJEXT) util.$(OBJEXT) $(am__objects_8) testapp_OBJECTS = $(am_testapp_OBJECTS) testapp_LDADD = $(LDADD) am_timedrun_OBJECTS = timedrun.$(OBJEXT) timedrun_OBJECTS = $(am_timedrun_OBJECTS) timedrun_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(memcached_SOURCES) $(memcached_debug_SOURCES) sizes.c \ $(testapp_SOURCES) $(timedrun_SOURCES) DIST_SOURCES = $(am__memcached_SOURCES_DIST) \ $(am__memcached_debug_SOURCES_DIST) sizes.c \ $(am__testapp_SOURCES_DIST) $(timedrun_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' HEADERS = $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DTRACE = @DTRACE@ DTRACEFLAGS = @DTRACEFLAGS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_SASL = @ENABLE_SASL@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROFILER = @PROFILER@ PROFILER_FLAGS = @PROFILER_FLAGS@ PROFILER_LDFLAGS = @PROFILER_LDFLAGS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XML2RFC = @XML2RFC@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = protocol_binary.h BUILT_SOURCES = $(am__append_5) testapp_SOURCES = testapp.c util.c util.h $(am__append_2) timedrun_SOURCES = timedrun.c memcached_SOURCES = memcached.c memcached.h hash.c hash.h slabs.c \ slabs.h items.c items.h assoc.c assoc.h thread.c daemon.c \ stats.c stats.h util.c util.h trace.h cache.h sasl_defs.h \ $(am__append_1) $(am__append_3) $(am__append_4) memcached_debug_SOURCES = $(memcached_SOURCES) memcached_CPPFLAGS = -DNDEBUG memcached_debug_LDADD = @PROFILER_LDFLAGS@ $(am__append_9) memcached_debug_CFLAGS = @PROFILER_FLAGS@ memcached_LDADD = $(am__append_7) memcached_DEPENDENCIES = $(am__append_8) memcached_debug_DEPENDENCIES = $(am__append_10) CLEANFILES = $(am__append_6) $(am__append_11) SUBDIRS = doc DIST_DIRS = scripts EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 MOSTLYCLEANFILES = *.gcov *.gcno *.gcda *.tcov all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) memcached$(EXEEXT): $(memcached_OBJECTS) $(memcached_DEPENDENCIES) @rm -f memcached$(EXEEXT) $(LINK) $(memcached_OBJECTS) $(memcached_LDADD) $(LIBS) memcached-debug$(EXEEXT): $(memcached_debug_OBJECTS) $(memcached_debug_DEPENDENCIES) @rm -f memcached-debug$(EXEEXT) $(memcached_debug_LINK) $(memcached_debug_OBJECTS) $(memcached_debug_LDADD) $(LIBS) sizes$(EXEEXT): $(sizes_OBJECTS) $(sizes_DEPENDENCIES) @rm -f sizes$(EXEEXT) $(LINK) $(sizes_OBJECTS) $(sizes_LDADD) $(LIBS) testapp$(EXEEXT): $(testapp_OBJECTS) $(testapp_DEPENDENCIES) @rm -f testapp$(EXEEXT) $(LINK) $(testapp_OBJECTS) $(testapp_LDADD) $(LIBS) timedrun$(EXEEXT): $(timedrun_OBJECTS) $(timedrun_DEPENDENCIES) @rm -f timedrun$(EXEEXT) $(LINK) $(timedrun_OBJECTS) $(timedrun_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-assoc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-daemon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-items.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-memcached.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-sasl_defs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-slabs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-solaris_priv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-assoc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-daemon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-items.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-memcached.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-sasl_defs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-slabs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-solaris_priv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcached_debug-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sizes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timedrun.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` memcached-memcached.o: memcached.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-memcached.o -MD -MP -MF $(DEPDIR)/memcached-memcached.Tpo -c -o memcached-memcached.o `test -f 'memcached.c' || echo '$(srcdir)/'`memcached.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-memcached.Tpo $(DEPDIR)/memcached-memcached.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memcached.c' object='memcached-memcached.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-memcached.o `test -f 'memcached.c' || echo '$(srcdir)/'`memcached.c memcached-memcached.obj: memcached.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-memcached.obj -MD -MP -MF $(DEPDIR)/memcached-memcached.Tpo -c -o memcached-memcached.obj `if test -f 'memcached.c'; then $(CYGPATH_W) 'memcached.c'; else $(CYGPATH_W) '$(srcdir)/memcached.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-memcached.Tpo $(DEPDIR)/memcached-memcached.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memcached.c' object='memcached-memcached.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-memcached.obj `if test -f 'memcached.c'; then $(CYGPATH_W) 'memcached.c'; else $(CYGPATH_W) '$(srcdir)/memcached.c'; fi` memcached-hash.o: hash.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-hash.o -MD -MP -MF $(DEPDIR)/memcached-hash.Tpo -c -o memcached-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-hash.Tpo $(DEPDIR)/memcached-hash.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='memcached-hash.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c memcached-hash.obj: hash.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-hash.obj -MD -MP -MF $(DEPDIR)/memcached-hash.Tpo -c -o memcached-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-hash.Tpo $(DEPDIR)/memcached-hash.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='memcached-hash.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` memcached-slabs.o: slabs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-slabs.o -MD -MP -MF $(DEPDIR)/memcached-slabs.Tpo -c -o memcached-slabs.o `test -f 'slabs.c' || echo '$(srcdir)/'`slabs.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-slabs.Tpo $(DEPDIR)/memcached-slabs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slabs.c' object='memcached-slabs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-slabs.o `test -f 'slabs.c' || echo '$(srcdir)/'`slabs.c memcached-slabs.obj: slabs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-slabs.obj -MD -MP -MF $(DEPDIR)/memcached-slabs.Tpo -c -o memcached-slabs.obj `if test -f 'slabs.c'; then $(CYGPATH_W) 'slabs.c'; else $(CYGPATH_W) '$(srcdir)/slabs.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-slabs.Tpo $(DEPDIR)/memcached-slabs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slabs.c' object='memcached-slabs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-slabs.obj `if test -f 'slabs.c'; then $(CYGPATH_W) 'slabs.c'; else $(CYGPATH_W) '$(srcdir)/slabs.c'; fi` memcached-items.o: items.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-items.o -MD -MP -MF $(DEPDIR)/memcached-items.Tpo -c -o memcached-items.o `test -f 'items.c' || echo '$(srcdir)/'`items.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-items.Tpo $(DEPDIR)/memcached-items.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='items.c' object='memcached-items.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-items.o `test -f 'items.c' || echo '$(srcdir)/'`items.c memcached-items.obj: items.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-items.obj -MD -MP -MF $(DEPDIR)/memcached-items.Tpo -c -o memcached-items.obj `if test -f 'items.c'; then $(CYGPATH_W) 'items.c'; else $(CYGPATH_W) '$(srcdir)/items.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-items.Tpo $(DEPDIR)/memcached-items.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='items.c' object='memcached-items.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-items.obj `if test -f 'items.c'; then $(CYGPATH_W) 'items.c'; else $(CYGPATH_W) '$(srcdir)/items.c'; fi` memcached-assoc.o: assoc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-assoc.o -MD -MP -MF $(DEPDIR)/memcached-assoc.Tpo -c -o memcached-assoc.o `test -f 'assoc.c' || echo '$(srcdir)/'`assoc.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-assoc.Tpo $(DEPDIR)/memcached-assoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='assoc.c' object='memcached-assoc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-assoc.o `test -f 'assoc.c' || echo '$(srcdir)/'`assoc.c memcached-assoc.obj: assoc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-assoc.obj -MD -MP -MF $(DEPDIR)/memcached-assoc.Tpo -c -o memcached-assoc.obj `if test -f 'assoc.c'; then $(CYGPATH_W) 'assoc.c'; else $(CYGPATH_W) '$(srcdir)/assoc.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-assoc.Tpo $(DEPDIR)/memcached-assoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='assoc.c' object='memcached-assoc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-assoc.obj `if test -f 'assoc.c'; then $(CYGPATH_W) 'assoc.c'; else $(CYGPATH_W) '$(srcdir)/assoc.c'; fi` memcached-thread.o: thread.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-thread.o -MD -MP -MF $(DEPDIR)/memcached-thread.Tpo -c -o memcached-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-thread.Tpo $(DEPDIR)/memcached-thread.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='memcached-thread.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c memcached-thread.obj: thread.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-thread.obj -MD -MP -MF $(DEPDIR)/memcached-thread.Tpo -c -o memcached-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-thread.Tpo $(DEPDIR)/memcached-thread.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='memcached-thread.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` memcached-daemon.o: daemon.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-daemon.o -MD -MP -MF $(DEPDIR)/memcached-daemon.Tpo -c -o memcached-daemon.o `test -f 'daemon.c' || echo '$(srcdir)/'`daemon.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-daemon.Tpo $(DEPDIR)/memcached-daemon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daemon.c' object='memcached-daemon.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-daemon.o `test -f 'daemon.c' || echo '$(srcdir)/'`daemon.c memcached-daemon.obj: daemon.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-daemon.obj -MD -MP -MF $(DEPDIR)/memcached-daemon.Tpo -c -o memcached-daemon.obj `if test -f 'daemon.c'; then $(CYGPATH_W) 'daemon.c'; else $(CYGPATH_W) '$(srcdir)/daemon.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-daemon.Tpo $(DEPDIR)/memcached-daemon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daemon.c' object='memcached-daemon.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-daemon.obj `if test -f 'daemon.c'; then $(CYGPATH_W) 'daemon.c'; else $(CYGPATH_W) '$(srcdir)/daemon.c'; fi` memcached-stats.o: stats.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-stats.o -MD -MP -MF $(DEPDIR)/memcached-stats.Tpo -c -o memcached-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-stats.Tpo $(DEPDIR)/memcached-stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stats.c' object='memcached-stats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c memcached-stats.obj: stats.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-stats.obj -MD -MP -MF $(DEPDIR)/memcached-stats.Tpo -c -o memcached-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-stats.Tpo $(DEPDIR)/memcached-stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stats.c' object='memcached-stats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi` memcached-util.o: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-util.o -MD -MP -MF $(DEPDIR)/memcached-util.Tpo -c -o memcached-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-util.Tpo $(DEPDIR)/memcached-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='memcached-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c memcached-util.obj: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-util.obj -MD -MP -MF $(DEPDIR)/memcached-util.Tpo -c -o memcached-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-util.Tpo $(DEPDIR)/memcached-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='memcached-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` memcached-cache.o: cache.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-cache.o -MD -MP -MF $(DEPDIR)/memcached-cache.Tpo -c -o memcached-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-cache.Tpo $(DEPDIR)/memcached-cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='memcached-cache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c memcached-cache.obj: cache.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-cache.obj -MD -MP -MF $(DEPDIR)/memcached-cache.Tpo -c -o memcached-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-cache.Tpo $(DEPDIR)/memcached-cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='memcached-cache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` memcached-solaris_priv.o: solaris_priv.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-solaris_priv.o -MD -MP -MF $(DEPDIR)/memcached-solaris_priv.Tpo -c -o memcached-solaris_priv.o `test -f 'solaris_priv.c' || echo '$(srcdir)/'`solaris_priv.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-solaris_priv.Tpo $(DEPDIR)/memcached-solaris_priv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='solaris_priv.c' object='memcached-solaris_priv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-solaris_priv.o `test -f 'solaris_priv.c' || echo '$(srcdir)/'`solaris_priv.c memcached-solaris_priv.obj: solaris_priv.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-solaris_priv.obj -MD -MP -MF $(DEPDIR)/memcached-solaris_priv.Tpo -c -o memcached-solaris_priv.obj `if test -f 'solaris_priv.c'; then $(CYGPATH_W) 'solaris_priv.c'; else $(CYGPATH_W) '$(srcdir)/solaris_priv.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-solaris_priv.Tpo $(DEPDIR)/memcached-solaris_priv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='solaris_priv.c' object='memcached-solaris_priv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-solaris_priv.obj `if test -f 'solaris_priv.c'; then $(CYGPATH_W) 'solaris_priv.c'; else $(CYGPATH_W) '$(srcdir)/solaris_priv.c'; fi` memcached-sasl_defs.o: sasl_defs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-sasl_defs.o -MD -MP -MF $(DEPDIR)/memcached-sasl_defs.Tpo -c -o memcached-sasl_defs.o `test -f 'sasl_defs.c' || echo '$(srcdir)/'`sasl_defs.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-sasl_defs.Tpo $(DEPDIR)/memcached-sasl_defs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sasl_defs.c' object='memcached-sasl_defs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-sasl_defs.o `test -f 'sasl_defs.c' || echo '$(srcdir)/'`sasl_defs.c memcached-sasl_defs.obj: sasl_defs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memcached-sasl_defs.obj -MD -MP -MF $(DEPDIR)/memcached-sasl_defs.Tpo -c -o memcached-sasl_defs.obj `if test -f 'sasl_defs.c'; then $(CYGPATH_W) 'sasl_defs.c'; else $(CYGPATH_W) '$(srcdir)/sasl_defs.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached-sasl_defs.Tpo $(DEPDIR)/memcached-sasl_defs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sasl_defs.c' object='memcached-sasl_defs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(memcached_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memcached-sasl_defs.obj `if test -f 'sasl_defs.c'; then $(CYGPATH_W) 'sasl_defs.c'; else $(CYGPATH_W) '$(srcdir)/sasl_defs.c'; fi` memcached_debug-memcached.o: memcached.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-memcached.o -MD -MP -MF $(DEPDIR)/memcached_debug-memcached.Tpo -c -o memcached_debug-memcached.o `test -f 'memcached.c' || echo '$(srcdir)/'`memcached.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-memcached.Tpo $(DEPDIR)/memcached_debug-memcached.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memcached.c' object='memcached_debug-memcached.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-memcached.o `test -f 'memcached.c' || echo '$(srcdir)/'`memcached.c memcached_debug-memcached.obj: memcached.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-memcached.obj -MD -MP -MF $(DEPDIR)/memcached_debug-memcached.Tpo -c -o memcached_debug-memcached.obj `if test -f 'memcached.c'; then $(CYGPATH_W) 'memcached.c'; else $(CYGPATH_W) '$(srcdir)/memcached.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-memcached.Tpo $(DEPDIR)/memcached_debug-memcached.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memcached.c' object='memcached_debug-memcached.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-memcached.obj `if test -f 'memcached.c'; then $(CYGPATH_W) 'memcached.c'; else $(CYGPATH_W) '$(srcdir)/memcached.c'; fi` memcached_debug-hash.o: hash.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-hash.o -MD -MP -MF $(DEPDIR)/memcached_debug-hash.Tpo -c -o memcached_debug-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-hash.Tpo $(DEPDIR)/memcached_debug-hash.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='memcached_debug-hash.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c memcached_debug-hash.obj: hash.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-hash.obj -MD -MP -MF $(DEPDIR)/memcached_debug-hash.Tpo -c -o memcached_debug-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-hash.Tpo $(DEPDIR)/memcached_debug-hash.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='memcached_debug-hash.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` memcached_debug-slabs.o: slabs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-slabs.o -MD -MP -MF $(DEPDIR)/memcached_debug-slabs.Tpo -c -o memcached_debug-slabs.o `test -f 'slabs.c' || echo '$(srcdir)/'`slabs.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-slabs.Tpo $(DEPDIR)/memcached_debug-slabs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slabs.c' object='memcached_debug-slabs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-slabs.o `test -f 'slabs.c' || echo '$(srcdir)/'`slabs.c memcached_debug-slabs.obj: slabs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-slabs.obj -MD -MP -MF $(DEPDIR)/memcached_debug-slabs.Tpo -c -o memcached_debug-slabs.obj `if test -f 'slabs.c'; then $(CYGPATH_W) 'slabs.c'; else $(CYGPATH_W) '$(srcdir)/slabs.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-slabs.Tpo $(DEPDIR)/memcached_debug-slabs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slabs.c' object='memcached_debug-slabs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-slabs.obj `if test -f 'slabs.c'; then $(CYGPATH_W) 'slabs.c'; else $(CYGPATH_W) '$(srcdir)/slabs.c'; fi` memcached_debug-items.o: items.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-items.o -MD -MP -MF $(DEPDIR)/memcached_debug-items.Tpo -c -o memcached_debug-items.o `test -f 'items.c' || echo '$(srcdir)/'`items.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-items.Tpo $(DEPDIR)/memcached_debug-items.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='items.c' object='memcached_debug-items.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-items.o `test -f 'items.c' || echo '$(srcdir)/'`items.c memcached_debug-items.obj: items.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-items.obj -MD -MP -MF $(DEPDIR)/memcached_debug-items.Tpo -c -o memcached_debug-items.obj `if test -f 'items.c'; then $(CYGPATH_W) 'items.c'; else $(CYGPATH_W) '$(srcdir)/items.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-items.Tpo $(DEPDIR)/memcached_debug-items.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='items.c' object='memcached_debug-items.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-items.obj `if test -f 'items.c'; then $(CYGPATH_W) 'items.c'; else $(CYGPATH_W) '$(srcdir)/items.c'; fi` memcached_debug-assoc.o: assoc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-assoc.o -MD -MP -MF $(DEPDIR)/memcached_debug-assoc.Tpo -c -o memcached_debug-assoc.o `test -f 'assoc.c' || echo '$(srcdir)/'`assoc.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-assoc.Tpo $(DEPDIR)/memcached_debug-assoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='assoc.c' object='memcached_debug-assoc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-assoc.o `test -f 'assoc.c' || echo '$(srcdir)/'`assoc.c memcached_debug-assoc.obj: assoc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-assoc.obj -MD -MP -MF $(DEPDIR)/memcached_debug-assoc.Tpo -c -o memcached_debug-assoc.obj `if test -f 'assoc.c'; then $(CYGPATH_W) 'assoc.c'; else $(CYGPATH_W) '$(srcdir)/assoc.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-assoc.Tpo $(DEPDIR)/memcached_debug-assoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='assoc.c' object='memcached_debug-assoc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-assoc.obj `if test -f 'assoc.c'; then $(CYGPATH_W) 'assoc.c'; else $(CYGPATH_W) '$(srcdir)/assoc.c'; fi` memcached_debug-thread.o: thread.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-thread.o -MD -MP -MF $(DEPDIR)/memcached_debug-thread.Tpo -c -o memcached_debug-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-thread.Tpo $(DEPDIR)/memcached_debug-thread.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='memcached_debug-thread.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c memcached_debug-thread.obj: thread.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-thread.obj -MD -MP -MF $(DEPDIR)/memcached_debug-thread.Tpo -c -o memcached_debug-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-thread.Tpo $(DEPDIR)/memcached_debug-thread.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='memcached_debug-thread.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` memcached_debug-daemon.o: daemon.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-daemon.o -MD -MP -MF $(DEPDIR)/memcached_debug-daemon.Tpo -c -o memcached_debug-daemon.o `test -f 'daemon.c' || echo '$(srcdir)/'`daemon.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-daemon.Tpo $(DEPDIR)/memcached_debug-daemon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daemon.c' object='memcached_debug-daemon.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-daemon.o `test -f 'daemon.c' || echo '$(srcdir)/'`daemon.c memcached_debug-daemon.obj: daemon.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-daemon.obj -MD -MP -MF $(DEPDIR)/memcached_debug-daemon.Tpo -c -o memcached_debug-daemon.obj `if test -f 'daemon.c'; then $(CYGPATH_W) 'daemon.c'; else $(CYGPATH_W) '$(srcdir)/daemon.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-daemon.Tpo $(DEPDIR)/memcached_debug-daemon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daemon.c' object='memcached_debug-daemon.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-daemon.obj `if test -f 'daemon.c'; then $(CYGPATH_W) 'daemon.c'; else $(CYGPATH_W) '$(srcdir)/daemon.c'; fi` memcached_debug-stats.o: stats.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-stats.o -MD -MP -MF $(DEPDIR)/memcached_debug-stats.Tpo -c -o memcached_debug-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-stats.Tpo $(DEPDIR)/memcached_debug-stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stats.c' object='memcached_debug-stats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c memcached_debug-stats.obj: stats.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-stats.obj -MD -MP -MF $(DEPDIR)/memcached_debug-stats.Tpo -c -o memcached_debug-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-stats.Tpo $(DEPDIR)/memcached_debug-stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stats.c' object='memcached_debug-stats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi` memcached_debug-util.o: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-util.o -MD -MP -MF $(DEPDIR)/memcached_debug-util.Tpo -c -o memcached_debug-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-util.Tpo $(DEPDIR)/memcached_debug-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='memcached_debug-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c memcached_debug-util.obj: util.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-util.obj -MD -MP -MF $(DEPDIR)/memcached_debug-util.Tpo -c -o memcached_debug-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-util.Tpo $(DEPDIR)/memcached_debug-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='memcached_debug-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` memcached_debug-cache.o: cache.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-cache.o -MD -MP -MF $(DEPDIR)/memcached_debug-cache.Tpo -c -o memcached_debug-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-cache.Tpo $(DEPDIR)/memcached_debug-cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='memcached_debug-cache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c memcached_debug-cache.obj: cache.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-cache.obj -MD -MP -MF $(DEPDIR)/memcached_debug-cache.Tpo -c -o memcached_debug-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-cache.Tpo $(DEPDIR)/memcached_debug-cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='memcached_debug-cache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` memcached_debug-solaris_priv.o: solaris_priv.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-solaris_priv.o -MD -MP -MF $(DEPDIR)/memcached_debug-solaris_priv.Tpo -c -o memcached_debug-solaris_priv.o `test -f 'solaris_priv.c' || echo '$(srcdir)/'`solaris_priv.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-solaris_priv.Tpo $(DEPDIR)/memcached_debug-solaris_priv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='solaris_priv.c' object='memcached_debug-solaris_priv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-solaris_priv.o `test -f 'solaris_priv.c' || echo '$(srcdir)/'`solaris_priv.c memcached_debug-solaris_priv.obj: solaris_priv.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-solaris_priv.obj -MD -MP -MF $(DEPDIR)/memcached_debug-solaris_priv.Tpo -c -o memcached_debug-solaris_priv.obj `if test -f 'solaris_priv.c'; then $(CYGPATH_W) 'solaris_priv.c'; else $(CYGPATH_W) '$(srcdir)/solaris_priv.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-solaris_priv.Tpo $(DEPDIR)/memcached_debug-solaris_priv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='solaris_priv.c' object='memcached_debug-solaris_priv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-solaris_priv.obj `if test -f 'solaris_priv.c'; then $(CYGPATH_W) 'solaris_priv.c'; else $(CYGPATH_W) '$(srcdir)/solaris_priv.c'; fi` memcached_debug-sasl_defs.o: sasl_defs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-sasl_defs.o -MD -MP -MF $(DEPDIR)/memcached_debug-sasl_defs.Tpo -c -o memcached_debug-sasl_defs.o `test -f 'sasl_defs.c' || echo '$(srcdir)/'`sasl_defs.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-sasl_defs.Tpo $(DEPDIR)/memcached_debug-sasl_defs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sasl_defs.c' object='memcached_debug-sasl_defs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-sasl_defs.o `test -f 'sasl_defs.c' || echo '$(srcdir)/'`sasl_defs.c memcached_debug-sasl_defs.obj: sasl_defs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -MT memcached_debug-sasl_defs.obj -MD -MP -MF $(DEPDIR)/memcached_debug-sasl_defs.Tpo -c -o memcached_debug-sasl_defs.obj `if test -f 'sasl_defs.c'; then $(CYGPATH_W) 'sasl_defs.c'; else $(CYGPATH_W) '$(srcdir)/sasl_defs.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/memcached_debug-sasl_defs.Tpo $(DEPDIR)/memcached_debug-sasl_defs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sasl_defs.c' object='memcached_debug-sasl_defs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memcached_debug_CFLAGS) $(CFLAGS) -c -o memcached_debug-sasl_defs.obj `if test -f 'sasl_defs.c'; then $(CYGPATH_W) 'sasl_defs.c'; else $(CYGPATH_W) '$(srcdir)/sasl_defs.c'; fi` install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) $(HEADERS) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-pkgincludeHEADERS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ ctags-recursive install install-am install-strip \ tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-binPROGRAMS \ clean-generic clean-noinstPROGRAMS ctags ctags-recursive dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzma dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-compile distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-pkgincludeHEADERS \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-pkgincludeHEADERS memcached_dtrace.h: memcached_dtrace.d ${DTRACE} -h -s memcached_dtrace.d sed -e 's,void \*,const void \*,g' memcached_dtrace.h | \ sed -e 's,char \*,const char \*,g' | tr '\t' ' ' > mmc_dtrace.tmp mv mmc_dtrace.tmp memcached_dtrace.h memcached_dtrace.o: $(memcached_OBJECTS) $(DTRACE) $(DTRACEFLAGS) -G -o memcached_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_OBJECTS) memcached_debug_dtrace.o: $(memcached_debug_OBJECTS) $(DTRACE) $(DTRACEFLAGS) -G -o memcached_debug_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_debug_OBJECTS) test: memcached-debug sizes testapp $(srcdir)/sizes $(srcdir)/testapp prove $(srcdir)/t @if test `basename $(PROFILER)` = "gcov"; then \ for file in memcached_debug-*.gc??; do \ mv -f $$file `echo $$file | sed 's/memcached_debug-//'`; \ done && \ for file in *.gcda; do \ srcfile=`echo $$file | sed 's/.gcda/.c/'`; \ if test -n "`echo $(memcached_debug_SOURCES) | grep $$srcfile`"; then \ echo `$(PROFILER) $$srcfile` | sed 's/'$$srcfile':.*//'; \ fi \ done \ elif test `basename $(PROFILER)` = "tcov"; then \ files=`grep SRCFILE memcached-debug.profile/tcovd | sed 's/SRCFILE://' | sort | uniq` && \ $(PROFILER) -x memcached-debug.profile $$files 2>&1; \ for file in *.tcov; do \ srcfile=`echo $$file | sed 's/.tcov//'`; \ if test -n "`echo $(memcached_debug_SOURCES) | grep $$srcfile`"; then \ echo $$srcfile : `grep 'Percent of the file executed' $$file`; \ fi \ done \ else :; fi docs: (cat Doxyfile ; echo "PROJECT_NUMBER=`cat version.num`") | doxygen - dist-hook: rm -f $(distdir)/*/*~ $(distdir)/t/lib/*~ $(distdir)/*~ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: memcached-1.4.14/solaris_priv.c0000644000175000017500000000235311701635506013317 00000000000000#include #include #include #include "memcached.h" /* * this section of code will drop all (Solaris) privileges including * those normally granted to all userland process (basic privileges). The * effect of this is that after running this code, the process will not able * to fork(), exec(), etc. See privileges(5) for more information. */ void drop_privileges(void) { priv_set_t *privs = priv_str_to_set("basic", ",", NULL); if (privs == NULL) { perror("priv_str_to_set"); exit(EXIT_FAILURE); } (void)priv_delset(privs, PRIV_FILE_LINK_ANY); (void)priv_delset(privs, PRIV_PROC_EXEC); (void)priv_delset(privs, PRIV_PROC_FORK); (void)priv_delset(privs, PRIV_PROC_INFO); (void)priv_delset(privs, PRIV_PROC_SESSION); if (setppriv(PRIV_SET, PRIV_PERMITTED, privs) != 0) { perror("setppriv(PRIV_SET, PRIV_PERMITTED)"); exit(EXIT_FAILURE); } priv_emptyset(privs); if (setppriv(PRIV_SET, PRIV_INHERITABLE, privs) != 0) { perror("setppriv(PRIV_SET, PRIV_INHERITABLE)"); exit(EXIT_FAILURE); } if (setppriv(PRIV_SET, PRIV_LIMIT, privs) != 0) { perror("setppriv(PRIV_SET, PRIV_LIMIT)"); exit(EXIT_FAILURE); } priv_freeset(privs); } memcached-1.4.14/ChangeLog0000644000175000017500000004607311606254362012221 000000000000002010-10-11 * ChangeLog is no longer being updated. See http://code.google.com/p/memcached/wiki/ReleaseNotes 2009-04-10 * *critical bugfix*. In 1.2.7 under multithreaded mode, memcached would never restart accepting connections after hitting the maximum connection limit. 2009-04-02 * Fix: Rewrote stat buffer handling (Trond) 2009-03-31 * Feature: -b option for configuring backlog * Feature: stats settings * Fix: binary stat alignment bug (bug26) * Fix: buffer overflow in stats (bug27) * Fix: recycle memory more aggressively (bug14) * Fix: incr validation (bug31) * Fix: 64-bit incr/decr delta problem (bug21) * Fix: Ascii UDP set (bug36) * Fix: stats slabs' used chunks (bug29) * Fix: stats reset resetting more (bug22) * Misc: More tests, documentation, cleanliness (godliness) * Stable merge (stats, debuggability, listen bugs) 2009-03-11 * Protocol: Binary complete (Dustin, Trond, Toru, etc...) * Performance: improvements from facebook (Dormando) * Performance: per-thread stats (Trond) * Performance: Hash expansion in its own thread (Trond) * Stats: Lots of new stats (Dustin) * Bug fixes (various) See the 1.3.2 release notes or revision control for more detail. 2008-09-06 * Display error status on listen failures (Dormando) * Remove managed instance code. Incomplete/etc. (Dormando) * Handle broken IPV6 stacks better (Brian Aker) * Generate warnings on setsockopt() failures (Brian Aker) * Fix some indentation issues (Brian Aker) * UDP/TCP can be disabled by setting their port to zero (Brian Aker) * Zero out libevent thread structures before use (Ricky Zhou) * New stat: Last accessed time for last evicted item per slab class. (Dormando) * Use a dedicated socket accept thread (Facebook) * Add -R option. Limit the number of requests processed by a connection at once. Prevents starving other threads if bulk loading. (Facebook) 2008-07-29 [Version 1.2.6 released] 2008-07-24 [Version 1.2.6-rc1 released] * Add support for newer automake (Facebook) * DTrace support for Solaris/etc (Trond Norbye) * LRU tests (Steve Yen) * Handle negative length items properly (Dormando) * Don't leave stale data after failed set attempts (Dormando) * Fix refcount leaks, which would result in OOM's on all sets (Dormando) * Fix buffer overruns (Dustin Sallings, Tomash Brechko) * Fix memory corruption with CAS (Dustin Sallings) 2008-06-11 * Fix -k to work with -d. (reported by Gary Zhu) 2008-03-02 [Version 1.2.5-rc1 released] * Add per-item-class tracking of evictions and OOM errors (dormando) * Optimize item_alloc() a little (dormando) * Give 'SERVER_ERROR out of memory' errors more context (dormando) * Enable usage of large memory pages under solaris (Trond.Norbye@Sun.COM) * Enable UDP by default, clean up server socket code (brian@tangent.org) * 'noreply' support (Tomash Brechko) * IPv6 support, and IPv6 multi-interface support (brian@tangent.org) * Add compiler options for Sun Studio compilers with --enable-threads (Trond.Norbye@Sun.COM) * Add --enable-64bit for mulitarget platforms (Trond.Norbye@Sun.COM) * Use gettimeofday(2) instead of time(2). * Make -k option work (Tomash Brechko) * Fix chunk slab alignment (Trond.Norbye@Sun.COM) 2007-12-06 [Version 1.2.4 released] 2007-12-05 * Fix compilation on panther (JS and Dormando) * More CAS tests (Chris Goffinet) * Final fixes for all 1.2.4 features are in, -rc2 sent out. 2007-11-19 [Version 1.2.4-rc1 released] 2007-11-19 Dormando * Patch series from Tomash Brechko : Minor fixes and optimisations. * Patches from Chris, Dustin, and Dormando to fix CAS. * Prepping for 1.2.4 release. 2007-11-13 Dormando * Adjusted patch from js : Compile on OS X Panther and earlier. 2007-11-12 Steven Grimm * Patch from Tomash Brechko : Always send "SERVER_ERROR out of memory" when memory exhausted. 2007-10-15 Paul Lindner * Patch from David Bremner that implements a new option "-a" which takes an octal permission mask (like chmod) sets the permissions on the unix domain socket (specified by "-s"). 2007-10-03 Paul Lindner * Incorporate "cas" operation developed by Dustin Sallings This change allows you to do atomic changes to an existing key. * Fix for stats.evictions not incrementing when exptime == 0 items are kicked off the cache. from Jean-Francois BUSTARRET . * Fix for do_item_cachedump() which was returning an incorrect timestamp. * Switch to unsigned 64-bit increment/decrement counters from Evan Miller and Dustin Sallings. * Add append command support written by Filipe Laborde. Thread safe version plus prepend command from Maxim Dounin * The memcached-tool script can now display stats. Patch provided by Dan Christian * Fix for Unix Domain sockets on FreeBSD FreeBSD's sendmsg() requires msg_name in msghdr structure to be NULL if not used, setting msg_namelen to 0 isn't enough. Patch from Maxim Dounin 2007-08-21 Paul Lindner * Incorporate incrememnt patch from Evan Miller to define increment overflow behavior. 2007-08-07 Leon Brocard * Bring the memcached.1 manpage up to date 2007-08-06 Paul Lindner * Fix crash when using -P and -d flags on x86_64 with latest libevent release. 2007-07-08 Steven Grimm * Item stats commands weren't thread-safe; wrap them with locks when compiled in multithreaded mode. * The "stats items" command now works again; it broke with the introduction of the powers-of-N chunk size change. 2007-07-06 [Version 1.2.3 released] 2007-06-19 Paul Lindner * Solaris portability fixes from Trond Norbye 2007-05-29 Paul Lindner * Properly document evictions statistic value 2007-05-10 Paul Lindner * Flesh out tests for unix domain sockets and binary data. * Update rpm spec file to run tests 2007-05-07 Paul Lindner * Fix compilation bug on freebsd 6.x (and maybe others) * Update RPM spec file per redhat bugzilla #238994 * Move unistd.h to memcached.h to get rid of warnings * Add string.h to thread.c to get correctly prototyped strerror() 2007-05-04 Paul Lindner * Add fedora/redhat style init script and RPM spec file 2007-05-12 [Version 1.2.2 released] 2007-04-16 Steven Grimm * Command tokenizer performance and cleanliness improvement. Patch contributed by Paolo Borelli . 2007-04-16 Paul Lindner * Add notes to README about MacOS, libevent and kqueue. * Windows Patch integration -- part 1, warnings elimination. 2007-04-12 Paul Lindner * Allow changes to the verbosity level of the server with a new "verbosity" command and some compiler cleanups. Patch contributed by Paolo Borelli . 2007-04-08 Paul Lindner * Add cleanup patch from "Tim Yardley" to clean up source spacing issues, fix -Wall warnings, add some null checks, adds asserts at the top of each function for any use of conn *c without checking to see if c is NULL first. * Also adjust clean-whitespace.pl to clean *.ac files. Add script to test-suite to test for tabs. 2007-04-04 Paul Lindner * Add clarification of flush_all in the protocol docs from Elizabeth Mattijsen 2007-03-31 Paul Lindner * Add patch from Eli Bingham to re-enable the -n switch to memcached. 2007-03-20 Paul Lindner * Add patch to collect eviction statistics from Jean-Francois BUSTARRET . * Updated docs, added new test cases for t/stats.t 2007-03-18 Paul Lindner * Add more test cases using larger buffer sizes up to and greater than 1MB. * Remove unused parameter to item_size_ok() * Use a single printf() in usage() * Add a failing test for conforming with maximum connections. 2007-03-17 * crash fix from Thomas van Gulick in conn_shrink(), passing &ptr, instead of ptr to realloc(). 2007-03-05 Paul Lindner * Fix a number of places where (s)printf calls were using unsigned or signed formats that did not match their arguments. * Add support for stdbool.h and stdint.h to use the bool and uint8_t types. * Major refactoring - move API calls for assoc/items/slabs to their own individual header files. Add apropriate const and static declarations as appropriate. * Avoid type-punning. Do a more efficient realloc inside the conn_shrink routine. * Fix overflow bug where uninitialized access to slabclass caused size-0 mallocs during slab preallocation. * Use EXIT_SUCCESS/EXIT_FAILURE constants. * Convert some sprintf calls to snprintf to protect against buffer overflows. * Explicitly compare against NULL or zero in many places. 2007-03-05 * Steven Grimm : Per-object-type stats collection support. Specify the object type delimiter with the -D command line option. Turn stats gathering on and off with "stats detail on" and "stats detail off". Dump the per-object-type details with "stats detail dump". 2007-03-01 * Steven Grimm : Fix an off-by-one error in the multithreaded version's message passing code. 2006-12-23 * fix expirations of items set with absolute expiration times in the past, before the server's start time. bug was introduced in 1.2.0 with rel_time_t. Thanks to Adam Dixon for the bug report and test case! 2006-11-26 * Steven Grimm : Performance improvements: Dynamic sizing of hashtable to reduce collisions on very large caches and conserve memory on small caches. Only reposition items in the LRU queue once a minute, to reduce overhead of accessing extremely frequently-used items. Stop listening for new connections until an existing one closes if we run out of available file descriptors. Command parser refactoring: Add a single-pass tokenizer to cut down on string scanning. Split the command processing into separate functions for easier profiling and better readability. Pass key lengths along with the keys in all API functions that need keys, to avoid needing to call strlen() repeatedly. 2006-11-25 * Steve Peters : OpenBSD has a malloc.h, but warns to use stdlib.h instead 2006-11-22 * Steven Grimm : Add support for multithreaded execution. Run configure with "--enable-threads" to enable. See doc/threads.txt for details. 2006-11-13 * Iain Wade : Fix for UDP responses on non-"get" commands. 2006-10-15 * Steven Grimm : Dynamic sizing of hashtable to reduce collisions on very large caches and conserve memory on small caches. 2006-10-13 * Steven Grimm : New faster hash function. 2006-09-20 * don't listen on UDP by default; more clear message when UDP port in use 2006-09-09 * release 1.2.0 (along with 1.1.13, which is the more tested branch) nobody has run 1.2.0 in production, to my knowledge. facebook has run their pre-merge-with-trunk version, but bugs were discovered (and fixed) after the merge. there might be more. you've been warned. :) 2006-09-04 * improved autoconf libevent detection, from the Tor project. 2006-09-03 * test suite and lot of expiration, delete, flush_all, etc corner case bugs fixed (Brad Fitzpatrick) 2006-09-02 * Nathan Neulinger : fix breakage in expiration code causing expiration times to not be processed correctly. 2006-08-21 * Nathan Neulinger : fix incompatabilities with unix domain socket support and the UDP code and clean up stale sockets 2006-08-20 * Nathan Neulinger : unix domain socket support 2006-05-03 * Steven Grimm : big bunch of changes: big CPU reduction work, UDP-based interface, increased memory efficiency. (intertwined patch, committed all together) or see svn commit logs 2006-04-30 * River Tarnell: autoconf work for Solaris 10. Brad: merge and verify it works on Nexenta. 2006-03-04 * avva: bucket/generation patch (old, but Brad's just finally committing it) 2006-01-01 * Brad Fitzpatrick : allocate 1 slab per class on start-up, to avoid confusing users with out-of-memory errors later. this is 18 MB of allocation on start, unless max memory allowed with -m is lower, in which case only the smaller slab classes are allocated. 2005-08-09 * Elizabeth Mattijsen : needed a way to flush all memcached backend servers, but not at exactly the same time (to reduce load peaks), I've added some simple functionality to the memcached protocol in the "flush_all" command that allows you to specify a time at which the flush will actually occur (instead of always at the moment the "flush_all" command is received). 2005-05-25 * patch from Peter van Dijk to make stderr unbuffered, for running under daemontools 2005-04-04 * patch from Don MacAskill 'flush_all' doesn't seem to work properly. Basically, if you try to add a key which is present, but expired, the store fails but the old key is no longer expired. * release 1.1.12 2005-01-14 * Date: Thu, 18 Nov 2004 15:25:59 -0600 From: David Phillips Here is a patch to configure.ac and Makefile.am to put the man page in the correct location. Trying to install the man page from a subdirectory results in the subdirectory being used in the install path (it tries to install to doc/memcached.1). This is the correct thing to do: - create a Makefile.am in the doc directory that installs the man page with man_MANS - modify Makefile.am in the base directory to reference the doc directory using SUBDIRS - modify the AC_CONFIG_FILES macro in configure.ac to output the Makefile in doc 2005-01-14 * pidfile saving support from Lisa Seelye , sent Jan 13, 2005 2005-01-14 * don't delete libevent events that haven't been added (the deltimer) patch from Ted Schundler 2004-12-10 * document -M and -r in manpage (Doug Porter ) 2004-07-22 * fix buffer overflow in items.c with 250 byte keys along with other info on the same line going into a 256 byte char[]. thanks to Andrei Nigmatulin 2004-06-15 * immediate deletes weren't being unlinked a few seconds, preventing "add" commands to the same key in that time period. thanks to Michael Alan Dorman for the bug report and demo script. 2004-04-30 * released 1.1.11 2004-04-24 * Avva: Add a new command line option: -r , to maximize core file limit. 2004-03-31 * Avva: Use getrlimit and setrlimit to set limits for number of simultaneously open file descriptors. Get the current limits and try to raise them if they're not enough for the specified (or the default) setting of max connections. 2004-02-24 * Adds a '-M' flag to turn off tossing items from the cache. (Jason Titus ) 2004-02-19 (Evan) * Install manpage on "make install", etc. 2003-12-30 (Brad) * remove static build stuff. interferes with PAM setuid stuff and was only included as a possible fix with the old memory allocator. really shouldn't make a difference. * add Jay Bonci's Debian scripts and manpage * release version 1.1.10 2003-12-01 (Avva) * New command: flush_all, causes all existing items to be invalidated immediately (without deleting them from memory, merely causing memcached to no longer return them). 2003-10-23 * Shift init code around to fix daemon mode on FreeBSD, * and drop root only after creating the server socket (to * allow the use of privileged ports) * version 1.1.10pre 2003-10-09 * BSD compile fixes from Ryan T. Dean * version 1.1.9 2003-09-29 * ignore SIGPIPE at start instead of crashing in rare cases it comes up. no other code had to be modified, since everything else is already dead-connection-aware. (avva) 2003-09-09 (Avva, Lisa Marie Seelye ) * setuid support 2003-09-05 (Avva) * accept all new connections in the same event (so we work with ET epoll) * mark all items as clsid=0 after slab page reassignment to please future asserts (on the road to making slab page reassignment work fully) 2003-08-12 (Brad Fitzpatrick) * use TCP_CORK on Linux or TCP_PUSH on BSD * only use TCP_NODELAY when we don't have alternatives 2003-08-10 * disable Nagel's Algorithm (TCP_NODELAY) for better performance (avva) 2003-08-10 * support multiple levels of verbosity (-vv) 2003-08-10 (Evan Martin) * Makefile.am: debug, optimization, and static flags are controlled by the configure script. * configure.ac: - allow specifying libevent directory with --with-libevent=DIR - check for malloc.h (unavailable on BSDs) - check for socklen_t (unavailable on OSX) * assoc.c, items.c, slabs.c: Remove some unused headers. * memcached.c: allow for nonexistence of malloc.h; #define a POSIX macro to import mlockall flags. 2003-07-29 * version 1.1.7 * big bug fix: item exptime 0 meant expire immediately, not never * version 1.1.8 2003-07-22 * make 'delete' take second arg, of time to refuse new add/replace * set/add/replace/delete can all take abs or delta time (delta can't be larger than a month) 2003-07-21 * added doc/protocol.txt 2003-07-01 * report CPU usage in stats 2003-06-30 * version 1.1.6 * fix a number of obscure bugs * more stats reporting 2003-06-10 * removing use of Judy; use a hash. (judy caused memory fragmentation) * shrink some structures * security improvements * version 1.1.0 2003-06-18 * changing maxsize back to an unsigned int 2003-06-16 * adding PHP support * added CONTRIBUTORS file * version 1.0.4 2003-06-15 * forgot to distribute website/api (still learning auto*) * version 1.0.3 2003-06-15 * update to version 1.0.2 * autoconf/automake fixes for older versions * make stats report version number * change license from GPL to BSD Fri, 13 Jun 2003 10:05:51 -0700 Evan Martin * configure.ac, autogen.sh, Makefile.am: Use autotools. * items.c, memcached.c: #include for time(), printf time_t as %lu (is this correct?), minor warnings fixes. memcached-1.4.14/COPYING0000644000175000017500000000273711246331452011475 00000000000000Copyright (c) 2003, Danga Interactive, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Danga Interactive 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. memcached-1.4.14/configure.ac0000644000175000017500000003623711712423271012731 00000000000000AC_PREREQ(2.52) m4_include([version.m4]) m4_include([m4/c99-backport.m4]) AC_INIT(memcached, VERSION_NUMBER, memcached@googlegroups.com) AC_CANONICAL_SYSTEM AC_CONFIG_SRCDIR(memcached.c) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AM_CONFIG_HEADER(config.h) AC_PROG_CC dnl ********************************************************************** dnl DETECT_ICC ([ACTION-IF-YES], [ACTION-IF-NO]) dnl dnl check if this is the Intel ICC compiler, and if so run the ACTION-IF-YES dnl sets the $ICC variable to "yes" or "no" dnl ********************************************************************** AC_DEFUN([DETECT_ICC], [ ICC="no" AC_MSG_CHECKING([for icc in use]) if test "$GCC" = "yes"; then dnl check if this is icc acting as gcc in disguise AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], AC_MSG_RESULT([no]) [$2], AC_MSG_RESULT([yes]) [$1] ICC="yes") else AC_MSG_RESULT([no]) [$2] fi ]) DETECT_ICC([], []) dnl ********************************************************************** dnl DETECT_SUNCC ([ACTION-IF-YES], [ACTION-IF-NO]) dnl dnl check if this is the Sun Studio compiler, and if so run the ACTION-IF-YES dnl sets the $SUNCC variable to "yes" or "no" dnl ********************************************************************** AC_DEFUN([DETECT_SUNCC], [ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) AS_IF(test "x$SUNCC" = "xyes", [$1], [$2]) ]) DETECT_SUNCC([CFLAGS="-mt $CFLAGS"], []) if test "$ICC" = "no"; then AC_PROG_CC_C99 fi AM_PROG_CC_C_O AC_PROG_INSTALL AC_ARG_ENABLE(sasl, [AS_HELP_STRING([--enable-sasl],[Enable SASL authentication])]) AC_ARG_ENABLE(sasl_pwdb, [AS_HELP_STRING([--enable-sasl-pwdb],[Enable plaintext password db])]) AS_IF([test "x$enable_sasl_pwdb" = "xyes"], [enable_sasl=yes ]) dnl ********************************************************************** dnl DETECT_SASL_CB_GETCONF dnl dnl check if we can use SASL_CB_GETCONF dnl ********************************************************************** AC_DEFUN([AC_C_DETECT_SASL_CB_GETCONF], [ AC_CACHE_CHECK([for SASL_CB_GETCONF], [ac_cv_c_sasl_cb_getconf], [AC_TRY_COMPILE( [ #include ], [ unsigned long val = SASL_CB_GETCONF; ], [ ac_cv_c_sasl_cb_getconf=yes ], [ ac_cv_c_sasl_cb_getconf=no ]) ]) AS_IF([test "$ac_cv_c_sasl_cb_getconf" = "yes"], [AC_DEFINE([HAVE_SASL_CB_GETCONF], 1, [Set to nonzero if your SASL implementation supports SASL_CB_GETCONF])]) ]) AC_CHECK_HEADERS([sasl/sasl.h]) if test "x$enable_sasl" = "xyes"; then AC_C_DETECT_SASL_CB_GETCONF AC_DEFINE([ENABLE_SASL],1,[Set to nonzero if you want to include SASL]) AC_SEARCH_LIBS([sasl_server_init], [sasl2 sasl], [], [ AC_MSG_ERROR([Failed to locate the library containing sasl_server_init]) ]) AS_IF([test "x$enable_sasl_pwdb" = "xyes"], [AC_DEFINE([ENABLE_SASL_PWDB], 1, [Set to nonzero if you want to enable a SASL pwdb])]) fi AC_ARG_ENABLE(dtrace, [AS_HELP_STRING([--enable-dtrace],[Enable dtrace probes])]) if test "x$enable_dtrace" = "xyes"; then AC_PATH_PROG([DTRACE], [dtrace], "no", [/usr/sbin:$PATH]) if test "x$DTRACE" != "xno"; then AC_DEFINE([ENABLE_DTRACE],1,[Set to nonzero if you want to include DTRACE]) build_dtrace=yes # DTrace on MacOSX does not use -G option $DTRACE -G -o conftest.$$ -s memcached_dtrace.d 2>/dev/zero if test $? -eq 0 then dtrace_instrument_obj=yes rm conftest.$$ fi if test "`which tr`" = "/usr/ucb/tr"; then AC_MSG_ERROR([Please remove /usr/ucb from your path. See man standards for more info]) fi else AC_MSG_ERROR([Need dtrace binary and OS support.]) fi fi AM_CONDITIONAL([BUILD_DTRACE],[test "$build_dtrace" = "yes"]) AM_CONDITIONAL([DTRACE_INSTRUMENT_OBJ],[test "$dtrace_instrument_obj" = "yes"]) AM_CONDITIONAL([ENABLE_SASL],[test "$enable_sasl" = "yes"]) AC_SUBST(DTRACE) AC_SUBST(DTRACEFLAGS) AC_SUBST(ENABLE_SASL) AC_SUBST(PROFILER_LDFLAGS) AC_ARG_ENABLE(coverage, [AS_HELP_STRING([--disable-coverage],[Disable code coverage])]) if test "x$enable_coverage" != "xno"; then if test "$ICC" = "yes" then dnl ICC trying to be gcc, but not well CFLAGS="$CFLAGS -pthread" elif test "$GCC" = "yes" then CFLAGS="$CFLAGS -pthread" AC_PATH_PROG([PROFILER], [gcov], "no", [$PATH]) if test "x$PROFILER" != "xno"; then # Issue 97: The existense of gcov doesn't mean we have -lgcov AC_CHECK_LIB(gcov, main, [ PROFILER_FLAGS="-fprofile-arcs -ftest-coverage" PROFILER_LDFLAGS="-lgcov" ], [ PROFILER_FLAGS= PROFILER_LDFLAGS= ]) fi elif test "$SUNCC" = "yes" then AC_PATH_PROG([PROFILER], [tcov], "no", [$PATH]) if test "x$PROFILER" != "xno"; then PROFILER_FLAGS=-xprofile=tcov fi fi fi AC_SUBST(PROFILER_FLAGS) AC_ARG_ENABLE(64bit, [AS_HELP_STRING([--enable-64bit],[build 64bit version])]) if test "x$enable_64bit" = "xyes" then org_cflags=$CFLAGS CFLAGS=-m64 AC_RUN_IFELSE( [AC_LANG_PROGRAM([], [dnl return sizeof(void*) == 8 ? 0 : 1; ]) ],[ CFLAGS="-m64 $org_cflags" ],[ AC_MSG_ERROR([Don't know how to build a 64-bit object.]) ]) fi # Issue 213: Search for clock_gettime to help people linking # with a static version of libevent AC_SEARCH_LIBS(clock_gettime, rt) # Issue 214: Search for the network libraries _before_ searching # for libevent (to help people linking with static libevent) AC_SEARCH_LIBS(socket, socket) AC_SEARCH_LIBS(gethostbyname, nsl) trylibeventdir="" AC_ARG_WITH(libevent, [ --with-libevent=PATH Specify path to libevent installation ], [ if test "x$withval" != "xno" ; then trylibeventdir=$withval fi ] ) dnl ------------------------------------------------------ dnl libevent detection. swiped from Tor. modified a bit. LIBEVENT_URL=http://www.monkey.org/~provos/libevent/ AC_CACHE_CHECK([for libevent directory], ac_cv_libevent_dir, [ saved_LIBS="$LIBS" saved_LDFLAGS="$LDFLAGS" saved_CPPFLAGS="$CPPFLAGS" le_found=no for ledir in $trylibeventdir "" $prefix /usr/local ; do LDFLAGS="$saved_LDFLAGS" LIBS="-levent $saved_LIBS" # Skip the directory if it isn't there. if test ! -z "$ledir" -a ! -d "$ledir" ; then continue; fi if test ! -z "$ledir" ; then if test -d "$ledir/lib" ; then LDFLAGS="-L$ledir/lib $LDFLAGS" else LDFLAGS="-L$ledir $LDFLAGS" fi if test -d "$ledir/include" ; then CPPFLAGS="-I$ledir/include $CPPFLAGS" else CPPFLAGS="-I$ledir $CPPFLAGS" fi fi # Can I compile and link it? AC_TRY_LINK([#include #include #include ], [ event_init(); ], [ libevent_linked=yes ], [ libevent_linked=no ]) if test $libevent_linked = yes; then if test ! -z "$ledir" ; then ac_cv_libevent_dir=$ledir _myos=`echo $target_os | cut -f 1 -d .` AS_IF(test "$SUNCC" = "yes" -o "x$_myos" = "xsolaris2", [saved_LDFLAGS="$saved_LDFLAGS -Wl,-R$ledir/lib"], [AS_IF(test "$GCC" = "yes", [saved_LDFLAGS="$saved_LDFLAGS -Wl,-rpath,$ledir/lib"])]) else ac_cv_libevent_dir="(system)" fi le_found=yes break fi done LIBS="$saved_LIBS" LDFLAGS="$saved_LDFLAGS" CPPFLAGS="$saved_CPPFLAGS" if test $le_found = no ; then AC_MSG_ERROR([libevent is required. You can get it from $LIBEVENT_URL If it's already installed, specify its path using --with-libevent=/dir/ ]) fi ]) LIBS="-levent $LIBS" if test $ac_cv_libevent_dir != "(system)"; then if test -d "$ac_cv_libevent_dir/lib" ; then LDFLAGS="-L$ac_cv_libevent_dir/lib $LDFLAGS" le_libdir="$ac_cv_libevent_dir/lib" else LDFLAGS="-L$ac_cv_libevent_dir $LDFLAGS" le_libdir="$ac_cv_libevent_dir" fi if test -d "$ac_cv_libevent_dir/include" ; then CPPFLAGS="-I$ac_cv_libevent_dir/include $CPPFLAGS" else CPPFLAGS="-I$ac_cv_libevent_dir $CPPFLAGS" fi fi dnl ---------------------------------------------------------------------------- AC_SEARCH_LIBS(umem_cache_create, umem) AC_SEARCH_LIBS(gethugepagesizes, hugetlbfs) AC_HEADER_STDBOOL AH_BOTTOM([#if HAVE_STDBOOL_H #include #else #define bool char #define false 0 #define true 1 #endif ]) AC_CHECK_HEADERS([inttypes.h]) AH_BOTTOM([#ifdef HAVE_INTTYPES_H #include #endif ]) dnl ********************************************************************** dnl Figure out if this system has the stupid sasl_callback_ft dnl ********************************************************************** AC_DEFUN([AC_HAVE_SASL_CALLBACK_FT], [AC_CACHE_CHECK(for sasl_callback_ft, ac_cv_has_sasl_callback_ft, [ AC_TRY_COMPILE([ #ifdef HAVE_SASL_SASL_H #include #include #endif ],[ sasl_callback_ft a_callback; ],[ ac_cv_has_sasl_callback_ft=yes ],[ ac_cv_has_sasl_callback_ft=no ]) ]) if test $ac_cv_has_sasl_callback_ft = yes; then AC_DEFINE(HAVE_SASL_CALLBACK_FT, 1, [we have sasl_callback_ft]) fi ]) AC_HAVE_SASL_CALLBACK_FT dnl ********************************************************************** dnl DETECT_UINT64_SUPPORT dnl dnl check if we can use a uint64_t dnl ********************************************************************** AC_DEFUN([AC_C_DETECT_UINT64_SUPPORT], [ AC_CACHE_CHECK([for print macros for integers (C99 section 7.8.1)], [ac_cv_c_uint64_support], [AC_TRY_COMPILE( [ #ifdef HAVE_INTTYPES_H #include #endif #include ], [ uint64_t val = 0; fprintf(stderr, "%" PRIu64 "\n", val); ], [ ac_cv_c_uint64_support=yes ], [ ac_cv_c_uint64_support=no ]) ]) ]) AC_C_DETECT_UINT64_SUPPORT AS_IF([test "x$ac_cv_c_uint64_support" = "xno"], [AC_MSG_WARN([ Failed to use print macros (PRIu) as defined in C99 section 7.8.1. ])]) AC_C_CONST dnl From licq: Copyright (c) 2000 Dirk Mueller dnl Check if the type socklen_t is defined anywhere AC_DEFUN([AC_C_SOCKLEN_T], [AC_CACHE_CHECK(for socklen_t, ac_cv_c_socklen_t, [ AC_TRY_COMPILE([ #include #include ],[ socklen_t foo; ],[ ac_cv_c_socklen_t=yes ],[ ac_cv_c_socklen_t=no ]) ]) if test $ac_cv_c_socklen_t = no; then AC_DEFINE(socklen_t, int, [define to int if socklen_t not available]) fi ]) AC_C_SOCKLEN_T dnl Check if we're a little-endian or a big-endian system, needed by hash code AC_DEFUN([AC_C_ENDIAN], [AC_CACHE_CHECK(for endianness, ac_cv_c_endian, [ AC_RUN_IFELSE( [AC_LANG_PROGRAM([], [dnl long val = 1; char *c = (char *) &val; exit(*c == 1); ]) ],[ ac_cv_c_endian=big ],[ ac_cv_c_endian=little ]) ]) if test $ac_cv_c_endian = big; then AC_DEFINE(ENDIAN_BIG, 1, [machine is bigendian]) fi if test $ac_cv_c_endian = little; then AC_DEFINE(ENDIAN_LITTLE, 1, [machine is littleendian]) fi ]) AC_C_ENDIAN AC_DEFUN([AC_C_HTONLL], [ AC_MSG_CHECKING([for htonll]) have_htoll="no" AC_TRY_LINK([ #include #include #ifdef HAVE_INTTYPES_H #include */ #endif ], [ return htonll(0); ], [ have_htoll="yes" AC_DEFINE([HAVE_HTONLL], [1], [Have ntohll]) ], [ have_htoll="no" ]) AC_MSG_RESULT([$have_htoll]) ]) AC_C_HTONLL dnl Check whether the user's system supports pthread AC_SEARCH_LIBS(pthread_create, pthread) if test "x$ac_cv_search_pthread_create" = "xno"; then AC_MSG_ERROR([Can't enable threads without the POSIX thread library.]) fi AC_CHECK_FUNCS(mlockall) AC_CHECK_FUNCS(getpagesizes) AC_CHECK_FUNCS(memcntl) AC_CHECK_FUNCS(sigignore) AC_CHECK_FUNCS(clock_gettime) AC_DEFUN([AC_C_ALIGNMENT], [AC_CACHE_CHECK(for alignment, ac_cv_c_alignment, [ AC_RUN_IFELSE( [AC_LANG_PROGRAM([ #include #include ], [ char *buf = malloc(32); uint64_t *ptr = (uint64_t*)(buf+2); // catch sigbus, etc. *ptr = 0x1; // catch unaligned word access (ARM cpus) *buf = 1; *(buf +1) = 2; *(buf + 2) = 2; *(buf + 3) = 3; *(buf + 4) = 4; int* i = (int*)(buf+1); return (84148994 == i) ? 0 : 1; ]) ],[ ac_cv_c_alignment=none ],[ ac_cv_c_alignment=need ],[ ac_cv_c_alignment=need ]) ]) if test $ac_cv_c_alignment = need; then AC_DEFINE(NEED_ALIGN, 1, [Machine need alignment]) fi ]) AC_C_ALIGNMENT dnl Check for our specific usage of GCC atomics. dnl These were added in 4.1.2, but 32bit OS's may lack shorts and 4.1.2 dnl lacks testable defines. have_gcc_atomics=no AC_MSG_CHECKING(for GCC atomics) AC_TRY_LINK([],[ unsigned short a; unsigned short b; b = __sync_add_and_fetch(&a, 1); b = __sync_sub_and_fetch(&a, 2); ],[have_gcc_atomics=yes AC_DEFINE(HAVE_GCC_ATOMICS, 1, [GCC Atomics available])]) AC_MSG_RESULT($have_gcc_atomics) dnl Check for the requirements for running memcached with less privileges dnl than the default privilege set. On Solaris we need setppriv and priv.h dnl If you want to add support for other platforms you should check for dnl your requirements, define HAVE_DROP_PRIVILEGES, and make sure you add dnl the source file containing the implementation into memcached_SOURCE dnl in Makefile.am AC_CHECK_FUNCS(setppriv, [ AC_CHECK_HEADER(priv.h, [ AC_DEFINE([HAVE_DROP_PRIVILEGES], 1, [Define this if you have an implementation of drop_privileges()]) build_solaris_privs=yes ], []) ],[]) AM_CONDITIONAL([BUILD_SOLARIS_PRIVS],[test "$build_solaris_privs" = "yes"]) AC_CHECK_HEADER(umem.h, [ AC_DEFINE([HAVE_UMEM_H], 1, [Define this if you have umem.h]) build_cache=no ], [build_cache=yes]) AM_CONDITIONAL([BUILD_CACHE], [test "x$build_cache" = "xyes"]) AC_ARG_ENABLE(docs, [AS_HELP_STRING([--disable-docs],[Disable documentation generation])]) AC_PATH_PROG([XML2RFC], [xml2rfc], "no") AC_PATH_PROG([XSLTPROC], [xsltproc], "no") AM_CONDITIONAL([BUILD_SPECIFICATIONS], [test "x$enable_docs" != "xno" -a "x$XML2RFC" != "xno" -a "x$XSLTPROC" != "xno"]) dnl Let the compiler be a bit more picky. Please note that you cannot dnl specify these flags to the compiler before AC_CHECK_FUNCS, because dnl the test program will generate a compilation warning and hence fail dnl to detect the function ;-) if test "$ICC" = "yes" then dnl ICC trying to be gcc. CFLAGS="$CFLAGS -diag-disable 187 -Wall -Werror" AC_DEFINE([_GNU_SOURCE],[1],[find sigignore on Linux]) elif test "$GCC" = "yes" then GCC_VERSION=`$CC -dumpversion` CFLAGS="$CFLAGS -Wall -Werror -pedantic -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls" case $GCC_VERSION in 4.4.*) CFLAGS="$CFLAGS -fno-strict-aliasing" ;; esac AC_DEFINE([_GNU_SOURCE],[1],[find sigignore on Linux]) elif test "$SUNCC" = "yes" then CFLAGS="$CFLAGS -errfmt=error -errwarn -errshort=tags" fi AC_CONFIG_FILES(Makefile doc/Makefile) AC_OUTPUT memcached-1.4.14/memcached.spec0000644000175000017500000000600312005572430013207 00000000000000Name: memcached Version: 1.4.14 Release: 1%{?dist} Summary: High Performance, Distributed Memory Object Cache Group: System Environment/Daemons License: BSD URL: http://www.danga.com/memcached/ Source0: http://memcached.googlecode.com/files/%{name}-1.4.14.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libevent-devel BuildRequires: perl(Test::More) BuildRequires: /usr/bin/prove Requires: initscripts Requires(post): /sbin/chkconfig Requires(preun): /sbin/chkconfig, /sbin/service Requires(postun): /sbin/service %description memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load. %prep %setup -q -n %{name}-1.4.14 %build %configure make %{?_smp_mflags} %check make test %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} # remove memcached-debug rm -f %{buildroot}/%{_bindir}/memcached-debug # Perl script for monitoring memcached install -Dp -m0755 scripts/memcached-tool %{buildroot}%{_bindir}/memcached-tool # Init script install -Dp -m0755 scripts/memcached.sysv %{buildroot}%{_initrddir}/memcached # Default configs mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig cat <%{buildroot}/%{_sysconfdir}/sysconfig/%{name} PORT="11211" USER="nobody" MAXCONN="1024" CACHESIZE="64" OPTIONS="" EOF # pid directory mkdir -p %{buildroot}/%{_localstatedir}/run/memcached %clean rm -rf %{buildroot} %post /sbin/chkconfig --add %{name} %preun if [ "$1" = 0 ] ; then /sbin/service %{name} stop > /dev/null 2>&1 /sbin/chkconfig --del %{name} fi exit 0 %postun if [ "$1" -ge 1 ]; then /sbin/service %{name} condrestart > /dev/null 2>&1 fi exit 0 %files %defattr(-,root,root,-) %doc AUTHORS ChangeLog COPYING NEWS README.md doc/CONTRIBUTORS doc/*.txt %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached %{_bindir}/memcached-tool %{_bindir}/memcached %{_mandir}/man1/memcached.1* %{_initrddir}/memcached %{_includedir}/memcached %changelog * Mon Nov 2 2009 Dormando - 1.4.3-1 - Fix autogen more. * Sat Aug 29 2009 Dustin Sallings - 1.4.1-1 - Autogenerate the version number from tags. * Wed Jul 4 2007 Paul Lindner - 1.2.2-5 - Use /var/run/memcached/ directory to hold PID file * Sat May 12 2007 Paul Lindner - 1.2.2-4 - Remove tabs from spec file, rpmlint reports no more errors * Thu May 10 2007 Paul Lindner - 1.2.2-3 - Enable build-time regression tests - add dependency on initscripts - remove memcached-debug (not needed in dist) - above suggestions from Bernard Johnson * Mon May 7 2007 Paul Lindner - 1.2.2-2 - Tidyness improvements suggested by Ruben Kerkhof in bugzilla #238994 * Fri May 4 2007 Paul Lindner - 1.2.2-1 - Initial spec file created via rpmdev-newspec memcached-1.4.14/thread.c0000644000175000017500000004756612005567145012072 00000000000000/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Thread management for memcached. */ #include "memcached.h" #include #include #include #include #include #include #include #ifdef __sun #include #endif #define ITEMS_PER_ALLOC 64 /* An item in the connection queue. */ typedef struct conn_queue_item CQ_ITEM; struct conn_queue_item { int sfd; enum conn_states init_state; int event_flags; int read_buffer_size; enum network_transport transport; CQ_ITEM *next; }; /* A connection queue. */ typedef struct conn_queue CQ; struct conn_queue { CQ_ITEM *head; CQ_ITEM *tail; pthread_mutex_t lock; pthread_cond_t cond; }; /* Lock for cache operations (item_*, assoc_*) */ pthread_mutex_t cache_lock; /* Connection lock around accepting new connections */ pthread_mutex_t conn_lock = PTHREAD_MUTEX_INITIALIZER; #if !defined(HAVE_GCC_ATOMICS) && !defined(__sun) pthread_mutex_t atomics_mutex = PTHREAD_MUTEX_INITIALIZER; #endif /* Lock for global stats */ static pthread_mutex_t stats_lock; /* Free list of CQ_ITEM structs */ static CQ_ITEM *cqi_freelist; static pthread_mutex_t cqi_freelist_lock; static pthread_mutex_t *item_locks; /* size of the item lock hash table */ static uint32_t item_lock_count; /* size - 1 for lookup masking */ static uint32_t item_lock_mask; static LIBEVENT_DISPATCHER_THREAD dispatcher_thread; /* * Each libevent instance has a wakeup pipe, which other threads * can use to signal that they've put a new connection on its queue. */ static LIBEVENT_THREAD *threads; /* * Number of worker threads that have finished setting themselves up. */ static int init_count = 0; static pthread_mutex_t init_lock; static pthread_cond_t init_cond; static void thread_libevent_process(int fd, short which, void *arg); unsigned short refcount_incr(unsigned short *refcount) { #ifdef HAVE_GCC_ATOMICS return __sync_add_and_fetch(refcount, 1); #elif defined(__sun) return atomic_inc_ushort_nv(refcount); #else unsigned short res; mutex_lock(&atomics_mutex); (*refcount)++; res = *refcount; mutex_unlock(&atomics_mutex); return res; #endif } unsigned short refcount_decr(unsigned short *refcount) { #ifdef HAVE_GCC_ATOMICS return __sync_sub_and_fetch(refcount, 1); #elif defined(__sun) return atomic_dec_ushort_nv(refcount); #else unsigned short res; mutex_lock(&atomics_mutex); (*refcount)--; res = *refcount; mutex_unlock(&atomics_mutex); return res; #endif } void item_lock(uint32_t hv) { mutex_lock(&item_locks[hv & item_lock_mask]); } void item_unlock(uint32_t hv) { mutex_unlock(&item_locks[hv & item_lock_mask]); } /* * Initializes a connection queue. */ static void cq_init(CQ *cq) { pthread_mutex_init(&cq->lock, NULL); pthread_cond_init(&cq->cond, NULL); cq->head = NULL; cq->tail = NULL; } /* * Looks for an item on a connection queue, but doesn't block if there isn't * one. * Returns the item, or NULL if no item is available */ static CQ_ITEM *cq_pop(CQ *cq) { CQ_ITEM *item; pthread_mutex_lock(&cq->lock); item = cq->head; if (NULL != item) { cq->head = item->next; if (NULL == cq->head) cq->tail = NULL; } pthread_mutex_unlock(&cq->lock); return item; } /* * Adds an item to a connection queue. */ static void cq_push(CQ *cq, CQ_ITEM *item) { item->next = NULL; pthread_mutex_lock(&cq->lock); if (NULL == cq->tail) cq->head = item; else cq->tail->next = item; cq->tail = item; pthread_cond_signal(&cq->cond); pthread_mutex_unlock(&cq->lock); } /* * Returns a fresh connection queue item. */ static CQ_ITEM *cqi_new(void) { CQ_ITEM *item = NULL; pthread_mutex_lock(&cqi_freelist_lock); if (cqi_freelist) { item = cqi_freelist; cqi_freelist = item->next; } pthread_mutex_unlock(&cqi_freelist_lock); if (NULL == item) { int i; /* Allocate a bunch of items at once to reduce fragmentation */ item = malloc(sizeof(CQ_ITEM) * ITEMS_PER_ALLOC); if (NULL == item) return NULL; /* * Link together all the new items except the first one * (which we'll return to the caller) for placement on * the freelist. */ for (i = 2; i < ITEMS_PER_ALLOC; i++) item[i - 1].next = &item[i]; pthread_mutex_lock(&cqi_freelist_lock); item[ITEMS_PER_ALLOC - 1].next = cqi_freelist; cqi_freelist = &item[1]; pthread_mutex_unlock(&cqi_freelist_lock); } return item; } /* * Frees a connection queue item (adds it to the freelist.) */ static void cqi_free(CQ_ITEM *item) { pthread_mutex_lock(&cqi_freelist_lock); item->next = cqi_freelist; cqi_freelist = item; pthread_mutex_unlock(&cqi_freelist_lock); } /* * Creates a worker thread. */ static void create_worker(void *(*func)(void *), void *arg) { pthread_t thread; pthread_attr_t attr; int ret; pthread_attr_init(&attr); if ((ret = pthread_create(&thread, &attr, func, arg)) != 0) { fprintf(stderr, "Can't create thread: %s\n", strerror(ret)); exit(1); } } /* * Sets whether or not we accept new connections. */ void accept_new_conns(const bool do_accept) { pthread_mutex_lock(&conn_lock); do_accept_new_conns(do_accept); pthread_mutex_unlock(&conn_lock); } /****************************** LIBEVENT THREADS *****************************/ /* * Set up a thread's information. */ static void setup_thread(LIBEVENT_THREAD *me) { me->base = event_init(); if (! me->base) { fprintf(stderr, "Can't allocate event base\n"); exit(1); } /* Listen for notifications from other threads */ event_set(&me->notify_event, me->notify_receive_fd, EV_READ | EV_PERSIST, thread_libevent_process, me); event_base_set(me->base, &me->notify_event); if (event_add(&me->notify_event, 0) == -1) { fprintf(stderr, "Can't monitor libevent notify pipe\n"); exit(1); } me->new_conn_queue = malloc(sizeof(struct conn_queue)); if (me->new_conn_queue == NULL) { perror("Failed to allocate memory for connection queue"); exit(EXIT_FAILURE); } cq_init(me->new_conn_queue); if (pthread_mutex_init(&me->stats.mutex, NULL) != 0) { perror("Failed to initialize mutex"); exit(EXIT_FAILURE); } me->suffix_cache = cache_create("suffix", SUFFIX_SIZE, sizeof(char*), NULL, NULL); if (me->suffix_cache == NULL) { fprintf(stderr, "Failed to create suffix cache\n"); exit(EXIT_FAILURE); } } /* * Worker thread: main event loop */ static void *worker_libevent(void *arg) { LIBEVENT_THREAD *me = arg; /* Any per-thread setup can happen here; thread_init() will block until * all threads have finished initializing. */ pthread_mutex_lock(&init_lock); init_count++; pthread_cond_signal(&init_cond); pthread_mutex_unlock(&init_lock); event_base_loop(me->base, 0); return NULL; } /* * Processes an incoming "handle a new connection" item. This is called when * input arrives on the libevent wakeup pipe. */ static void thread_libevent_process(int fd, short which, void *arg) { LIBEVENT_THREAD *me = arg; CQ_ITEM *item; char buf[1]; if (read(fd, buf, 1) != 1) if (settings.verbose > 0) fprintf(stderr, "Can't read from libevent pipe\n"); item = cq_pop(me->new_conn_queue); if (NULL != item) { conn *c = conn_new(item->sfd, item->init_state, item->event_flags, item->read_buffer_size, item->transport, me->base); if (c == NULL) { if (IS_UDP(item->transport)) { fprintf(stderr, "Can't listen for events on UDP socket\n"); exit(1); } else { if (settings.verbose > 0) { fprintf(stderr, "Can't listen for events on fd %d\n", item->sfd); } close(item->sfd); } } else { c->thread = me; } cqi_free(item); } } /* Which thread we assigned a connection to most recently. */ static int last_thread = -1; /* * Dispatches a new connection to another thread. This is only ever called * from the main thread, either during initialization (for UDP) or because * of an incoming connection. */ void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum network_transport transport) { CQ_ITEM *item = cqi_new(); int tid = (last_thread + 1) % settings.num_threads; LIBEVENT_THREAD *thread = threads + tid; last_thread = tid; item->sfd = sfd; item->init_state = init_state; item->event_flags = event_flags; item->read_buffer_size = read_buffer_size; item->transport = transport; cq_push(thread->new_conn_queue, item); MEMCACHED_CONN_DISPATCH(sfd, thread->thread_id); if (write(thread->notify_send_fd, "", 1) != 1) { perror("Writing to thread notify pipe"); } } /* * Returns true if this is the thread that listens for new TCP connections. */ int is_listen_thread() { return pthread_self() == dispatcher_thread.thread_id; } /********************************* ITEM ACCESS *******************************/ /* * Allocates a new item. */ item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes) { item *it; /* do_item_alloc handles its own locks */ it = do_item_alloc(key, nkey, flags, exptime, nbytes); return it; } /* * Returns an item if it hasn't been marked as expired, * lazy-expiring as needed. */ item *item_get(const char *key, const size_t nkey) { item *it; uint32_t hv; hv = hash(key, nkey, 0); item_lock(hv); it = do_item_get(key, nkey, hv); item_unlock(hv); return it; } item *item_touch(const char *key, size_t nkey, uint32_t exptime) { item *it; uint32_t hv; hv = hash(key, nkey, 0); item_lock(hv); it = do_item_touch(key, nkey, exptime, hv); item_unlock(hv); return it; } /* * Links an item into the LRU and hashtable. */ int item_link(item *item) { int ret; uint32_t hv; hv = hash(ITEM_key(item), item->nkey, 0); item_lock(hv); ret = do_item_link(item, hv); item_unlock(hv); return ret; } /* * Decrements the reference count on an item and adds it to the freelist if * needed. */ void item_remove(item *item) { uint32_t hv; hv = hash(ITEM_key(item), item->nkey, 0); item_lock(hv); do_item_remove(item); item_unlock(hv); } /* * Replaces one item with another in the hashtable. * Unprotected by a mutex lock since the core server does not require * it to be thread-safe. */ int item_replace(item *old_it, item *new_it, const uint32_t hv) { return do_item_replace(old_it, new_it, hv); } /* * Unlinks an item from the LRU and hashtable. */ void item_unlink(item *item) { uint32_t hv; hv = hash(ITEM_key(item), item->nkey, 0); item_lock(hv); do_item_unlink(item, hv); item_unlock(hv); } /* * Moves an item to the back of the LRU queue. */ void item_update(item *item) { uint32_t hv; hv = hash(ITEM_key(item), item->nkey, 0); item_lock(hv); do_item_update(item); item_unlock(hv); } /* * Does arithmetic on a numeric item value. */ enum delta_result_type add_delta(conn *c, const char *key, const size_t nkey, int incr, const int64_t delta, char *buf, uint64_t *cas) { enum delta_result_type ret; uint32_t hv; hv = hash(key, nkey, 0); item_lock(hv); ret = do_add_delta(c, key, nkey, incr, delta, buf, cas, hv); item_unlock(hv); return ret; } /* * Stores an item in the cache (high level, obeys set/add/replace semantics) */ enum store_item_type store_item(item *item, int comm, conn* c) { enum store_item_type ret; uint32_t hv; hv = hash(ITEM_key(item), item->nkey, 0); item_lock(hv); ret = do_store_item(item, comm, c, hv); item_unlock(hv); return ret; } /* * Flushes expired items after a flush_all call */ void item_flush_expired() { mutex_lock(&cache_lock); do_item_flush_expired(); mutex_unlock(&cache_lock); } /* * Dumps part of the cache */ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int *bytes) { char *ret; mutex_lock(&cache_lock); ret = do_item_cachedump(slabs_clsid, limit, bytes); mutex_unlock(&cache_lock); return ret; } /* * Dumps statistics about slab classes */ void item_stats(ADD_STAT add_stats, void *c) { mutex_lock(&cache_lock); do_item_stats(add_stats, c); mutex_unlock(&cache_lock); } /* * Dumps a list of objects of each size in 32-byte increments */ void item_stats_sizes(ADD_STAT add_stats, void *c) { mutex_lock(&cache_lock); do_item_stats_sizes(add_stats, c); mutex_unlock(&cache_lock); } /******************************* GLOBAL STATS ******************************/ void STATS_LOCK() { pthread_mutex_lock(&stats_lock); } void STATS_UNLOCK() { pthread_mutex_unlock(&stats_lock); } void threadlocal_stats_reset(void) { int ii, sid; for (ii = 0; ii < settings.num_threads; ++ii) { pthread_mutex_lock(&threads[ii].stats.mutex); threads[ii].stats.get_cmds = 0; threads[ii].stats.get_misses = 0; threads[ii].stats.touch_cmds = 0; threads[ii].stats.touch_misses = 0; threads[ii].stats.delete_misses = 0; threads[ii].stats.incr_misses = 0; threads[ii].stats.decr_misses = 0; threads[ii].stats.cas_misses = 0; threads[ii].stats.bytes_read = 0; threads[ii].stats.bytes_written = 0; threads[ii].stats.flush_cmds = 0; threads[ii].stats.conn_yields = 0; threads[ii].stats.auth_cmds = 0; threads[ii].stats.auth_errors = 0; for(sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) { threads[ii].stats.slab_stats[sid].set_cmds = 0; threads[ii].stats.slab_stats[sid].get_hits = 0; threads[ii].stats.slab_stats[sid].touch_hits = 0; threads[ii].stats.slab_stats[sid].delete_hits = 0; threads[ii].stats.slab_stats[sid].incr_hits = 0; threads[ii].stats.slab_stats[sid].decr_hits = 0; threads[ii].stats.slab_stats[sid].cas_hits = 0; threads[ii].stats.slab_stats[sid].cas_badval = 0; } pthread_mutex_unlock(&threads[ii].stats.mutex); } } void threadlocal_stats_aggregate(struct thread_stats *stats) { int ii, sid; /* The struct has a mutex, but we can safely set the whole thing * to zero since it is unused when aggregating. */ memset(stats, 0, sizeof(*stats)); for (ii = 0; ii < settings.num_threads; ++ii) { pthread_mutex_lock(&threads[ii].stats.mutex); stats->get_cmds += threads[ii].stats.get_cmds; stats->get_misses += threads[ii].stats.get_misses; stats->touch_cmds += threads[ii].stats.touch_cmds; stats->touch_misses += threads[ii].stats.touch_misses; stats->delete_misses += threads[ii].stats.delete_misses; stats->decr_misses += threads[ii].stats.decr_misses; stats->incr_misses += threads[ii].stats.incr_misses; stats->cas_misses += threads[ii].stats.cas_misses; stats->bytes_read += threads[ii].stats.bytes_read; stats->bytes_written += threads[ii].stats.bytes_written; stats->flush_cmds += threads[ii].stats.flush_cmds; stats->conn_yields += threads[ii].stats.conn_yields; stats->auth_cmds += threads[ii].stats.auth_cmds; stats->auth_errors += threads[ii].stats.auth_errors; for (sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) { stats->slab_stats[sid].set_cmds += threads[ii].stats.slab_stats[sid].set_cmds; stats->slab_stats[sid].get_hits += threads[ii].stats.slab_stats[sid].get_hits; stats->slab_stats[sid].touch_hits += threads[ii].stats.slab_stats[sid].touch_hits; stats->slab_stats[sid].delete_hits += threads[ii].stats.slab_stats[sid].delete_hits; stats->slab_stats[sid].decr_hits += threads[ii].stats.slab_stats[sid].decr_hits; stats->slab_stats[sid].incr_hits += threads[ii].stats.slab_stats[sid].incr_hits; stats->slab_stats[sid].cas_hits += threads[ii].stats.slab_stats[sid].cas_hits; stats->slab_stats[sid].cas_badval += threads[ii].stats.slab_stats[sid].cas_badval; } pthread_mutex_unlock(&threads[ii].stats.mutex); } } void slab_stats_aggregate(struct thread_stats *stats, struct slab_stats *out) { int sid; out->set_cmds = 0; out->get_hits = 0; out->touch_hits = 0; out->delete_hits = 0; out->incr_hits = 0; out->decr_hits = 0; out->cas_hits = 0; out->cas_badval = 0; for (sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) { out->set_cmds += stats->slab_stats[sid].set_cmds; out->get_hits += stats->slab_stats[sid].get_hits; out->touch_hits += stats->slab_stats[sid].touch_hits; out->delete_hits += stats->slab_stats[sid].delete_hits; out->decr_hits += stats->slab_stats[sid].decr_hits; out->incr_hits += stats->slab_stats[sid].incr_hits; out->cas_hits += stats->slab_stats[sid].cas_hits; out->cas_badval += stats->slab_stats[sid].cas_badval; } } /* * Initializes the thread subsystem, creating various worker threads. * * nthreads Number of worker event handler threads to spawn * main_base Event base for main thread */ void thread_init(int nthreads, struct event_base *main_base) { int i; int power; pthread_mutex_init(&cache_lock, NULL); pthread_mutex_init(&stats_lock, NULL); pthread_mutex_init(&init_lock, NULL); pthread_cond_init(&init_cond, NULL); pthread_mutex_init(&cqi_freelist_lock, NULL); cqi_freelist = NULL; /* Want a wide lock table, but don't waste memory */ if (nthreads < 3) { power = 10; } else if (nthreads < 4) { power = 11; } else if (nthreads < 5) { power = 12; } else { /* 8192 buckets, and central locks don't scale much past 5 threads */ power = 13; } item_lock_count = ((unsigned long int)1 << (power)); item_lock_mask = item_lock_count - 1; item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t)); if (! item_locks) { perror("Can't allocate item locks"); exit(1); } for (i = 0; i < item_lock_count; i++) { pthread_mutex_init(&item_locks[i], NULL); } threads = calloc(nthreads, sizeof(LIBEVENT_THREAD)); if (! threads) { perror("Can't allocate thread descriptors"); exit(1); } dispatcher_thread.base = main_base; dispatcher_thread.thread_id = pthread_self(); for (i = 0; i < nthreads; i++) { int fds[2]; if (pipe(fds)) { perror("Can't create notify pipe"); exit(1); } threads[i].notify_receive_fd = fds[0]; threads[i].notify_send_fd = fds[1]; setup_thread(&threads[i]); /* Reserve three fds for the libevent base, and two for the pipe */ stats.reserved_fds += 5; } /* Create threads after we've done all the libevent setup. */ for (i = 0; i < nthreads; i++) { create_worker(worker_libevent, &threads[i]); } /* Wait for all the threads to set themselves up before returning. */ pthread_mutex_lock(&init_lock); while (init_count < nthreads) { pthread_cond_wait(&init_cond, &init_lock); } pthread_mutex_unlock(&init_lock); } memcached-1.4.14/protocol_binary.h0000644000175000017500000004021411701635506014013 00000000000000/* * Copyright (c) <2008>, Sun Microsystems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the 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 SUN MICROSYSTEMS, INC. ``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 SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, 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. */ /* * Summary: Constants used by to implement the binary protocol. * * Copy: See Copyright for the status of this software. * * Author: Trond Norbye */ #ifndef PROTOCOL_BINARY_H #define PROTOCOL_BINARY_H /** * This file contains definitions of the constants and packet formats * defined in the binary specification. Please note that you _MUST_ remember * to convert each multibyte field to / from network byte order to / from * host order. */ #ifdef __cplusplus extern "C" { #endif /** * Definition of the legal "magic" values used in a packet. * See section 3.1 Magic byte */ typedef enum { PROTOCOL_BINARY_REQ = 0x80, PROTOCOL_BINARY_RES = 0x81 } protocol_binary_magic; /** * Definition of the valid response status numbers. * See section 3.2 Response Status */ typedef enum { PROTOCOL_BINARY_RESPONSE_SUCCESS = 0x00, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT = 0x01, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS = 0x02, PROTOCOL_BINARY_RESPONSE_E2BIG = 0x03, PROTOCOL_BINARY_RESPONSE_EINVAL = 0x04, PROTOCOL_BINARY_RESPONSE_NOT_STORED = 0x05, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL = 0x06, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR = 0x20, PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE = 0x21, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND = 0x81, PROTOCOL_BINARY_RESPONSE_ENOMEM = 0x82 } protocol_binary_response_status; /** * Defintion of the different command opcodes. * See section 3.3 Command Opcodes */ typedef enum { PROTOCOL_BINARY_CMD_GET = 0x00, PROTOCOL_BINARY_CMD_SET = 0x01, PROTOCOL_BINARY_CMD_ADD = 0x02, PROTOCOL_BINARY_CMD_REPLACE = 0x03, PROTOCOL_BINARY_CMD_DELETE = 0x04, PROTOCOL_BINARY_CMD_INCREMENT = 0x05, PROTOCOL_BINARY_CMD_DECREMENT = 0x06, PROTOCOL_BINARY_CMD_QUIT = 0x07, PROTOCOL_BINARY_CMD_FLUSH = 0x08, PROTOCOL_BINARY_CMD_GETQ = 0x09, PROTOCOL_BINARY_CMD_NOOP = 0x0a, PROTOCOL_BINARY_CMD_VERSION = 0x0b, PROTOCOL_BINARY_CMD_GETK = 0x0c, PROTOCOL_BINARY_CMD_GETKQ = 0x0d, PROTOCOL_BINARY_CMD_APPEND = 0x0e, PROTOCOL_BINARY_CMD_PREPEND = 0x0f, PROTOCOL_BINARY_CMD_STAT = 0x10, PROTOCOL_BINARY_CMD_SETQ = 0x11, PROTOCOL_BINARY_CMD_ADDQ = 0x12, PROTOCOL_BINARY_CMD_REPLACEQ = 0x13, PROTOCOL_BINARY_CMD_DELETEQ = 0x14, PROTOCOL_BINARY_CMD_INCREMENTQ = 0x15, PROTOCOL_BINARY_CMD_DECREMENTQ = 0x16, PROTOCOL_BINARY_CMD_QUITQ = 0x17, PROTOCOL_BINARY_CMD_FLUSHQ = 0x18, PROTOCOL_BINARY_CMD_APPENDQ = 0x19, PROTOCOL_BINARY_CMD_PREPENDQ = 0x1a, PROTOCOL_BINARY_CMD_TOUCH = 0x1c, PROTOCOL_BINARY_CMD_GAT = 0x1d, PROTOCOL_BINARY_CMD_GATQ = 0x1e, PROTOCOL_BINARY_CMD_GATK = 0x23, PROTOCOL_BINARY_CMD_GATKQ = 0x24, PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 0x20, PROTOCOL_BINARY_CMD_SASL_AUTH = 0x21, PROTOCOL_BINARY_CMD_SASL_STEP = 0x22, /* These commands are used for range operations and exist within * this header for use in other projects. Range operations are * not expected to be implemented in the memcached server itself. */ PROTOCOL_BINARY_CMD_RGET = 0x30, PROTOCOL_BINARY_CMD_RSET = 0x31, PROTOCOL_BINARY_CMD_RSETQ = 0x32, PROTOCOL_BINARY_CMD_RAPPEND = 0x33, PROTOCOL_BINARY_CMD_RAPPENDQ = 0x34, PROTOCOL_BINARY_CMD_RPREPEND = 0x35, PROTOCOL_BINARY_CMD_RPREPENDQ = 0x36, PROTOCOL_BINARY_CMD_RDELETE = 0x37, PROTOCOL_BINARY_CMD_RDELETEQ = 0x38, PROTOCOL_BINARY_CMD_RINCR = 0x39, PROTOCOL_BINARY_CMD_RINCRQ = 0x3a, PROTOCOL_BINARY_CMD_RDECR = 0x3b, PROTOCOL_BINARY_CMD_RDECRQ = 0x3c /* End Range operations */ } protocol_binary_command; /** * Definition of the data types in the packet * See section 3.4 Data Types */ typedef enum { PROTOCOL_BINARY_RAW_BYTES = 0x00 } protocol_binary_datatypes; /** * Definition of the header structure for a request packet. * See section 2 */ typedef union { struct { uint8_t magic; uint8_t opcode; uint16_t keylen; uint8_t extlen; uint8_t datatype; uint16_t reserved; uint32_t bodylen; uint32_t opaque; uint64_t cas; } request; uint8_t bytes[24]; } protocol_binary_request_header; /** * Definition of the header structure for a response packet. * See section 2 */ typedef union { struct { uint8_t magic; uint8_t opcode; uint16_t keylen; uint8_t extlen; uint8_t datatype; uint16_t status; uint32_t bodylen; uint32_t opaque; uint64_t cas; } response; uint8_t bytes[24]; } protocol_binary_response_header; /** * Definition of a request-packet containing no extras */ typedef union { struct { protocol_binary_request_header header; } message; uint8_t bytes[sizeof(protocol_binary_request_header)]; } protocol_binary_request_no_extras; /** * Definition of a response-packet containing no extras */ typedef union { struct { protocol_binary_response_header header; } message; uint8_t bytes[sizeof(protocol_binary_response_header)]; } protocol_binary_response_no_extras; /** * Definition of the packet used by the get, getq, getk and getkq command. * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_get; typedef protocol_binary_request_no_extras protocol_binary_request_getq; typedef protocol_binary_request_no_extras protocol_binary_request_getk; typedef protocol_binary_request_no_extras protocol_binary_request_getkq; /** * Definition of the packet returned from a successful get, getq, getk and * getkq. * See section 4 */ typedef union { struct { protocol_binary_response_header header; struct { uint32_t flags; } body; } message; uint8_t bytes[sizeof(protocol_binary_response_header) + 4]; } protocol_binary_response_get; typedef protocol_binary_response_get protocol_binary_response_getq; typedef protocol_binary_response_get protocol_binary_response_getk; typedef protocol_binary_response_get protocol_binary_response_getkq; /** * Definition of the packet used by the delete command * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_delete; /** * Definition of the packet returned by the delete command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_delete; /** * Definition of the packet used by the flush command * See section 4 * Please note that the expiration field is optional, so remember to see * check the header.bodysize to see if it is present. */ typedef union { struct { protocol_binary_request_header header; struct { uint32_t expiration; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; } protocol_binary_request_flush; /** * Definition of the packet returned by the flush command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_flush; /** * Definition of the packet used by set, add and replace * See section 4 */ typedef union { struct { protocol_binary_request_header header; struct { uint32_t flags; uint32_t expiration; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; } protocol_binary_request_set; typedef protocol_binary_request_set protocol_binary_request_add; typedef protocol_binary_request_set protocol_binary_request_replace; /** * Definition of the packet returned by set, add and replace * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_set; typedef protocol_binary_response_no_extras protocol_binary_response_add; typedef protocol_binary_response_no_extras protocol_binary_response_replace; /** * Definition of the noop packet * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_noop; /** * Definition of the packet returned by the noop command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_noop; /** * Definition of the structure used by the increment and decrement * command. * See section 4 */ typedef union { struct { protocol_binary_request_header header; struct { uint64_t delta; uint64_t initial; uint32_t expiration; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 20]; } protocol_binary_request_incr; typedef protocol_binary_request_incr protocol_binary_request_decr; /** * Definition of the response from an incr or decr command * command. * See section 4 */ typedef union { struct { protocol_binary_response_header header; struct { uint64_t value; } body; } message; uint8_t bytes[sizeof(protocol_binary_response_header) + 8]; } protocol_binary_response_incr; typedef protocol_binary_response_incr protocol_binary_response_decr; /** * Definition of the quit * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_quit; /** * Definition of the packet returned by the quit command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_quit; /** * Definition of the packet used by append and prepend command * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_append; typedef protocol_binary_request_no_extras protocol_binary_request_prepend; /** * Definition of the packet returned from a successful append or prepend * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_append; typedef protocol_binary_response_no_extras protocol_binary_response_prepend; /** * Definition of the packet used by the version command * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_version; /** * Definition of the packet returned from a successful version command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_version; /** * Definition of the packet used by the stats command. * See section 4 */ typedef protocol_binary_request_no_extras protocol_binary_request_stats; /** * Definition of the packet returned from a successful stats command * See section 4 */ typedef protocol_binary_response_no_extras protocol_binary_response_stats; /** * Definition of the packet used by the touch command. */ typedef union { struct { protocol_binary_request_header header; struct { uint32_t expiration; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; } protocol_binary_request_touch; /** * Definition of the packet returned from the touch command */ typedef protocol_binary_response_no_extras protocol_binary_response_touch; /** * Definition of the packet used by the GAT(Q) command. */ typedef union { struct { protocol_binary_request_header header; struct { uint32_t expiration; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; } protocol_binary_request_gat; typedef protocol_binary_request_gat protocol_binary_request_gatq; typedef protocol_binary_request_gat protocol_binary_request_gatk; typedef protocol_binary_request_gat protocol_binary_request_gatkq; /** * Definition of the packet returned from the GAT(Q) */ typedef protocol_binary_response_get protocol_binary_response_gat; typedef protocol_binary_response_get protocol_binary_response_gatq; typedef protocol_binary_response_get protocol_binary_response_gatk; typedef protocol_binary_response_get protocol_binary_response_gatkq; /** * Definition of a request for a range operation. * See http://code.google.com/p/memcached/wiki/RangeOps * * These types are used for range operations and exist within * this header for use in other projects. Range operations are * not expected to be implemented in the memcached server itself. */ typedef union { struct { protocol_binary_response_header header; struct { uint16_t size; uint8_t reserved; uint8_t flags; uint32_t max_results; } body; } message; uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; } protocol_binary_request_rangeop; typedef protocol_binary_request_rangeop protocol_binary_request_rget; typedef protocol_binary_request_rangeop protocol_binary_request_rset; typedef protocol_binary_request_rangeop protocol_binary_request_rsetq; typedef protocol_binary_request_rangeop protocol_binary_request_rappend; typedef protocol_binary_request_rangeop protocol_binary_request_rappendq; typedef protocol_binary_request_rangeop protocol_binary_request_rprepend; typedef protocol_binary_request_rangeop protocol_binary_request_rprependq; typedef protocol_binary_request_rangeop protocol_binary_request_rdelete; typedef protocol_binary_request_rangeop protocol_binary_request_rdeleteq; typedef protocol_binary_request_rangeop protocol_binary_request_rincr; typedef protocol_binary_request_rangeop protocol_binary_request_rincrq; typedef protocol_binary_request_rangeop protocol_binary_request_rdecr; typedef protocol_binary_request_rangeop protocol_binary_request_rdecrq; #ifdef __cplusplus } #endif #endif /* PROTOCOL_BINARY_H */ memcached-1.4.14/configure0000755000175000017500000065117012005572432012351 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for memcached 1.4.14. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: memcached@googlegroups.com about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='memcached' PACKAGE_TARNAME='memcached' PACKAGE_VERSION='1.4.14' PACKAGE_STRING='memcached 1.4.14' PACKAGE_BUGREPORT='memcached@googlegroups.com' PACKAGE_URL='' ac_unique_file="memcached.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS BUILD_SPECIFICATIONS_FALSE BUILD_SPECIFICATIONS_TRUE XSLTPROC XML2RFC BUILD_CACHE_FALSE BUILD_CACHE_TRUE BUILD_SOLARIS_PRIVS_FALSE BUILD_SOLARIS_PRIVS_TRUE PROFILER_FLAGS PROFILER PROFILER_LDFLAGS ENABLE_SASL DTRACEFLAGS ENABLE_SASL_FALSE ENABLE_SASL_TRUE DTRACE_INSTRUMENT_OBJ_FALSE DTRACE_INSTRUMENT_OBJ_TRUE BUILD_DTRACE_FALSE BUILD_DTRACE_TRUE DTRACE EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_sasl enable_sasl_pwdb enable_dtrace enable_coverage enable_64bit with_libevent enable_docs ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error "unrecognized option: \`$ac_option' Try \`$0 --help' for more information." ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures memcached 1.4.14 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/memcached] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of memcached 1.4.14:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-sasl Enable SASL authentication --enable-sasl-pwdb Enable plaintext password db --enable-dtrace Enable dtrace probes --disable-coverage Disable code coverage --enable-64bit build 64bit version --disable-docs Disable documentation generation Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-libevent=PATH Specify path to libevent installation Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF memcached configure 1.4.14 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_decl LINENO SYMBOL VAR # ------------------------------------ # Tests whether SYMBOL is declared, setting cache variable VAR accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5 $as_echo_n "checking whether $2 is declared... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $2 (void) $2; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_decl # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( cat <<\_ASBOX ## ----------------------------------------- ## ## Report this to memcached@googlegroups.com ## ## ----------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_mongrel # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by memcached $as_me 1.4.14, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do for ac_t in install-sh install.sh shtool; do if test -f "$ac_dir/$ac_t"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/$ac_t -c" break 2 fi done done if test -z "$ac_aux_dir"; then as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=memcached VERSION=1.4.14 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "no acceptable C compiler found in \$PATH See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of object files: cannot compile See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" ICC="no" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for icc in use" >&5 $as_echo_n "checking for icc in use... " >&6; } if test "$GCC" = "yes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ __INTEL_COMPILER _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "^__INTEL_COMPILER" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ICC="yes" fi rm -f conftest* else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "__SUNPRO_C" "ac_cv_have_decl___SUNPRO_C" "$ac_includes_default" if test "x$ac_cv_have_decl___SUNPRO_C" = x""yes; then : SUNCC="yes" else SUNCC="no" fi if test "x$SUNCC" = "xyes"; then : CFLAGS="-mt $CFLAGS" fi if test "$ICC" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if test "${ac_cv_prog_cc_c99+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -c99 -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : fi fi if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Check whether --enable-sasl was given. if test "${enable_sasl+set}" = set; then : enableval=$enable_sasl; fi # Check whether --enable-sasl_pwdb was given. if test "${enable_sasl_pwdb+set}" = set; then : enableval=$enable_sasl_pwdb; fi if test "x$enable_sasl_pwdb" = "xyes"; then : enable_sasl=yes fi for ac_header in sasl/sasl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sasl/sasl.h" "ac_cv_header_sasl_sasl_h" "$ac_includes_default" if test "x$ac_cv_header_sasl_sasl_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SASL_SASL_H 1 _ACEOF fi done if test "x$enable_sasl" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SASL_CB_GETCONF" >&5 $as_echo_n "checking for SASL_CB_GETCONF... " >&6; } if test "${ac_cv_c_sasl_cb_getconf+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { unsigned long val = SASL_CB_GETCONF; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_sasl_cb_getconf=yes else ac_cv_c_sasl_cb_getconf=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_sasl_cb_getconf" >&5 $as_echo "$ac_cv_c_sasl_cb_getconf" >&6; } if test "$ac_cv_c_sasl_cb_getconf" = "yes"; then : $as_echo "#define HAVE_SASL_CB_GETCONF 1" >>confdefs.h fi $as_echo "#define ENABLE_SASL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sasl_server_init" >&5 $as_echo_n "checking for library containing sasl_server_init... " >&6; } if test "${ac_cv_search_sasl_server_init+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sasl_server_init (); int main () { return sasl_server_init (); ; return 0; } _ACEOF for ac_lib in '' sasl2 sasl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_sasl_server_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_sasl_server_init+set}" = set; then : break fi done if test "${ac_cv_search_sasl_server_init+set}" = set; then : else ac_cv_search_sasl_server_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sasl_server_init" >&5 $as_echo "$ac_cv_search_sasl_server_init" >&6; } ac_res=$ac_cv_search_sasl_server_init if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error "Failed to locate the library containing sasl_server_init" "$LINENO" 5 fi if test "x$enable_sasl_pwdb" = "xyes"; then : $as_echo "#define ENABLE_SASL_PWDB 1" >>confdefs.h fi fi # Check whether --enable-dtrace was given. if test "${enable_dtrace+set}" = set; then : enableval=$enable_dtrace; fi if test "x$enable_dtrace" = "xyes"; then # Extract the first word of "dtrace", so it can be a program name with args. set dummy dtrace; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_DTRACE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DTRACE in [\\/]* | ?:[\\/]*) ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/sbin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DTRACE" && ac_cv_path_DTRACE=""no"" ;; esac fi DTRACE=$ac_cv_path_DTRACE if test -n "$DTRACE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 $as_echo "$DTRACE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$DTRACE" != "xno"; then $as_echo "#define ENABLE_DTRACE 1" >>confdefs.h build_dtrace=yes # DTrace on MacOSX does not use -G option $DTRACE -G -o conftest.$$ -s memcached_dtrace.d 2>/dev/zero if test $? -eq 0 then dtrace_instrument_obj=yes rm conftest.$$ fi if test "`which tr`" = "/usr/ucb/tr"; then as_fn_error "Please remove /usr/ucb from your path. See man standards for more info" "$LINENO" 5 fi else as_fn_error "Need dtrace binary and OS support." "$LINENO" 5 fi fi if test "$build_dtrace" = "yes"; then BUILD_DTRACE_TRUE= BUILD_DTRACE_FALSE='#' else BUILD_DTRACE_TRUE='#' BUILD_DTRACE_FALSE= fi if test "$dtrace_instrument_obj" = "yes"; then DTRACE_INSTRUMENT_OBJ_TRUE= DTRACE_INSTRUMENT_OBJ_FALSE='#' else DTRACE_INSTRUMENT_OBJ_TRUE='#' DTRACE_INSTRUMENT_OBJ_FALSE= fi if test "$enable_sasl" = "yes"; then ENABLE_SASL_TRUE= ENABLE_SASL_FALSE='#' else ENABLE_SASL_TRUE='#' ENABLE_SASL_FALSE= fi # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : enableval=$enable_coverage; fi if test "x$enable_coverage" != "xno"; then if test "$ICC" = "yes" then CFLAGS="$CFLAGS -pthread" elif test "$GCC" = "yes" then CFLAGS="$CFLAGS -pthread" # Extract the first word of "gcov", so it can be a program name with args. set dummy gcov; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PROFILER+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PROFILER in [\\/]* | ?:[\\/]*) ac_cv_path_PROFILER="$PROFILER" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PROFILER="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PROFILER" && ac_cv_path_PROFILER=""no"" ;; esac fi PROFILER=$ac_cv_path_PROFILER if test -n "$PROFILER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROFILER" >&5 $as_echo "$PROFILER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$PROFILER" != "xno"; then # Issue 97: The existense of gcov doesn't mean we have -lgcov { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgcov" >&5 $as_echo_n "checking for main in -lgcov... " >&6; } if test "${ac_cv_lib_gcov_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgcov $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gcov_main=yes else ac_cv_lib_gcov_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcov_main" >&5 $as_echo "$ac_cv_lib_gcov_main" >&6; } if test "x$ac_cv_lib_gcov_main" = x""yes; then : PROFILER_FLAGS="-fprofile-arcs -ftest-coverage" PROFILER_LDFLAGS="-lgcov" else PROFILER_FLAGS= PROFILER_LDFLAGS= fi fi elif test "$SUNCC" = "yes" then # Extract the first word of "tcov", so it can be a program name with args. set dummy tcov; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PROFILER+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PROFILER in [\\/]* | ?:[\\/]*) ac_cv_path_PROFILER="$PROFILER" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PROFILER="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PROFILER" && ac_cv_path_PROFILER=""no"" ;; esac fi PROFILER=$ac_cv_path_PROFILER if test -n "$PROFILER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROFILER" >&5 $as_echo "$PROFILER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$PROFILER" != "xno"; then PROFILER_FLAGS=-xprofile=tcov fi fi fi # Check whether --enable-64bit was given. if test "${enable_64bit+set}" = set; then : enableval=$enable_64bit; fi if test "x$enable_64bit" = "xyes" then org_cflags=$CFLAGS CFLAGS=-m64 if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run test program while cross compiling See \`config.log' for more details." "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return sizeof(void*) == 8 ? 0 : 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : CFLAGS="-m64 $org_cflags" else as_fn_error "Don't know how to build a 64-bit object." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi # Issue 213: Search for clock_gettime to help people linking # with a static version of libevent { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } if test "${ac_cv_search_clock_gettime+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_clock_gettime+set}" = set; then : break fi done if test "${ac_cv_search_clock_gettime+set}" = set; then : else ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 $as_echo "$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # Issue 214: Search for the network libraries _before_ searching # for libevent (to help people linking with static libevent) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 $as_echo_n "checking for library containing socket... " >&6; } if test "${ac_cv_search_socket+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_socket+set}" = set; then : break fi done if test "${ac_cv_search_socket+set}" = set; then : else ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 $as_echo "$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 $as_echo_n "checking for library containing gethostbyname... " >&6; } if test "${ac_cv_search_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethostbyname=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_gethostbyname+set}" = set; then : break fi done if test "${ac_cv_search_gethostbyname+set}" = set; then : else ac_cv_search_gethostbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 $as_echo "$ac_cv_search_gethostbyname" >&6; } ac_res=$ac_cv_search_gethostbyname if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi trylibeventdir="" # Check whether --with-libevent was given. if test "${with_libevent+set}" = set; then : withval=$with_libevent; if test "x$withval" != "xno" ; then trylibeventdir=$withval fi fi LIBEVENT_URL=http://www.monkey.org/~provos/libevent/ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libevent directory" >&5 $as_echo_n "checking for libevent directory... " >&6; } if test "${ac_cv_libevent_dir+set}" = set; then : $as_echo_n "(cached) " >&6 else saved_LIBS="$LIBS" saved_LDFLAGS="$LDFLAGS" saved_CPPFLAGS="$CPPFLAGS" le_found=no for ledir in $trylibeventdir "" $prefix /usr/local ; do LDFLAGS="$saved_LDFLAGS" LIBS="-levent $saved_LIBS" # Skip the directory if it isn't there. if test ! -z "$ledir" -a ! -d "$ledir" ; then continue; fi if test ! -z "$ledir" ; then if test -d "$ledir/lib" ; then LDFLAGS="-L$ledir/lib $LDFLAGS" else LDFLAGS="-L$ledir $LDFLAGS" fi if test -d "$ledir/include" ; then CPPFLAGS="-I$ledir/include $CPPFLAGS" else CPPFLAGS="-I$ledir $CPPFLAGS" fi fi # Can I compile and link it? cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { event_init(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : libevent_linked=yes else libevent_linked=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $libevent_linked = yes; then if test ! -z "$ledir" ; then ac_cv_libevent_dir=$ledir _myos=`echo $target_os | cut -f 1 -d .` if test "$SUNCC" = "yes" -o "x$_myos" = "xsolaris2"; then : saved_LDFLAGS="$saved_LDFLAGS -Wl,-R$ledir/lib" else if test "$GCC" = "yes"; then : saved_LDFLAGS="$saved_LDFLAGS -Wl,-rpath,$ledir/lib" fi fi else ac_cv_libevent_dir="(system)" fi le_found=yes break fi done LIBS="$saved_LIBS" LDFLAGS="$saved_LDFLAGS" CPPFLAGS="$saved_CPPFLAGS" if test $le_found = no ; then as_fn_error "libevent is required. You can get it from $LIBEVENT_URL If it's already installed, specify its path using --with-libevent=/dir/ " "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libevent_dir" >&5 $as_echo "$ac_cv_libevent_dir" >&6; } LIBS="-levent $LIBS" if test $ac_cv_libevent_dir != "(system)"; then if test -d "$ac_cv_libevent_dir/lib" ; then LDFLAGS="-L$ac_cv_libevent_dir/lib $LDFLAGS" le_libdir="$ac_cv_libevent_dir/lib" else LDFLAGS="-L$ac_cv_libevent_dir $LDFLAGS" le_libdir="$ac_cv_libevent_dir" fi if test -d "$ac_cv_libevent_dir/include" ; then CPPFLAGS="-I$ac_cv_libevent_dir/include $CPPFLAGS" else CPPFLAGS="-I$ac_cv_libevent_dir $CPPFLAGS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing umem_cache_create" >&5 $as_echo_n "checking for library containing umem_cache_create... " >&6; } if test "${ac_cv_search_umem_cache_create+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char umem_cache_create (); int main () { return umem_cache_create (); ; return 0; } _ACEOF for ac_lib in '' umem; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_umem_cache_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_umem_cache_create+set}" = set; then : break fi done if test "${ac_cv_search_umem_cache_create+set}" = set; then : else ac_cv_search_umem_cache_create=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_umem_cache_create" >&5 $as_echo "$ac_cv_search_umem_cache_create" >&6; } ac_res=$ac_cv_search_umem_cache_create if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethugepagesizes" >&5 $as_echo_n "checking for library containing gethugepagesizes... " >&6; } if test "${ac_cv_search_gethugepagesizes+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethugepagesizes (); int main () { return gethugepagesizes (); ; return 0; } _ACEOF for ac_lib in '' hugetlbfs; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethugepagesizes=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_gethugepagesizes+set}" = set; then : break fi done if test "${ac_cv_search_gethugepagesizes+set}" = set; then : else ac_cv_search_gethugepagesizes=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethugepagesizes" >&5 $as_echo "$ac_cv_search_gethugepagesizes" >&6; } ac_res=$ac_cv_search_gethugepagesizes if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if test "${ac_cv_header_stdbool_h+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; bool e = &s; char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; # if defined __xlc__ || defined __GNUC__ /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 reported by James Lemley on 2005-10-05; see http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html This test is not quite right, since xlc is allowed to reject this program, as the initializer for xlcbug is not one of the forms that C requires support for. However, doing the test right would require a runtime test, and that would make cross-compilation harder. Let us hope that IBM fixes the xlc bug, and also adds support for this kind of constant expression. In the meantime, this test will reject xlc, which is OK, since our stdbool.h substitute should suffice. We also test this with GCC, where it should work, to detect more quickly whether someone messes up the test in the future. */ char digs[] = "0123456789"; int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); # endif /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sasl_callback_ft" >&5 $as_echo_n "checking for sasl_callback_ft... " >&6; } if test "${ac_cv_has_sasl_callback_ft+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_SASL_SASL_H #include #include #endif int main () { sasl_callback_ft a_callback; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_has_sasl_callback_ft=yes else ac_cv_has_sasl_callback_ft=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_has_sasl_callback_ft" >&5 $as_echo "$ac_cv_has_sasl_callback_ft" >&6; } if test $ac_cv_has_sasl_callback_ft = yes; then $as_echo "#define HAVE_SASL_CALLBACK_FT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for print macros for integers (C99 section 7.8.1)" >&5 $as_echo_n "checking for print macros for integers (C99 section 7.8.1)... " >&6; } if test "${ac_cv_c_uint64_support+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_INTTYPES_H #include #endif #include int main () { uint64_t val = 0; fprintf(stderr, "%" PRIu64 "\n", val); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_uint64_support=yes else ac_cv_c_uint64_support=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_uint64_support" >&5 $as_echo "$ac_cv_c_uint64_support" >&6; } if test "x$ac_cv_c_uint64_support" = "xno"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed to use print macros (PRIu) as defined in C99 section 7.8.1. " >&5 $as_echo "$as_me: WARNING: Failed to use print macros (PRIu) as defined in C99 section 7.8.1. " >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 $as_echo_n "checking for socklen_t... " >&6; } if test "${ac_cv_c_socklen_t+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { socklen_t foo; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_socklen_t=yes else ac_cv_c_socklen_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_socklen_t" >&5 $as_echo "$ac_cv_c_socklen_t" >&6; } if test $ac_cv_c_socklen_t = no; then $as_echo "#define socklen_t int" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for endianness" >&5 $as_echo_n "checking for endianness... " >&6; } if test "${ac_cv_c_endian+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run test program while cross compiling See \`config.log' for more details." "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { long val = 1; char *c = (char *) &val; exit(*c == 1); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_endian=big else ac_cv_c_endian=little fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_endian" >&5 $as_echo "$ac_cv_c_endian" >&6; } if test $ac_cv_c_endian = big; then $as_echo "#define ENDIAN_BIG 1" >>confdefs.h fi if test $ac_cv_c_endian = little; then $as_echo "#define ENDIAN_LITTLE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for htonll" >&5 $as_echo_n "checking for htonll... " >&6; } have_htoll="no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifdef HAVE_INTTYPES_H #include */ #endif int main () { return htonll(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_htoll="yes" $as_echo "#define HAVE_HTONLL 1" >>confdefs.h else have_htoll="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_htoll" >&5 $as_echo "$have_htoll" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 $as_echo_n "checking for library containing pthread_create... " >&6; } if test "${ac_cv_search_pthread_create+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF for ac_lib in '' pthread; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_pthread_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_pthread_create+set}" = set; then : break fi done if test "${ac_cv_search_pthread_create+set}" = set; then : else ac_cv_search_pthread_create=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 $as_echo "$ac_cv_search_pthread_create" >&6; } ac_res=$ac_cv_search_pthread_create if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi if test "x$ac_cv_search_pthread_create" = "xno"; then as_fn_error "Can't enable threads without the POSIX thread library." "$LINENO" 5 fi for ac_func in mlockall do : ac_fn_c_check_func "$LINENO" "mlockall" "ac_cv_func_mlockall" if test "x$ac_cv_func_mlockall" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MLOCKALL 1 _ACEOF fi done for ac_func in getpagesizes do : ac_fn_c_check_func "$LINENO" "getpagesizes" "ac_cv_func_getpagesizes" if test "x$ac_cv_func_getpagesizes" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZES 1 _ACEOF fi done for ac_func in memcntl do : ac_fn_c_check_func "$LINENO" "memcntl" "ac_cv_func_memcntl" if test "x$ac_cv_func_memcntl" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MEMCNTL 1 _ACEOF fi done for ac_func in sigignore do : ac_fn_c_check_func "$LINENO" "sigignore" "ac_cv_func_sigignore" if test "x$ac_cv_func_sigignore" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SIGIGNORE 1 _ACEOF fi done for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alignment" >&5 $as_echo_n "checking for alignment... " >&6; } if test "${ac_cv_c_alignment+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_alignment=need else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { char *buf = malloc(32); uint64_t *ptr = (uint64_t*)(buf+2); // catch sigbus, etc. *ptr = 0x1; // catch unaligned word access (ARM cpus) *buf = 1; *(buf +1) = 2; *(buf + 2) = 2; *(buf + 3) = 3; *(buf + 4) = 4; int* i = (int*)(buf+1); return (84148994 == i) ? 0 : 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_alignment=none else ac_cv_c_alignment=need fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_alignment" >&5 $as_echo "$ac_cv_c_alignment" >&6; } if test $ac_cv_c_alignment = need; then $as_echo "#define NEED_ALIGN 1" >>confdefs.h fi have_gcc_atomics=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC atomics" >&5 $as_echo_n "checking for GCC atomics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { unsigned short a; unsigned short b; b = __sync_add_and_fetch(&a, 1); b = __sync_sub_and_fetch(&a, 2); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_gcc_atomics=yes $as_echo "#define HAVE_GCC_ATOMICS 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_atomics" >&5 $as_echo "$have_gcc_atomics" >&6; } for ac_func in setppriv do : ac_fn_c_check_func "$LINENO" "setppriv" "ac_cv_func_setppriv" if test "x$ac_cv_func_setppriv" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETPPRIV 1 _ACEOF ac_fn_c_check_header_mongrel "$LINENO" "priv.h" "ac_cv_header_priv_h" "$ac_includes_default" if test "x$ac_cv_header_priv_h" = x""yes; then : $as_echo "#define HAVE_DROP_PRIVILEGES 1" >>confdefs.h build_solaris_privs=yes fi fi done if test "$build_solaris_privs" = "yes"; then BUILD_SOLARIS_PRIVS_TRUE= BUILD_SOLARIS_PRIVS_FALSE='#' else BUILD_SOLARIS_PRIVS_TRUE='#' BUILD_SOLARIS_PRIVS_FALSE= fi ac_fn_c_check_header_mongrel "$LINENO" "umem.h" "ac_cv_header_umem_h" "$ac_includes_default" if test "x$ac_cv_header_umem_h" = x""yes; then : $as_echo "#define HAVE_UMEM_H 1" >>confdefs.h build_cache=no else build_cache=yes fi if test "x$build_cache" = "xyes"; then BUILD_CACHE_TRUE= BUILD_CACHE_FALSE='#' else BUILD_CACHE_TRUE='#' BUILD_CACHE_FALSE= fi # Check whether --enable-docs was given. if test "${enable_docs+set}" = set; then : enableval=$enable_docs; fi # Extract the first word of "xml2rfc", so it can be a program name with args. set dummy xml2rfc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_XML2RFC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XML2RFC in [\\/]* | ?:[\\/]*) ac_cv_path_XML2RFC="$XML2RFC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_XML2RFC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XML2RFC" && ac_cv_path_XML2RFC=""no"" ;; esac fi XML2RFC=$ac_cv_path_XML2RFC if test -n "$XML2RFC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2RFC" >&5 $as_echo "$XML2RFC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "xsltproc", so it can be a program name with args. set dummy xsltproc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_XSLTPROC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XSLTPROC in [\\/]* | ?:[\\/]*) ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_XSLTPROC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XSLTPROC" && ac_cv_path_XSLTPROC=""no"" ;; esac fi XSLTPROC=$ac_cv_path_XSLTPROC if test -n "$XSLTPROC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 $as_echo "$XSLTPROC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$enable_docs" != "xno" -a "x$XML2RFC" != "xno" -a "x$XSLTPROC" != "xno"; then BUILD_SPECIFICATIONS_TRUE= BUILD_SPECIFICATIONS_FALSE='#' else BUILD_SPECIFICATIONS_TRUE='#' BUILD_SPECIFICATIONS_FALSE= fi if test "$ICC" = "yes" then CFLAGS="$CFLAGS -diag-disable 187 -Wall -Werror" $as_echo "#define _GNU_SOURCE 1" >>confdefs.h elif test "$GCC" = "yes" then GCC_VERSION=`$CC -dumpversion` CFLAGS="$CFLAGS -Wall -Werror -pedantic -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls" case $GCC_VERSION in 4.4.*) CFLAGS="$CFLAGS -fno-strict-aliasing" ;; esac $as_echo "#define _GNU_SOURCE 1" >>confdefs.h elif test "$SUNCC" = "yes" then CFLAGS="$CFLAGS -errfmt=error -errwarn -errshort=tags" fi ac_config_files="$ac_config_files Makefile doc/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DTRACE_TRUE}" && test -z "${BUILD_DTRACE_FALSE}"; then as_fn_error "conditional \"BUILD_DTRACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DTRACE_INSTRUMENT_OBJ_TRUE}" && test -z "${DTRACE_INSTRUMENT_OBJ_FALSE}"; then as_fn_error "conditional \"DTRACE_INSTRUMENT_OBJ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_SASL_TRUE}" && test -z "${ENABLE_SASL_FALSE}"; then as_fn_error "conditional \"ENABLE_SASL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SOLARIS_PRIVS_TRUE}" && test -z "${BUILD_SOLARIS_PRIVS_FALSE}"; then as_fn_error "conditional \"BUILD_SOLARIS_PRIVS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_CACHE_TRUE}" && test -z "${BUILD_CACHE_FALSE}"; then as_fn_error "conditional \"BUILD_CACHE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SPECIFICATIONS_TRUE}" && test -z "${BUILD_SPECIFICATIONS_FALSE}"; then as_fn_error "conditional \"BUILD_SPECIFICATIONS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by memcached $as_me 1.4.14, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ memcached config.status 1.4.14 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi memcached-1.4.14/aclocal.m40000644000175000017500000010667112005572431012302 00000000000000# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, [m4_warning([this file was generated for autoconf 2.65. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR memcached-1.4.14/memcached_dtrace.d0000644000175000017500000002535412005341533014032 00000000000000/* * Copyright (c) <2008>, Sun Microsystems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the 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 SUN MICROSYSTEMS, INC. ``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 SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, 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. */ provider memcached { /** * Fired when a connection object is allocated from the connection pool. * @param connid the connection id */ probe conn__allocate(int connid); /** * Fired when a connection object is released back to the connection pool. * @param connid the connection id */ probe conn__release(int connid); /** * Fired when a new connection object is created (there are no more * connection objects in the connection pool). * @param ptr pointer to the connection object */ probe conn__create(void *ptr); /** * Fired when a connection object is destroyed ("released back to * the memory subsystem"). * @param ptr pointer to the connection object */ probe conn__destroy(void *ptr); /** * Fired when a connection is dispatched from the "main thread" to a * worker thread. * @param connid the connection id * @param threadid the thread id */ probe conn__dispatch(int connid, int threadid); /** * Allocate memory from the slab allocator. * @param size the requested size * @param slabclass the allocation will be fulfilled in this class * @param slabsize the size of each item in this class * @param ptr pointer to allocated memory */ probe slabs__allocate(int size, int slabclass, int slabsize, void* ptr); /** * Failed to allocate memory (out of memory). * @param size the requested size * @param slabclass the class that failed to fulfill the request */ probe slabs__allocate__failed(int size, int slabclass); /** * Fired when a slab class attempts to allocate more space. * @param slabclass class that needs more memory */ probe slabs__slabclass__allocate(int slabclass); /** * Failed to allocate memory (out of memory). * @param slabclass the class that failed grab more memory */ probe slabs__slabclass__allocate__failed(int slabclass); /** * Release memory. * @param size the size of the memory * @param slabclass the class the memory belongs to * @param ptr pointer to the memory to release */ probe slabs__free(int size, int slabclass, void* ptr); /** * Fired when the when we have searched the hash table for a named key. * These two elements provide an insight in how well the hash function * functions. Long traversals are a sign of a less optimal function, * wasting cpu capacity. * * @param key the key searched for * @param keylen length of the key * @param depth the depth in the list of hash table */ probe assoc__find(const char *key, int keylen, int depth); /** * Fired when a new item has been inserted. * @param key the key just inserted * @param keylen length of the key * @param nokeys the total number of keys currently stored, * including the key for which insert was called. */ probe assoc__insert(const char *key, int keylen, int nokeys); /** * Fired when a new item has been removed. * @param key the key just deleted * @param keylen length of the key * @param nokeys the total number of keys currently stored, * excluding the key for which delete was called. */ probe assoc__delete(const char *key, int keylen, int nokeys); /** * Fired when an item is linked into the cache. * @param key the items key * @param keylen length of the key * @param size the size of the data */ probe item__link(const char *key, int keylen, int size); /** * Fired when an item is deleted. * @param key the items key * @param keylen length of the key * @param size the size of the data */ probe item__unlink(const char *key, int keylen, int size); /** * Fired when the refcount for an item is reduced. * @param key the items key * @param keylen length of the key * @param size the size of the data */ probe item__remove(const char *key, int keylen, int size); /** * Fired when the "last refenced" time is updated. * @param key the items key * @param keylen length of the key * @param size the size of the data */ probe item__update(const char *key, int keylen, int size); /** * Fired when an item is replaced with another item. * @param oldkey the key of the item to replace * @param oldkeylen the length of the old key * @param oldsize the size of the old item * @param newkey the key of the new item * @param newkeylen the length of the new key * @param newsize the size of the new item */ probe item__replace(const char *oldkey, int oldkeylen, int oldsize, const char *newkey, int newkeylen, int newsize); /** * Fired when the processing of a command starts. * @param connid the connection id * @param request the incomming request * @param size the size of the request */ probe process__command__start(int connid, const void *request, int size); /** * Fired when the processing of a command is done. * @param connid the connection id * @param respnse the response to send back to the client * @param size the size of the response */ probe process__command__end(int connid, const void *response, int size); /** * Fired for a get-command * @param connid connection id * @param key requested key * @param keylen length of the key * @param size size of the key's data (or signed int -1 if not found) * @param casid the casid for the item */ probe command__get(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for an add-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__add(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for a set-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__set(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for a replace-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__replace(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for a prepend-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__prepend(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for an append-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__append(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for an touch-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size the new size of the key's data (or signed int -1 if * not found) * @param casid the casid for the item */ probe command__touch(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for a cas-command. * @param connid connection id * @param key requested key * @param keylen length of the key * @param size size of the key's data (or signed int -1 if not found) * @param casid the cas id requested */ probe command__cas(int connid, const char *key, int keylen, int size, int64_t casid); /** * Fired for an incr command. * @param connid connection id * @param key the requested key * @param keylen length of the key * @param val the new value */ probe command__incr(int connid, const char *key, int keylen, int64_t val); /** * Fired for a decr command. * @param connid connection id * @param key the requested key * @param keylen length of the key * @param val the new value */ probe command__decr(int connid, const char *key, int keylen, int64_t val); /** * Fired for a delete command. * @param connid connection id * @param key the requested key * @param keylen length of the key */ probe command__delete(int connid, const char *key, int keylen); }; #pragma D attributes Unstable/Unstable/Common provider memcached provider #pragma D attributes Private/Private/Common provider memcached module #pragma D attributes Private/Private/Common provider memcached function #pragma D attributes Unstable/Unstable/Common provider memcached name #pragma D attributes Unstable/Unstable/Common provider memcached args memcached-1.4.14/doc/0000755000175000017500000000000012005572437011262 500000000000000memcached-1.4.14/doc/Makefile.am0000644000175000017500000000065011701635506013236 00000000000000man_MANS = memcached.1 EXTRA_DIST = *.txt BUILT_SOURCES= if BUILD_SPECIFICATIONS BUILT_SOURCES += protocol-binary.txt protocol-binary-range.txt MOSTLYCLEANFILES = protocol-binary.txt protocol-binary-range.txt endif %.txt: %.full @XML2RFC@ $< $@ %.chk: %.xml xml2rfc/rfc2629-refchk.xsl @XSLTPROC@ xml2rfc/rfc2629-refchk.xsl $< >$@ %.full: %.xml xml2rfc/rfc2629-noinc.xsl @XSLTPROC@ xml2rfc/rfc2629-noinc.xsl $< >$@ memcached-1.4.14/doc/Doxyfile0000644000175000017500000014451711446413300012713 00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = memcached # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 0.8 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = NO # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = YES # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = .. # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h \ *.c # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = config.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO memcached-1.4.14/doc/CONTRIBUTORS0000644000175000017500000000274011701635506013064 00000000000000MEMCACHED CONTRIBUTORS This file contains a list of people who have contributed code and effort to the memcached project. If you don't see your name mentioned send email to the memcached mailing list so you can be immortalized. Also see the ChangeLog for even more people who have helped over the years by submitting fixes, patches and reporting bugs. Major authors: -------------- Brad Fitzpatrick -- maintainer, original implementations Anatoly Vorobey -- lots of the modern server code Steven Grimm -- iov writing (less CPU), UDP mode, non-2.0 slab mantissas, multithread, ... Other Contributors ------------------ Evan Martin Nathan Neulinger Eric Hodel Michael Johnson Paul Querna Jamie McCarthy Philip Neustrom Andrew O'Brien Josh Rotenberg Robin H. Johnson Tim Yardley Paolo Borelli Eli Bingham Jean-Francois Bustarret Paul G Paul Lindner Dormando Dustin Sallings Chris Goffinet Tomash Brechko Brian Aker Trond Norbye memcached-1.4.14/doc/memcached.10000644000175000017500000001245311701635506013176 00000000000000.TH MEMCACHED 1 "April 11, 2005" .SH NAME memcached \- high-performance memory object caching system .SH SYNOPSIS .B memcached .RI [ options ] .br .SH DESCRIPTION This manual page documents briefly the .B memcached memory object caching daemon. .PP .B memcached is a flexible memory object caching daemon designed to alleviate database load in dynamic web applications by storing objects in memory. It's based on libevent to scale to any size needed, and is specifically optimized to avoid swapping and always use non-blocking I/O. .br .SH OPTIONS These programs follow the usual GNU command line syntax. A summary of options is included below. .TP .B \-s Unix socket path to listen on (disables network support). .TP .B \-a Permissions (in octal format) for Unix socket created with \-s option. .TP .B \-l Listen on ; default to INADDR_ANY. This is an important option to consider as there is no other way to secure the installation. Binding to an internal or firewalled network interface is suggested. .TP .B \-d Run memcached as a daemon. .TP .B \-u Assume the identity of (only when run as root). .TP .B \-m Use MB memory max to use for object storage; the default is 64 megabytes. .TP .B \-c Use max simultaneous connections; the default is 1024. .TP .B \-R This option seeks to prevent client starvation by setting a limit to the number of sequential requests the server will process from an individual client connection. Once a connection has exceeded this value, the server will attempt to process I/O on other connections before handling any further request from this connection. The default value for this option is 20. .TP .B \-k Lock down all paged memory. This is a somewhat dangerous option with large caches, so consult the README and memcached homepage for configuration suggestions. .TP .B \-p Listen on TCP port , the default is port 11211. .TP .B \-U Listen on UDP port , the default is port 11211, 0 is off. .TP .B \-M Disable automatic removal of items from the cache when out of memory. Additions will not be possible until adequate space is freed up. .TP .B \-r Raise the core file size limit to the maximum allowable. .TP .B \-f Use as the multiplier for computing the sizes of memory chunks that items are stored in. A lower value may result in less wasted memory depending on the total amount of memory available and the distribution of item sizes. The default is 1.25. .TP .B \-n Allocate a minimum of bytes for the item key, value, and flags. The default is 48. If you have a lot of small keys and values, you can get a significant memory efficiency gain with a lower value. If you use a high chunk growth factor (\-f option), on the other hand, you may want to increase the size to allow a bigger percentage of your items to fit in the most densely packed (smallest) chunks. .TP .B \-C Disable the use of CAS (and reduce the per-item size by 8 bytes). .TP .B \-h Show the version of memcached and a summary of options. .TP .B \-v Be verbose during the event loop; print out errors and warnings. .TP .B \-vv Be even more verbose; same as \-v but also print client commands and responses. .TP .B \-i Print memcached and libevent licenses. .TP .B \-P Print pidfile to , only used under \-d option. .TP .B \-t Number of threads to use to process incoming requests. This option is only meaningful if memcached was compiled with thread support enabled. It is typically not useful to set this higher than the number of CPU cores on the memcached server. The default is 4. .TP .B \-D Use as the delimiter between key prefixes and IDs. This is used for per-prefix stats reporting. The default is ":" (colon). If this option is specified, stats collection is turned on automatically; if not, then it may be turned on by sending the "stats detail on" command to the server. .TP .B \-L Try to use large memory pages (if available). Increasing the memory page size could reduce the number of TLB misses and improve the performance. In order to get large pages from the OS, memcached will allocate the total item-cache in one large chunk. Only available if supported on your OS. .TP .B \-B Specify the binding protocol to use. By default, the server will autonegotiate client connections. By using this option, you can specify the protocol clients must speak. Possible options are "auto" (the default, autonegotiation behavior), "ascii" and "binary". .TP .B \-I Override the default size of each slab page. Default is 1mb. Default is 1m, minimum is 1k, max is 128m. Adjusting this value changes the item size limit. Beware that this also increases the number of slabs (use -v to view), and the overal memory usage of memcached. .TP .B \-o Comma separated list of extended or experimental options. See -h or wiki for up to date list. .br .SH LICENSE The memcached daemon is copyright Danga Interactive and is distributed under the BSD license. Note that daemon clients are licensed separately. .br .SH SEE ALSO The README file that comes with memcached .br .B http://www.danga.com/memcached .SH AUTHOR The memcached daemon was written by Anatoly Vorobey .B and Brad Fitzpatrick .B and the rest of the crew of Danga Interactive .B http://www.danga.com .br memcached-1.4.14/doc/protocol-binary.xml0000644000175000017500000017244711701635506015065 00000000000000 Memcache Binary Protocol Six Apart, Ltd.
548 4th Street San Francisco CA 94107 USA aaron@serendipity.palo-alto.ca.us
Sun Microsystems, INC
Haakon VII g. 7B Trondheim NO-7485 Trondheim Norway trond.norbye@sun.com
Applications memcache memcached cache This memo explains the memcache binary protocol for informational purposes. Memcache is a high performance key-value cache. It is intentionally a dumb cache, optimized for speed only. Applications using memcache do not rely on it for data -- a persistent database with guaranteed reliability is strongly recommended -- but applications can run much faster when cached data is available in memcache.
Memcache is a high performance key-value cache. It is intentionally a dumb cache, optimized for speed only. Applications using memcache should not rely on it for data -- a persistent database with guaranteed reliability is strongly recommended -- but applications can run much faster when cached data is available in memcache. Memcache was originally written to make LiveJournal faster. It now powers all of the fastest web sites that you love.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in .
General format of a packet: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0/ HEADER / / / / / / / +---------------+---------------+---------------+---------------+ 24/ COMMAND-SPECIFIC EXTRAS (as needed) / +/ (note length in the extras length header field) / +---------------+---------------+---------------+---------------+ m/ Key (as needed) / +/ (note length in key length header field) / +---------------+---------------+---------------+---------------+ n/ Value (as needed) / +/ (note length is total body length header field, minus / +/ sum of the extras and key length body fields) / +---------------+---------------+---------------+---------------+ Total 24 bytes
Request header: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Magic | Opcode | Key length | +---------------+---------------+---------------+---------------+ 4| Extras length | Data type | Reserved | +---------------+---------------+---------------+---------------+ 8| Total body length | +---------------+---------------+---------------+---------------+ 12| Opaque | +---------------+---------------+---------------+---------------+ 16| CAS | | | +---------------+---------------+---------------+---------------+ Total 24 bytes
Response header: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Magic | Opcode | Key Length | +---------------+---------------+---------------+---------------+ 4| Extras length | Data type | Status | +---------------+---------------+---------------+---------------+ 8| Total body length | +---------------+---------------+---------------+---------------+ 12| Opaque | +---------------+---------------+---------------+---------------+ 16| CAS | | | +---------------+---------------+---------------+---------------+ Total 24 bytes
Header fields: Magic number. Command code. Length in bytes of the text key that follows the command extras. Status of the response (non-zero on error). Length in bytes of the command extras. Reserved for future use (Sean is using this soon). Really reserved for future use (up for grabs). Length in bytes of extra + key + value. Will be copied back to you in the response. Data version check.
Request packet for this protocol version Response packet for this protocol version Magic byte / version. For each version of the protocol, we'll use a different request/response value pair. This is useful for protocol analyzers to distinguish the nature of the packet from the direction which it is moving. Note, it is common to run a memcached instance on a host that also runs an application server. Such a host will both send and receive memcache packets. The version should hopefully correspond only to different meanings of the command byte. In an ideal world, we will not change the header format. As reserved bytes are given defined meaning, the protocol version / magic byte values should be incremented. Traffic analysis tools are encouraged to identify memcache packets and provide detailed interpretation if the magic bytes are recognized and otherwise to provide a generic breakdown of the packet. Note, that the key and value positions can always be identified even if the magic byte or command opcode are not recognized.
Possible values of this two-byte field: No error Key not found Key exists Value too large Invalid arguments Item not stored Incr/Decr on non-numeric value. Unknown command Out of memory
Possible values of the one-byte field: Get Set Add Replace Delete Increment Decrement Quit Flush GetQ No-op Version GetK GetKQ Append Prepend Stat SetQ AddQ ReplaceQ DeleteQ IncrementQ DecrementQ QuitQ FlushQ AppendQ PrependQ As a convention all of the commands ending with "Q" for Quiet. A quiet version of a command will omit responses that are considered uninteresting. Whether a given response is interesting is dependent upon the command. See the descriptions of the set commands and set commands for examples of commands that include quiet variants.
Possible values of the one-byte field: Raw bytes
All communication is initiated by a request from the client, and the server will respond to each request with zero or multiple packets for each request. If the status code of a response packet is non-nil, the body of the packet will contain a textual error message. If the status code is nil, the command opcode will define the layout of the body of the message.
The following figure illustrates the packet layout for a packet with an error message.
Packet layout: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x01 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x09 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x4e ('N') | 0x6f ('o') | 0x74 ('t') | 0x20 (' ') | +---------------+---------------+---------------+---------------+ 28| 0x66 ('f') | 0x6f ('o') | 0x75 ('u') | 0x6e ('n') | +---------------+---------------+---------------+---------------+ 32| 0x64 ('d') | +---------------+ Total 33 bytes (24 byte header, and 9 bytes value) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x00 Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Status (6,7) : 0x0001 Total body (8-11) : 0x00000009 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : None Value (24-32): The textual string "Not found"
Request: MUST NOT have extras. MUST have key. MUST NOT have value. Response (if found): MUST have extras. MAY have key. MAY have value. 4 byte flags
Extra data for the get commands: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Flags | +---------------+---------------+---------------+---------------+ Total 4 bytes
The get command gets a single key. The getq command is both mum on cache miss and quiet, holding its response until a non-quiet command is issued. Getk and getkq differs from get and getq by adding the key into the response packet. You're not guaranteed a response to a getq/getkq cache hit until you send a non-getq/getkq command later, which uncorks the server and bundles up IOs to send to the client in one go. Clients should implement multi-get (still important for reducing network roundtrips!) as n pipelined requests, the first n-1 being getq/getkq, the last being a regular get/getk. That way you're guaranteed to get a response, and you know when the server's done. You can also do the naive thing and send n pipelined get/getks, but then you could potentially get back a lot of "NOT_FOUND" error code packets. Alternatively, you can send 'n' getq/getkqs, followed by a 'noop' command.
To request the data associated with the key "Hello" the following fields must be specified in the packet.
get request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x48 ('H') | 0x65 ('e') | 0x6c ('l') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 28| 0x6f ('o') | +---------------+ Total 29 bytes (24 byte header, and 5 bytes key) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x00 Key length (2,3) : 0x0005 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000005 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key (24-29): The textual string: "Hello" Value : None
If the item exist on the server the following packet is returned, otherwise a packet with status code != 0 will be returned (see Introduction)
get/getq response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x04 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x09 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x01 | +---------------+---------------+---------------+---------------+ 24| 0xde | 0xad | 0xbe | 0xef | +---------------+---------------+---------------+---------------+ 28| 0x57 ('W') | 0x6f ('o') | 0x72 ('r') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 32| 0x64 ('d') | +---------------+ Total 33 bytes (24 byte header, 4 byte extras and 5 byte value) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x00 Key length (2,3) : 0x0000 Extra length (4) : 0x04 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000009 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000001 Extras : Flags (24-27): 0xdeadbeef Key : None Value (28-32): The textual string "World"
getk/getkq response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 4| 0x04 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x09 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x01 | +---------------+---------------+---------------+---------------+ 24| 0xde | 0xad | 0xbe | 0xef | +---------------+---------------+---------------+---------------+ 28| 0x48 ('H') | 0x65 ('e') | 0x6c ('l') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 32| 0x6f ('o') | 0x57 ('W') | 0x6f ('o') | 0x72 ('r') | +---------------+---------------+---------------+---------------+ 36| 0x6c ('l') | 0x64 ('d') | +---------------+---------------+ Total 38 bytes (24 byte header, 4 byte extras, 5 byte key and 5 byte value) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x00 Key length (2,3) : 0x0005 Extra length (4) : 0x04 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000009 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000001 Extras : Flags (24-27): 0xdeadbeef Key (28-32): The textual string: "Hello" Value (33-37): The textual string: "World"
MUST have extras. MUST have key. MUST have value. 4 byte flags 4 byte expiration time
Extra data for set/add/replace: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Flags | +---------------+---------------+---------------+---------------+ 4| Expiration | +---------------+---------------+---------------+---------------+ Total 8 bytes
If the Data Version Check (CAS) is nonzero, the requested operation MUST only succeed if the item exists and has a CAS value identical to the provided value. Add MUST fail if the item already exist. Replace MUST fail if the item doesn't exist. Set should store the data unconditionally if the item exists or not. Quiet mutations only return responses on failure. Success is considered the general case and is suppressed when in quiet mode, but errors should not be allowed to go unnoticed.
The following figure shows an add-command for Key: "Hello" Value: "World" Flags: 0xdeadbeef Expiry: in two hours
Add request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x02 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 4| 0x08 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x12 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0xde | 0xad | 0xbe | 0xef | +---------------+---------------+---------------+---------------+ 28| 0x00 | 0x00 | 0x0e | 0x10 | +---------------+---------------+---------------+---------------+ 32| 0x48 ('H') | 0x65 ('e') | 0x6c ('l') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 36| 0x6f ('o') | 0x57 ('W') | 0x6f ('o') | 0x72 ('r') | +---------------+---------------+---------------+---------------+ 40| 0x6c ('l') | 0x64 ('d') | +---------------+---------------+ Total 42 bytes (24 byte header, 8 byte extras, 5 byte key and 5 byte value) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x02 Key length (2,3) : 0x0005 Extra length (4) : 0x08 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000012 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : Flags (24-27): 0xdeadbeef Expiry (28-31): 0x00000e10 Key (32-36): The textual string "Hello" Value (37-41): The textual string "World"
The response-packet contains no extra data, and the result of the operation is signaled through the status code. If the command succeeds, the CAS value for the item is returned in the CAS-field of the packet.
Successful add response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x02 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x01 | +---------------+---------------+---------------+---------------+ Total 24 bytes Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x02 Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000000 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000001 Extras : None Key : None Value : None
MUST NOT have extras. MUST have key. MUST NOT have value. Delete the item with the specific key.
The following figure shows a delete message for the item "Hello".
Delete request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x04 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x48 ('H') | 0x65 ('e') | 0x6c ('l') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 28| 0x6f ('o') | +---------------+ Total 29 bytes (24 byte header, 5 byte value) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x04 Key length (2,3) : 0x0005 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000005 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : The textual string "Hello" Value : None
The response-packet contains no extra data, and the result of the operation is signaled through the status code.
MUST have extras. MUST have key. MUST NOT have value. 8 byte value to add / subtract 8 byte initial value (unsigned) 4 byte expiration time
Extra data for incr/decr: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Amount to add | | | +---------------+---------------+---------------+---------------+ 8| Initial value | | | +---------------+---------------+---------------+---------------+ 16| Expiration | +---------------+---------------+---------------+---------------+ Total 20 bytes
These commands will either add or remove the specified amount to the requested counter. If the counter does not exist, one of two things may happen: If the expiration value is all one-bits (0xffffffff), the operation will fail with NOT_FOUND. For all other expiration values, the operation will succeed by seeding the value for this key with the provided initial value to expire with the provided expiration time. The flags will be set to zero.
incr/decr response body: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 64-bit unsigned response. | | | +---------------+---------------+---------------+---------------+ Total 8 bytes
The following figure shows an incr-command for Key: "counter" Delta: 0x01 Initial: 0x00 Expiry: in two hours
Increment request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x05 | 0x00 | 0x07 | +---------------+---------------+---------------+---------------+ 4| 0x14 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x1b | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 28| 0x00 | 0x00 | 0x00 | 0x01 | +---------------+---------------+---------------+---------------+ 32| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 36| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 40| 0x00 | 0x00 | 0x0e | 0x10 | +---------------+---------------+---------------+---------------+ 44| 0x63 ('c') | 0x6f ('o') | 0x75 ('u') | 0x6e ('n') | +---------------+---------------+---------------+---------------+ 48| 0x74 ('t') | 0x65 ('e') | 0x72 ('r') | +---------------+---------------+---------------+ Total 51 bytes (24 byte header, 20 byte extras, 7 byte key) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x05 Key length (2,3) : 0x0007 Extra length (4) : 0x14 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x0000001b Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : delta (24-31): 0x0000000000000001 initial (32-39): 0x0000000000000000 exipration (40-43): 0x00000e10 Key : Textual string "counter" Value : None
If the key doesn't exist, the server will respond with the initial value. If not the incremented value will be returned. Let's assume that the key didn't exist, so the initial value is returned.
Increment response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x05 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x08 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 24| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 28| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ Total 32 bytes (24 byte header, 8 byte value) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x05 Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000008 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000005 Extras : None Key : None Value : 0x0000000000000000
MUST NOT have extras. MUST NOT have key. MUST NOT have value. Close the connection to the server.
Quit request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x07 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ Total 24 bytes Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x07 Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000000 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : None Value : None
The response-packet contains no extra data, and the result of the operation is signaled through the status code. The server will then close the connection.
MAY have extras. MUST NOT have key. MUST NOT have value. 4 byte expiration time
Extra data for flush: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Expiration | +---------------+---------------+---------------+---------------+ Total 4 bytes
Flush the items in the cache now or some time in the future as specified by the expiration field. See the documentation of the textual protocol for the full description on how to specify the expiration time.
To flush the cache (delete all items) in two hours, the set the following values in the request
Flush request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x08 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x04 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x04 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x00 | 0x00 | 0x0e | 0x10 | +---------------+---------------+---------------+---------------+ Total 28 bytes (24 byte header, 4 byte body) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x08 Key length (2,3) : 0x0000 Extra length (4) : 0x04 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000004 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : Expiry (24-27): 0x000e10 Key : None Value : None
The response-packet contains no extra data, and the result of the operation is signaled through the status code.
MUST NOT have extras. MUST NOT have key. MUST NOT have value. Used as a keep alive. Flushes outstanding getq/getkq's.
Noop request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x0a | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ Total 24 bytes Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x0a Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000000 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : None Value : None
The response-packet contains no extra data, and the result of the operation is signaled through the status code.
MUST NOT have extras. MUST NOT have key. MUST NOT have value. Request the server version. The server responds with a packet containing the version string in the body with the following format: "x.y.z"
Version request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x0b | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ Total 24 bytes Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x0b Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000000 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None
Version response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x0b | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x31 ('1') | 0x2e ('.') | 0x33 ('3') | 0x2e ('.') | +---------------+---------------+---------------+---------------+ 28| 0x31 ('1') | +---------------+ Total 29 bytes (24 byte header, 5 byte body) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x0b Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000005 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : None Value : Textual string "1.3.1"
MUST NOT have extras. MUST have key. MUST have value. These commands will either append or prepend the specified value to the requested key.
The following example appends '!' to the 'Hello' key.
Append request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x0e | 0x00 | 0x05 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x06 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x48 ('H') | 0x65 ('e') | 0x6c ('l') | 0x6c ('l') | +---------------+---------------+---------------+---------------+ 28| 0x6f ('o') | 0x21 ('!') | +---------------+---------------+ Total 30 bytes (24 byte header, 5 byte key, 1 byte value) Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x0e Key length (2,3) : 0x0005 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000006 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key (24-28): The textual string "Hello" Value (29) : "!"
The response-packet contains no extra data, and the result of the operation is signaled through the status code.
MUST NOT have extras. MAY have key. MUST NOT have value. Request server statistics. Without a key specified the server will respond with a "default" set of statistics information. Each piece of statistical information is returned in its own packet (key contains the name of the statistical item and the body contains the value in ASCII format). The sequence of return packets is terminated with a packet that contains no key and no value.
The following example requests all statistics from the server
Stat request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x80 | 0x10 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ Total 24 bytes Field (offset) (value) Magic (0) : 0x80 Opcode (1) : 0x10 Key length (2,3) : 0x0000 Extra length (4) : 0x00 Data type (5) : 0x00 Reserved (6,7) : 0x0000 Total body (8-11) : 0x00000000 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Extras : None Key : None Value : None
The server will send each value in a separate packet with an "empty" packet (no key / no value) to terminate the sequence. Each of the response packets look like the following example:
Stat response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| 0x81 | 0x10 | 0x00 | 0x03 | +---------------+---------------+---------------+---------------+ 4| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 8| 0x00 | 0x00 | 0x00 | 0x07 | +---------------+---------------+---------------+---------------+ 12| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 16| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 20| 0x00 | 0x00 | 0x00 | 0x00 | +---------------+---------------+---------------+---------------+ 24| 0x70 ('p') | 0x69 ('i') | 0x64 ('d') | 0x33 ('3') | +---------------+---------------+---------------+---------------+ 28| 0x30 ('0') | 0x37 ('7') | 0x38 ('8') | +---------------+---------------+---------------+ Total 31 bytes (24 byte header, 3 byte key, 4 byte body) Field (offset) (value) Magic (0) : 0x81 Opcode (1) : 0x10 Key length (2,3) : 0x0003 Extra length (4) : 0x00 Data type (5) : 0x00 Status (6,7) : 0x0000 Total body (8-11) : 0x00000007 Opaque (12-15): 0x00000000 CAS (16-23): 0x0000000000000000 Exstras : None Key : The textual string "pid" Value : The textual string "3078"
Memcache has no authentication or security layers whatsoever. It is RECOMMENDED that memcache be deployed strictly on closed, protected, back-end networks within a single data center, within a single cluster of servers, or even on a single host, providing shared caching for multiple applications. Memcache MUST NOT be made available on a public network.
LJ NEEDS MOAR SPEED Danga Interactive http://www.livejournal.com/
Thanks to Brad Fitzpatrick, Anatoly Vorobey, Steven Grimm, and Dustin Sallings, for their work on the memcached server. Thanks to Sean Chittenden, Jonathan Steinert, Brian Aker, Evan Martin, Nathan Neulinger, Eric Hodel, Michael Johnson, Paul Querna, Jamie McCarthy, Philip Neustrom, Andrew O'Brien, Josh Rotenberg, Robin H. Johnson, Tim Yardley, Paolo Borelli, Eli Bingham, Jean-Francois Bustarret, Paul G, Paul Lindner, Alan Kasindorf, Chris Goffinet, Tomash Brechko, and others for their work reporting bugs and maintaining memcached client libraries and bindings in many languages.
memcached-1.4.14/doc/protocol-binary-range.xml0000644000175000017500000002230011701635506016135 00000000000000 Memcache Binary Protocol: Extensions for UDP Six Apart, Ltd.
548 4th Street San Francisco CA 94107 USA aaron@serendipity.palo-alto.ca.us
Applications memcache memcached cache udp This memo explains extensions to the memcache binary protocol for use in a UDP environment. Memcache is a high performance key-value cache. It is intentionally a dumb cache, optimized for speed only. Applications using memcache do not rely on it for data -- a persistent database with guaranteed reliability is strongly recommended -- but applications can run much faster when cached data is available in memcache.
Memcache is a high performance key-value cache. It is intentionally a dumb cache, optimized for speed only. Applications using memcache do not rely on it for data -- a persistent database with guaranteed reliability is strongly recommended -- but applications can run much faster when cached data is available in memcache. Sites may find that, due to their network architecture or application usage patterns, the stateless protocol better suits their needs. This document provides extensions and descriptions of use of the memcache protocol in a UDP environment. It is a goal of this document to provide sufficient information in each UDP packet as to avoid any requirement for statefulness on the part of the server nor significant caching of outstanding packets on the part of the client.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in .
The magic bytes remains the same as in .
Additional status values: Value is larger than a single response packet
Additional opcode values: Get Range Set Range
There are no new data types in this extension.
This section extends the behavior of the Get and GetQ commands as described in . When a Get or GetQ request is made via UDP, and the value of the key for which the request was made is larger than can be placed into a single UDP packet (noting that the protocol header must also be counted), a Get Range response packet MUST be sent instead of the Get response packet. In this instance: The Status field of the response header MUST be 0x0004. The Offset field of the GetR response extras MUST be 0. The Length field of the GetR response extras, and the data contained in the Value field of the packet, SHOULD be the maximum allowed length of a UDP packet, less the space required by the header and extras; however it MAY be any amount below this maximum. The Total value length field of the response extras MUST be the actual length of the complete value. The client, upon receipt of a Get Range response bearing Status 0x004 and a Message ID corresponding to its Get request, shall then know that it has received only the first portion of the value. The client MAY choose to request the remaining portion of the value by sending one or more Get Range requests.
The Get Range request is primarily intended for use over a UDP transport to request byte ranges of the value for a key. In the event that the Data version check fails to match that of the key, an error MUST be returned.
Extra data for get range request: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Flags | +---------------+---------------+---------------+---------------+ 4| Data version check | | | +---------------+---------------+---------------+---------------+ 12| Offset | +---------------+---------------+---------------+---------------+ 16| Length | +---------------+---------------+---------------+---------------+ Total 20 bytes
The Get Range request is primarily intended for use over a UDP transport to indicate the location of the bytes of the value for a key contained in a given packet. A client receives enough information in each Get Range extras to construct an appropriately sized buffer in its own memory and blindly insert the contents of the packet at the given byte offset.
Extra data for get range response: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0| Flags | +---------------+---------------+---------------+---------------+ 4| Data version check | | | +---------------+---------------+---------------+---------------+ 12| Offset | +---------------+---------------+---------------+---------------+ 16| Length | +---------------+---------------+---------------+---------------+ 20| Total value length | +---------------+---------------+---------------+---------------+ Total 24 bytes
This document does not introduce any new security considerations beyond those discussed in .
memcached-1.4.14/doc/readme.txt0000644000175000017500000000011211701635506013171 00000000000000To build the documentation you need xml2rfc ( http://xml.resource.org/ ). memcached-1.4.14/doc/Makefile.in0000644000175000017500000003222512005572432013246 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILD_SPECIFICATIONS_TRUE@am__append_1 = protocol-binary.txt protocol-binary-range.txt subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/version.m4 \ $(top_srcdir)/m4/c99-backport.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DTRACE = @DTRACE@ DTRACEFLAGS = @DTRACEFLAGS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_SASL = @ENABLE_SASL@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PROFILER = @PROFILER@ PROFILER_FLAGS = @PROFILER_FLAGS@ PROFILER_LDFLAGS = @PROFILER_LDFLAGS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ XML2RFC = @XML2RFC@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = memcached.1 EXTRA_DIST = *.txt BUILT_SOURCES = $(am__append_1) @BUILD_SPECIFICATIONS_TRUE@MOSTLYCLEANFILES = protocol-binary.txt protocol-binary-range.txt all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: all check install install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-man uninstall-man1 %.txt: %.full @XML2RFC@ $< $@ %.chk: %.xml xml2rfc/rfc2629-refchk.xsl @XSLTPROC@ xml2rfc/rfc2629-refchk.xsl $< >$@ %.full: %.xml xml2rfc/rfc2629-noinc.xsl @XSLTPROC@ xml2rfc/rfc2629-noinc.xsl $< >$@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: memcached-1.4.14/doc/xml2rfc/0000755000175000017500000000000011701635506012636 500000000000000memcached-1.4.14/doc/xml2rfc/rfc2629-other.ent0000644000175000017500000000725411701635506015512 00000000000000 memcached-1.4.14/doc/xml2rfc/reference.RFC.0768.xml0000644000175000017500000000130011701635506016244 00000000000000 User Datagram Protocol University of Southern California (USC)/Information Sciences Institute
4676 Admiralty Way Marina del Rey CA 90291 US +1 213 822 1511
memcached-1.4.14/doc/xml2rfc/rfc2629-xhtml.ent0000644000175000017500000003617011701635506015524 00000000000000 memcached-1.4.14/doc/xml2rfc/rfc2629-noinc.xsl0000644000175000017500000000617111701635506015514 00000000000000 .xml http://xml.resource.org/public/rfc/ .xml memcached-1.4.14/doc/xml2rfc/rfc2629-refchk.xsl0000644000175000017500000000500611701635506015644 00000000000000 memcached-1.4.14/doc/xml2rfc/rfc2629.dtd0000644000175000017500000002074511701635506014360 00000000000000 %rfc2629-xhtml; %rfc2629-other; memcached-1.4.14/doc/protocol.txt0000644000175000017500000010430312005173037013576 00000000000000Protocol -------- Clients of memcached communicate with server through TCP connections. (A UDP interface is also available; details are below under "UDP protocol.") A given running memcached server listens on some (configurable) port; clients connect to that port, send commands to the server, read responses, and eventually close the connection. There is no need to send any command to end the session. A client may just close the connection at any moment it no longer needs it. Note, however, that clients are encouraged to cache their connections rather than reopen them every time they need to store or retrieve data. This is because memcached is especially designed to work very efficiently with a very large number (many hundreds, more than a thousand if necessary) of open connections. Caching connections will eliminate the overhead associated with establishing a TCP connection (the overhead of preparing for a new connection on the server side is insignificant compared to this). There are two kinds of data sent in the memcache protocol: text lines and unstructured data. Text lines are used for commands from clients and responses from servers. Unstructured data is sent when a client wants to store or retrieve data. The server will transmit back unstructured data in exactly the same way it received it, as a byte stream. The server doesn't care about byte order issues in unstructured data and isn't aware of them. There are no limitations on characters that may appear in unstructured data; however, the reader of such data (either a client or a server) will always know, from a preceding text line, the exact length of the data block being transmitted. Text lines are always terminated by \r\n. Unstructured data is _also_ terminated by \r\n, even though \r, \n or any other 8-bit characters may also appear inside the data. Therefore, when a client retrieves data from a server, it must use the length of the data block (which it will be provided with) to determine where the data block ends, and not the fact that \r\n follows the end of the data block, even though it does. Keys ---- Data stored by memcached is identified with the help of a key. A key is a text string which should uniquely identify the data for clients that are interested in storing and retrieving it. Currently the length limit of a key is set at 250 characters (of course, normally clients wouldn't need to use such long keys); the key must not include control characters or whitespace. Commands -------- There are three types of commands. Storage commands (there are six: "set", "add", "replace", "append" "prepend" and "cas") ask the server to store some data identified by a key. The client sends a command line, and then a data block; after that the client expects one line of response, which will indicate success or failure. Retrieval commands (there are two: "get" and "gets") ask the server to retrieve data corresponding to a set of keys (one or more keys in one request). The client sends a command line, which includes all the requested keys; after that for each item the server finds it sends to the client one response line with information about the item, and one data block with the item's data; this continues until the server finished with the "END" response line. All other commands don't involve unstructured data. In all of them, the client sends one command line, and expects (depending on the command) either one line of response, or several lines of response ending with "END" on the last line. A command line always starts with the name of the command, followed by parameters (if any) delimited by whitespace. Command names are lower-case and are case-sensitive. Expiration times ---------------- Some commands involve a client sending some kind of expiration time (relative to an item or to an operation requested by the client) to the server. In all such cases, the actual value sent may either be Unix time (number of seconds since January 1, 1970, as a 32-bit value), or a number of seconds starting from current time. In the latter case, this number of seconds may not exceed 60*60*24*30 (number of seconds in 30 days); if the number sent by a client is larger than that, the server will consider it to be real Unix time value rather than an offset from current time. Error strings ------------- Each command sent by a client may be answered with an error string from the server. These error strings come in three types: - "ERROR\r\n" means the client sent a nonexistent command name. - "CLIENT_ERROR \r\n" means some sort of client error in the input line, i.e. the input doesn't conform to the protocol in some way. is a human-readable error string. - "SERVER_ERROR \r\n" means some sort of server error prevents the server from carrying out the command. is a human-readable error string. In cases of severe server errors, which make it impossible to continue serving the client (this shouldn't normally happen), the server will close the connection after sending the error line. This is the only case in which the server closes a connection to a client. In the descriptions of individual commands below, these error lines are not again specifically mentioned, but clients must allow for their possibility. Storage commands ---------------- First, the client sends a command line which looks like this: [noreply]\r\n cas [noreply]\r\n - is "set", "add", "replace", "append" or "prepend" "set" means "store this data". "add" means "store this data, but only if the server *doesn't* already hold data for this key". "replace" means "store this data, but only if the server *does* already hold data for this key". "append" means "add this data to an existing key after existing data". "prepend" means "add this data to an existing key before existing data". The append and prepend commands do not accept flags or exptime. They update existing data portions, and ignore new flag and exptime settings. "cas" is a check and set operation which means "store this data but only if no one else has updated since I last fetched it." - is the key under which the client asks to store the data - is an arbitrary 16-bit unsigned integer (written out in decimal) that the server stores along with the data and sends back when the item is retrieved. Clients may use this as a bit field to store data-specific information; this field is opaque to the server. Note that in memcached 1.2.1 and higher, flags may be 32-bits, instead of 16, but you might want to restrict yourself to 16 bits for compatibility with older versions. - is expiration time. If it's 0, the item never expires (although it may be deleted from the cache to make place for other items). If it's non-zero (either Unix time or offset in seconds from current time), it is guaranteed that clients will not be able to retrieve this item after the expiration time arrives (measured by server time). - is the number of bytes in the data block to follow, *not* including the delimiting \r\n. may be zero (in which case it's followed by an empty data block). - is a unique 64-bit value of an existing entry. Clients should use the value returned from the "gets" command when issuing "cas" updates. - "noreply" optional parameter instructs the server to not send the reply. NOTE: if the request line is malformed, the server can't parse "noreply" option reliably. In this case it may send the error to the client, and not reading it on the client side will break things. Client should construct only valid requests. After this line, the client sends the data block: \r\n - is a chunk of arbitrary 8-bit data of length from the previous line. After sending the command line and the data blockm the client awaits the reply, which may be: - "STORED\r\n", to indicate success. - "NOT_STORED\r\n" to indicate the data was not stored, but not because of an error. This normally means that the condition for an "add" or a "replace" command wasn't met. - "EXISTS\r\n" to indicate that the item you are trying to store with a "cas" command has been modified since you last fetched it. - "NOT_FOUND\r\n" to indicate that the item you are trying to store with a "cas" command did not exist. Retrieval command: ------------------ The retrieval commands "get" and "gets" operates like this: get *\r\n gets *\r\n - * means one or more key strings separated by whitespace. After this command, the client expects zero or more items, each of which is received as a text line followed by a data block. After all the items have been transmitted, the server sends the string "END\r\n" to indicate the end of response. Each item sent by the server looks like this: VALUE []\r\n \r\n - is the key for the item being sent - is the flags value set by the storage command - is the length of the data block to follow, *not* including its delimiting \r\n - is a unique 64-bit integer that uniquely identifies this specific item. - is the data for this item. If some of the keys appearing in a retrieval request are not sent back by the server in the item list this means that the server does not hold items with such keys (because they were never stored, or stored but deleted to make space for more items, or expired, or explicitly deleted by a client). Deletion -------- The command "delete" allows for explicit deletion of items: delete [noreply]\r\n - is the key of the item the client wishes the server to delete - "noreply" optional parameter instructs the server to not send the reply. See the note in Storage commands regarding malformed requests. The response line to this command can be one of: - "DELETED\r\n" to indicate success - "NOT_FOUND\r\n" to indicate that the item with this key was not found. See the "flush_all" command below for immediate invalidation of all existing items. Increment/Decrement ------------------- Commands "incr" and "decr" are used to change data for some item in-place, incrementing or decrementing it. The data for the item is treated as decimal representation of a 64-bit unsigned integer. If the current data value does not conform to such a representation, the incr/decr commands return an error (memcached <= 1.2.6 treated the bogus value as if it were 0, leading to confusing). Also, the item must already exist for incr/decr to work; these commands won't pretend that a non-existent key exists with value 0; instead, they will fail. The client sends the command line: incr [noreply]\r\n or decr [noreply]\r\n - is the key of the item the client wishes to change - is the amount by which the client wants to increase/decrease the item. It is a decimal representation of a 64-bit unsigned integer. - "noreply" optional parameter instructs the server to not send the reply. See the note in Storage commands regarding malformed requests. The response will be one of: - "NOT_FOUND\r\n" to indicate the item with this value was not found - \r\n , where is the new value of the item's data, after the increment/decrement operation was carried out. Note that underflow in the "decr" command is caught: if a client tries to decrease the value below 0, the new value will be 0. Overflow in the "incr" command will wrap around the 64 bit mark. Note also that decrementing a number such that it loses length isn't guaranteed to decrement its returned length. The number MAY be space-padded at the end, but this is purely an implementation optimization, so you also shouldn't rely on that. Touch ----- The "touch" command is used to update the expiration time of an existing item without fetching it. touch [noreply]\r\n - is the key of the item the client wishes the server to delete - is expiration time. Works the same as with the update commands (set/add/etc). This replaces the existing expiration time. If an existing item were to expire in 10 seconds, but then was touched with an expiration time of "20", the item would then expire in 20 seconds. - "noreply" optional parameter instructs the server to not send the reply. See the note in Storage commands regarding malformed requests. The response line to this command can be one of: - "TOUCHED\r\n" to indicate success - "NOT_FOUND\r\n" to indicate that the item with this key was not found. Slabs Reassign -------------- NOTE: This command is subject to change as of this writing. The slabs reassign command is used to redistribute memory once a running instance has hit its limit. It might be desireable to have memory laid out differently than was automatically assigned after the server started. slabs reassign \r\n - is an id number for the slab class to steal a page from A source class id of -1 means "pick from any valid class" - is an id number for the slab class to move a page to The response line could be one of: - "OK" to indicate the page has been scheduled to move - "BUSY [message]" to indicate a page is already being processed, try again later. - "BADCLASS [message]" a bad class id was specified - "NOSPARE [message]" source class has no spare pages - "NOTFULL [message]" dest class must be full to move new pages to it - "UNSAFE [message]" source class cannot move a page right now - "SAME [message]" must specify different source/dest ids. Slabs Automove -------------- NOTE: This command is subject to change as of this writing. The slabs automove command enables a background thread which decides on its own when to move memory between slab classes. Its implementation and options will likely be in flux for several versions. See the wiki/mailing list for more details. The automover can be enabled or disabled at runtime with this command. slabs automove <0|1> - 0|1|2 is the indicator on whether to enable the slabs automover or not. The response should always be "OK\r\n" - <0> means to set the thread on standby - <1> means to run the builtin slow algorithm to choose pages to move - <2> is a highly aggressive mode which causes pages to be moved every time there is an eviction. It is not recommended to run for very long in this mode unless your access patterns are very well understood. Statistics ---------- The command "stats" is used to query the server about statistics it maintains and other internal data. It has two forms. Without arguments: stats\r\n it causes the server to output general-purpose statistics and settings, documented below. In the other form it has some arguments: stats \r\n Depending on , various internal data is sent by the server. The kinds of arguments and the data sent are not documented in this version of the protocol, and are subject to change for the convenience of memcache developers. General-purpose statistics -------------------------- Upon receiving the "stats" command without arguments, the server sents a number of lines which look like this: STAT \r\n The server terminates this list with the line END\r\n In each line of statistics, is the name of this statistic, and is the data. The following is the list of all names sent in response to the "stats" command, together with the type of the value sent for this name, and the meaning of the value. In the type column below, "32u" means a 32-bit unsigned integer, "64u" means a 64-bit unsigned integer. '32u.32u' means two 32-bit unsigned integers separated by a colon (treat this as a floating point number). |-----------------------+---------+-------------------------------------------| | Name | Type | Meaning | |-----------------------+---------+-------------------------------------------| | pid | 32u | Process id of this server process | | uptime | 32u | Number of secs since the server started | | time | 32u | current UNIX time according to the server | | version | string | Version string of this server | | pointer_size | 32 | Default size of pointers on the host OS | | | | (generally 32 or 64) | | rusage_user | 32u.32u | Accumulated user time for this process | | | | (seconds:microseconds) | | rusage_system | 32u.32u | Accumulated system time for this process | | | | (seconds:microseconds) | | curr_items | 32u | Current number of items stored | | total_items | 32u | Total number of items stored since | | | | the server started | | bytes | 64u | Current number of bytes used | | | | to store items | | curr_connections | 32u | Number of open connections | | total_connections | 32u | Total number of connections opened since | | | | the server started running | | connection_structures | 32u | Number of connection structures allocated | | | | by the server | | reserved_fds | 32u | Number of misc fds used internally | | cmd_get | 64u | Cumulative number of retrieval reqs | | cmd_set | 64u | Cumulative number of storage reqs | | cmd_flush | 64u | Cumulative number of flush reqs | | cmd_touch | 64u | Cumulative number of touch reqs | | get_hits | 64u | Number of keys that have been requested | | | | and found present | | get_misses | 64u | Number of items that have been requested | | | | and not found | | delete_misses | 64u | Number of deletions reqs for missing keys | | delete_hits | 64u | Number of deletion reqs resulting in | | | | an item being removed. | | incr_misses | 64u | Number of incr reqs against missing keys. | | incr_hits | 64u | Number of successful incr reqs. | | decr_misses | 64u | Number of decr reqs against missing keys. | | decr_hits | 64u | Number of successful decr reqs. | | cas_misses | 64u | Number of CAS reqs against missing keys. | | cas_hits | 64u | Number of successful CAS reqs. | | cas_badval | 64u | Number of CAS reqs for which a key was | | | | found, but the CAS value did not match. | | touch_hits | 64u | Numer of keys that have been touched with | | | | a new expiration time | | touch_misses | 64u | Numer of items that have been touched and | | | | not found | | auth_cmds | 64u | Number of authentication commands | | | | handled, success or failure. | | auth_errors | 64u | Number of failed authentications. | | evictions | 64u | Number of valid items removed from cache | | | | to free memory for new items | | reclaimed | 64u | Number of times an entry was stored using | | | | memory from an expired entry | | bytes_read | 64u | Total number of bytes read by this server | | | | from network | | bytes_written | 64u | Total number of bytes sent by this server | | | | to network | | limit_maxbytes | 32u | Number of bytes this server is allowed to | | | | use for storage. | | threads | 32u | Number of worker threads requested. | | | | (see doc/threads.txt) | | conn_yields | 64u | Number of times any connection yielded to | | | | another due to hitting the -R limit. | | hash_power_level | 32u | Current size multiplier for hash table | | hash_bytes | 64u | Bytes currently used by hash tables | | hash_is_expanding | bool | Indicates if the hash table is being | | | | grown to a new size | | expired_unfetched | 64u | Items pulled from LRU that were never | | | | touched by get/incr/append/etc before | | | | expiring | | evicted_unfetched | 64u | Items evicted from LRU that were never | | | | touched by get/incr/append/etc. | | slab_reassign_running | bool | If a slab page is being moved | | slabs_moved | 64u | Total slab pages moved | |-----------------------+---------+-------------------------------------------| Settings statistics ------------------- CAVEAT: This section describes statistics which are subject to change in the future. The "stats" command with the argument of "settings" returns details of the settings of the running memcached. This is primarily made up of the results of processing commandline options. Note that these are not guaranteed to return in any specific order and this list may not be exhaustive. Otherwise, this returns like any other stats command. |-------------------+----------+----------------------------------------------| | Name | Type | Meaning | |-------------------+----------+----------------------------------------------| | maxbytes | size_t | Maximum number of bytes allows in this cache | | maxconns | 32 | Maximum number of clients allowed. | | tcpport | 32 | TCP listen port. | | udpport | 32 | UDP listen port. | | inter | string | Listen interface. | | verbosity | 32 | 0 = none, 1 = some, 2 = lots | | oldest | 32u | Age of the oldest honored object. | | evictions | on/off | When off, LRU evictions are disabled. | | domain_socket | string | Path to the domain socket (if any). | | umask | 32 (oct) | umask for the creation of the domain socket. | | growth_factor | float | Chunk size growth factor. | | chunk_size | 32 | Minimum space allocated for key+value+flags. | | num_threads | 32 | Number of threads (including dispatch). | | stat_key_prefix | char | Stats prefix separator character. | | detail_enabled | bool | If yes, stats detail is enabled. | | reqs_per_event | 32 | Max num IO ops processed within an event. | | cas_enabled | bool | When no, CAS is not enabled for this server. | | tcp_backlog | 32 | TCP listen backlog. | | auth_enabled_sasl | yes/no | SASL auth requested and enabled. | | item_size_max | size_t | maximum item size | | maxconns_fast | bool | If fast disconnects are enabled | | hashpower_init | 32 | Starting size multiplier for hash table | | slab_reassign | bool | Whether slab page reassignment is allowed | | slab_automove | bool | Whether slab page automover is enabled | |-------------------+----------+----------------------------------------------| Item statistics --------------- CAVEAT: This section describes statistics which are subject to change in the future. The "stats" command with the argument of "items" returns information about item storage per slab class. The data is returned in the format: STAT items:: \r\n The server terminates this list with the line END\r\n The slabclass aligns with class ids used by the "stats slabs" command. Where "stats slabs" describes size and memory usage, "stats items" shows higher level information. The following item values are defined as of writing. Name Meaning ------------------------------ number Number of items presently stored in this class. Expired items are not automatically excluded. age Age of the oldest item in the LRU. evicted Number of times an item had to be evicted from the LRU before it expired. evicted_nonzero Number of times an item which had an explicit expire time set had to be evicted from the LRU before it expired. evicted_time Seconds since the last access for the most recent item evicted from this class. Use this to judge how recently active your evicted data is. outofmemory Number of times the underlying slab class was unable to store a new item. This means you are running with -M or an eviction failed. tailrepairs Number of times we self-healed a slab with a refcount leak. If this counter is increasing a lot, please report your situation to the developers. reclaimed Number of times an entry was stored using memory from an expired entry. expired_unfetched Number of expired items reclaimed from the LRU which were never touched after being set. evicted_unfetched Number of valid items evicted from the LRU which were never touched after being set. Note this will only display information about slabs which exist, so an empty cache will return an empty set. Item size statistics -------------------- CAVEAT: This section describes statistics which are subject to change in the future. The "stats" command with the argument of "sizes" returns information about the general size and count of all items stored in the cache. WARNING: This command WILL lock up your cache! It iterates over *every item* and examines the size. While the operation is fast, if you have many items you could prevent memcached from serving requests for several seconds. The data is returned in the following format: \r\n The server terminates this list with the line END\r\n 'size' is an approximate size of the item, within 32 bytes. 'count' is the amount of items that exist within that 32-byte range. This is essentially a display of all of your items if there was a slab class for every 32 bytes. You can use this to determine if adjusting the slab growth factor would save memory overhead. For example: generating more classes in the lower range could allow items to fit more snugly into their slab classes, if most of your items are less than 200 bytes in size. Slab statistics --------------- CAVEAT: This section describes statistics which are subject to change in the future. The "stats" command with the argument of "slabs" returns information about each of the slabs created by memcached during runtime. This includes per-slab information along with some totals. The data is returned in the format: STAT : \r\n STAT \r\n The server terminates this list with the line END\r\n |-----------------+----------------------------------------------------------| | Name | Meaning | |-----------------+----------------------------------------------------------| | chunk_size | The amount of space each chunk uses. One item will use | | | one chunk of the appropriate size. | | chunks_per_page | How many chunks exist within one page. A page by | | | default is less than or equal to one megabyte in size. | | | Slabs are allocated by page, then broken into chunks. | | total_pages | Total number of pages allocated to the slab class. | | total_chunks | Total number of chunks allocated to the slab class. | | get_hits | Total number of get requests serviced by this class. | | cmd_set | Total number of set requests storing data in this class. | | delete_hits | Total number of successful deletes from this class. | | incr_hits | Total number of incrs modifying this class. | | decr_hits | Total number of decrs modifying this class. | | cas_hits | Total number of CAS commands modifying this class. | | cas_badval | Total number of CAS commands that failed to modify a | | | value due to a bad CAS id. | | touch_hits | Total number of touches serviced by this class. | | used_chunks | How many chunks have been allocated to items. | | free_chunks | Chunks not yet allocated to items, or freed via delete. | | free_chunks_end | Number of free chunks at the end of the last allocated | | | page. | | mem_requested | Number of bytes requested to be stored in this slab[*]. | | active_slabs | Total number of slab classes allocated. | | total_malloced | Total amount of memory allocated to slab pages. | |-----------------+----------------------------------------------------------| * Items are stored in a slab that is the same size or larger than the item. mem_requested shows the size of all items within a slab. (total_chunks * chunk_size) - mem_requested shows memory wasted in a slab class. If you see a lot of waste, consider tuning the slab factor. Other commands -------------- "flush_all" is a command with an optional numeric argument. It always succeeds, and the server sends "OK\r\n" in response (unless "noreply" is given as the last parameter). Its effect is to invalidate all existing items immediately (by default) or after the expiration specified. After invalidation none of the items will be returned in response to a retrieval command (unless it's stored again under the same key *after* flush_all has invalidated the items). flush_all doesn't actually free all the memory taken up by existing items; that will happen gradually as new items are stored. The most precise definition of what flush_all does is the following: it causes all items whose update time is earlier than the time at which flush_all was set to be executed to be ignored for retrieval purposes. The intent of flush_all with a delay, was that in a setting where you have a pool of memcached servers, and you need to flush all content, you have the option of not resetting all memcached servers at the same time (which could e.g. cause a spike in database load with all clients suddenly needing to recreate content that would otherwise have been found in the memcached daemon). The delay option allows you to have them reset in e.g. 10 second intervals (by passing 0 to the first, 10 to the second, 20 to the third, etc. etc.). "version" is a command with no arguments: version\r\n In response, the server sends "VERSION \r\n", where is the version string for the server. "verbosity" is a command with a numeric argument. It always succeeds, and the server sends "OK\r\n" in response (unless "noreply" is given as the last parameter). Its effect is to set the verbosity level of the logging output. "quit" is a command with no arguments: quit\r\n Upon receiving this command, the server closes the connection. However, the client may also simply close the connection when it no longer needs it, without issuing this command. UDP protocol ------------ For very large installations where the number of clients is high enough that the number of TCP connections causes scaling difficulties, there is also a UDP-based interface. The UDP interface does not provide guaranteed delivery, so should only be used for operations that aren't required to succeed; typically it is used for "get" requests where a missing or incomplete response can simply be treated as a cache miss. Each UDP datagram contains a simple frame header, followed by data in the same format as the TCP protocol described above. In the current implementation, requests must be contained in a single UDP datagram, but responses may span several datagrams. (The only common requests that would span multiple datagrams are huge multi-key "get" requests and "set" requests, both of which are more suitable to TCP transport for reliability reasons anyway.) The frame header is 8 bytes long, as follows (all values are 16-bit integers in network byte order, high byte first): 0-1 Request ID 2-3 Sequence number 4-5 Total number of datagrams in this message 6-7 Reserved for future use; must be 0 The request ID is supplied by the client. Typically it will be a monotonically increasing value starting from a random seed, but the client is free to use whatever request IDs it likes. The server's response will contain the same ID as the incoming request. The client uses the request ID to differentiate between responses to outstanding requests if there are several pending from the same server; any datagrams with an unknown request ID are probably delayed responses to an earlier request and should be discarded. The sequence number ranges from 0 to n-1, where n is the total number of datagrams in the message. The client should concatenate the payloads of the datagrams for a given response in sequence number order; the resulting byte stream will contain a complete response in the same format as the TCP protocol (including terminating \r\n sequences). memcached-1.4.14/doc/Makefile0000644000175000017500000003315512005572437012651 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # doc/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. pkgdatadir = $(datadir)/memcached pkgincludedir = $(includedir)/memcached pkglibdir = $(libdir)/memcached pkglibexecdir = $(libexecdir)/memcached am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-unknown-linux-gnu host_triplet = x86_64-unknown-linux-gnu target_triplet = x86_64-unknown-linux-gnu #am__append_1 = protocol-binary.txt protocol-binary-range.txt subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/version.m4 \ $(top_srcdir)/m4/c99-backport.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run aclocal-1.11 AMTAR = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run tar AUTOCONF = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run autoconf AUTOHEADER = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run autoheader AUTOMAKE = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run automake-1.11 AWK = gawk CC = gcc -std=gnu99 CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 -pthread -Wall -Werror -pedantic -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -fno-strict-aliasing CPP = gcc -E CPPFLAGS = CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DTRACE = DTRACEFLAGS = ECHO_C = ECHO_N = -n ECHO_T = EGREP = /bin/grep -E ENABLE_SASL = EXEEXT = GREP = /bin/grep INSTALL = /usr/bin/install -c INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LDFLAGS = LIBOBJS = LIBS = -levent -lrt LTLIBOBJS = MAKEINFO = ${SHELL} /home/dormando/p/danga/git/memcached/missing --run makeinfo MKDIR_P = /bin/mkdir -p OBJEXT = o PACKAGE = memcached PACKAGE_BUGREPORT = memcached@googlegroups.com PACKAGE_NAME = memcached PACKAGE_STRING = memcached 1.4.14 PACKAGE_TARNAME = memcached PACKAGE_URL = PACKAGE_VERSION = 1.4.14 PATH_SEPARATOR = : PROFILER = /usr/bin/gcov PROFILER_FLAGS = -fprofile-arcs -ftest-coverage PROFILER_LDFLAGS = -lgcov SET_MAKE = SHELL = /bin/bash STRIP = VERSION = 1.4.14 XML2RFC = no XSLTPROC = /usr/bin/xsltproc abs_builddir = /home/dormando/p/danga/git/memcached/doc abs_srcdir = /home/dormando/p/danga/git/memcached/doc abs_top_builddir = /home/dormando/p/danga/git/memcached abs_top_srcdir = /home/dormando/p/danga/git/memcached ac_ct_CC = gcc am__include = include am__leading_dot = . am__quote = am__tar = ${AMTAR} chof - "$$tardir" am__untar = ${AMTAR} xf - bindir = ${exec_prefix}/bin build = x86_64-unknown-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = unknown builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} host = x86_64-unknown-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = unknown htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /home/dormando/p/danga/git/memcached/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var mandir = ${datarootdir}/man mkdir_p = /bin/mkdir -p oldincludedir = /usr/include pdfdir = ${docdir} prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . sysconfdir = ${prefix}/etc target = x86_64-unknown-linux-gnu target_alias = target_cpu = x86_64 target_os = linux-gnu target_vendor = unknown top_build_prefix = ../ top_builddir = .. top_srcdir = .. man_MANS = memcached.1 EXTRA_DIST = *.txt BUILT_SOURCES = $(am__append_1) #MOSTLYCLEANFILES = protocol-binary.txt protocol-binary-range.txt all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: all check install install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-man uninstall-man1 %.txt: %.full no $< $@ %.chk: %.xml xml2rfc/rfc2629-refchk.xsl /usr/bin/xsltproc xml2rfc/rfc2629-refchk.xsl $< >$@ %.full: %.xml xml2rfc/rfc2629-noinc.xsl /usr/bin/xsltproc xml2rfc/rfc2629-noinc.xsl $< >$@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: memcached-1.4.14/compile0000755000175000017500000000727111331674343012022 00000000000000#! /bin/sh # Wrapper for compilers which do not understand `-c -o'. scriptversion=2009-10-06.20; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software # Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand `-c -o'. Remove `-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file `INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; esac ofile= cfile= eat= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as `compile cc -o foo foo.c'. # So we strip `-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no `-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # `.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use `[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: