aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/diameter/.gitignore57
-rw-r--r--lib/diameter/Makefile32
-rw-r--r--lib/diameter/Makefile.in88
-rw-r--r--lib/diameter/aclocal.m465
-rwxr-xr-xlib/diameter/autoconf/config.guess1519
-rwxr-xr-xlib/diameter/autoconf/config.sub1630
-rwxr-xr-xlib/diameter/autoconf/install-sh519
-rw-r--r--lib/diameter/configure.in137
-rw-r--r--lib/diameter/doc/.gitignore4
-rw-r--r--lib/diameter/doc/src/Makefile10
-rw-r--r--lib/diameter/doc/src/diameter.xml103
-rw-r--r--lib/diameter/doc/src/diameter_transport.xml42
-rw-r--r--lib/diameter/make/release_targets.mk92
-rw-r--r--lib/diameter/make/rules.mk.in193
-rw-r--r--lib/diameter/make/subdir.mk53
-rw-r--r--lib/diameter/make/target.mk33
-rw-r--r--lib/diameter/src/Makefile9
-rw-r--r--lib/diameter/src/base/diameter.erl16
-rw-r--r--lib/diameter/src/base/diameter_config.erl81
-rw-r--r--lib/diameter/src/base/diameter_peer.erl2
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl82
-rw-r--r--lib/diameter/src/base/diameter_reg.erl255
-rw-r--r--lib/diameter/src/base/diameter_service.erl538
-rw-r--r--lib/diameter/src/base/diameter_session.erl14
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl142
-rw-r--r--lib/diameter/test/Makefile9
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl95
-rw-r--r--lib/diameter/test/diameter_watchdog_SUITE.erl711
-rw-r--r--lib/stdlib/test/dict_SUITE.erl20
-rw-r--r--lib/stdlib/test/dict_test_lib.erl55
-rw-r--r--lib/stdlib/test/sets_SUITE.erl342
-rw-r--r--lib/stdlib/test/sets_test_lib.erl82
-rw-r--r--lib/test_server/src/test_server.erl287
-rw-r--r--lib/test_server/src/test_server_ctrl.erl538
-rw-r--r--lib/test_server/src/test_server_internal.hrl4
-rw-r--r--lib/test_server/src/test_server_node.erl256
36 files changed, 1633 insertions, 6482 deletions
diff --git a/lib/diameter/.gitignore b/lib/diameter/.gitignore
index 5afcbedc23..8b13789179 100644
--- a/lib/diameter/.gitignore
+++ b/lib/diameter/.gitignore
@@ -1,58 +1 @@
-# Match at any level.
-*~
-autom4te.cache
-
-# Compiler derivatives
-#
-# Do not use too creative wildcards.
-# Those might ignore files that should not be ignored.
-
-i686-pc-linux-gnu
-x86_64-unknown-linux-gnu
-i386-apple-darwin[0-9]*.[0-9]*.[0-9]*
-sparc-sun-solaris[0-9]*.[0-9]*
-i386-pc-solaris[0-9]*.[0-9]*
-i386-unknown-freebsd[0-9]*.[0-9]*
-tile-tilera-linux-gnu
-powerpc-unknown-linux-gnu
-
-# Mac OS X
-a.out.dSYM/
-
-# Anchored from $DIAMETER_TOP
-/config.log
-/config.status
-
-/Makefile
-/configure
-
-
-# General patterns for applications in lib.
-#
-# Assume that all test/Emakefiles are generated.
-#
-# Any application with a checked-in test/Emakefile should
-# use a negative pattern in its own .gitignore.
-
-#
-# Files generated by configure.
-#
-
-/configure
-/config.log
-/config.status
-
-
-#
-# Generated documentation. (ie. not doc/src)
-#
-
-/doc/[^s]*
-
-
-#
-# Files generated when building/running tests
-#
-
-/test/*.log
diff --git a/lib/diameter/Makefile b/lib/diameter/Makefile
new file mode 100644
index 0000000000..9961d627cf
--- /dev/null
+++ b/lib/diameter/Makefile
@@ -0,0 +1,32 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2010-2012. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+include vsn.mk
+include subdirs.mk
+
+SUB_DIRECTORIES = $(SUB_DIRS) doc/src
+SPECIAL_TARGETS =
+
+include $(ERL_TOP)/make/otp_subdir.mk
+
+info:
+ @echo "APP_VSN = $(APP_VSN)"
+
+.PHONY: info
diff --git a/lib/diameter/Makefile.in b/lib/diameter/Makefile.in
deleted file mode 100644
index cf38c26045..0000000000
--- a/lib/diameter/Makefile.in
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2010-2011. All Rights Reserved.
-#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# %CopyrightEnd%
-
-ifneq ($(ERL_TOP),)
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-else
-include $(DIAMETER_TOP)/make/target.mk
-include $(DIAMETER_TOP)/make/$(TARGET)/rules.mk
-endif
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include vsn.mk
-VSN=$(DIAMETER_VSN)
-
-DIAMETER_TOP = @DIAMETER_TOP@
-
-
-# ----------------------------------------------------
-# Common Macros
-# ----------------------------------------------------
-
-include subdirs.mk
-
-SUB_DIRECTORIES = $(SUB_DIRS) doc/src
-
-SPECIAL_TARGETS =
-
-ifneq ($(ERL_TOP),)
-ifneq ($(PREFIX),)
-CONFIGURE_OPTS += --prefix=$(PREFIX)
-endif
-endif
-
-
-# ----------------------------------------------------
-# Default Subdir Targets
-# ----------------------------------------------------
-ifneq ($(ERL_TOP),)
-include $(ERL_TOP)/make/otp_subdir.mk
-else
-include $(DIAMETER_TOP)/make/subdir.mk
-endif
-
-.PHONY: reconf conf info version dialyzer
-
-reconf:
- autoconf
-
-conf: do_configure
-
-do_configure: configure
- ./configure $(CONFIGURE_OPTS)
-
-configure: configure.in
- autoconf
-
-info:
- @echo "APP_VSN: $(APP_VSN)"
- @echo "DIAMETER_VSN: $(DIAMETER_VSN)"
-
-version:
- @echo "$(VSN)"
-
-
-dialyzer:
- (cd ./ebin; \
- dialyzer --build_plt \
- --output_plt ../priv/diameter.plt \
- -r ../../diameter/ebin \
- --verbose)
diff --git a/lib/diameter/aclocal.m4 b/lib/diameter/aclocal.m4
deleted file mode 100644
index 2abb47dba2..0000000000
--- a/lib/diameter/aclocal.m4
+++ /dev/null
@@ -1,65 +0,0 @@
-dnl
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2011. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-dnl
-
-dnl
-dnl aclocal.m4
-dnl
-dnl Local macros used in configure.in. The Local Macros which
-dnl could/should be part of autoconf are prefixed LM_, macros specific
-dnl to the Erlang system are prefixed ERL_.
-dnl
-
-dnl ----------------------------------------------------------------------
-dnl
-dnl LM_PROG_INSTALL_DIR
-dnl
-dnl Figure out how to create directories with parents.
-dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better)
-dnl
-dnl We prefer 'install -d', but use 'mkdir -p' if it exists.
-dnl If none of these methods works, we give up.
-dnl
-
-
-AC_DEFUN(LM_PROG_INSTALL_DIR,
-[AC_CACHE_CHECK(how to create a directory including parents,
-ac_cv_prog_mkdir_p,
-[
-temp_name_base=config.$$
-temp_name=$temp_name_base/x/y/z
-$INSTALL -d $temp_name >/dev/null 2>&1
-ac_cv_prog_mkdir_p=none
-if test -d $temp_name; then
- ac_cv_prog_mkdir_p="$INSTALL -d"
-else
- mkdir -p $temp_name >/dev/null 2>&1
- if test -d $temp_name; then
- ac_cv_prog_mkdir_p="mkdir -p"
- fi
-fi
-rm -fr $temp_name_base
-])
-
-case "${ac_cv_prog_mkdir_p}" in
- none) AC_MSG_ERROR(don't know how create directories with parents) ;;
- *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;;
-esac
-])
-
-
diff --git a/lib/diameter/autoconf/config.guess b/lib/diameter/autoconf/config.guess
deleted file mode 100755
index 38a833903b..0000000000
--- a/lib/diameter/autoconf/config.guess
+++ /dev/null
@@ -1,1519 +0,0 @@
-#! /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 Free Software Foundation,
-# Inc.
-
-timestamp='2007-05-17'
-
-# 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 <[email protected]>.
-# Please send patches to <[email protected]>. 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 <[email protected]>."
-
-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
-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.
-# ([email protected] 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 __ELF__ >/dev/null
- 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*:*:*)
- # [email protected] (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 ;;
- 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.*:* | ix86xen:SunOS:5.*:*)
- echo i386-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 <stdio.h> /* 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 <sys/systemcfg.h>
-
- 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:*:[45])
- 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 <stdlib.h>
- #include <unistd.h>
-
- 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 __LP64__ >/dev/null
- 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 <unistd.h>
- 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)
- echo x86_64-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 ;;
- 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:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- 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:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #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; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #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 ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- 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 ;;
- tile:Linux:*:*)
- echo tile-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 xtensa-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"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #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.0*:*)
- 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' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/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 i386.
- echo i386-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; } ;;
- 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.0*:*)
- 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
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <[email protected]>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- 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 ;;
- 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 ;;
-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 <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#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 <sys/param.h>
- 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 <sys/param.h>
-# 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 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
-and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> 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:
diff --git a/lib/diameter/autoconf/config.sub b/lib/diameter/autoconf/config.sub
deleted file mode 100755
index f43233b104..0000000000
--- a/lib/diameter/autoconf/config.sub
+++ /dev/null
@@ -1,1630 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
-
-timestamp='2007-04-29'
-
-# 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 <[email protected]>. 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 <[email protected]>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-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* | \
- 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
- ;;
- -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 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | 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[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)
- 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-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | 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[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-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
- | ymp-* \
- | z8k-*)
- ;;
- # 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
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- 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
- ;;
- cr16c)
- basic_machine=cr16c-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
- ;;
- 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
- ;;
- 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
- ;;
- 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
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- tile*)
- basic_machine=tile-tilera
- os=-linux-gnu
- ;;
- 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
- ;;
- 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[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* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -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* \
- | -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
- ;;
- -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
- ;;
- -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:
diff --git a/lib/diameter/autoconf/install-sh b/lib/diameter/autoconf/install-sh
deleted file mode 100755
index a5897de6ea..0000000000
--- a/lib/diameter/autoconf/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# 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-end: "$"
-# End:
diff --git a/lib/diameter/configure.in b/lib/diameter/configure.in
deleted file mode 100644
index 8acfb28fed..0000000000
--- a/lib/diameter/configure.in
+++ /dev/null
@@ -1,137 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-
-dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1998-2011. All Rights Reserved.
-dnl
-dnl The contents of this file are subject to the Erlang Public License,
-dnl Version 1.1, (the "License"); you may not use this file except in
-dnl compliance with the License. You should have received a copy of the
-dnl Erlang Public License along with this software. If not, it can be
-dnl retrieved online at http://www.erlang.org/.
-dnl
-dnl Software distributed under the License is distributed on an "AS IS"
-dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-dnl the License for the specific language governing rights and limitations
-dnl under the License.
-dnl
-dnl %CopyrightEnd%
-
-if test "x$no_recursion" != "xyes" -a "x$OVERRIDE_CONFIG_CACHE" = "x"; then
- # We do not want to use a common cache!
- cache_file=/dev/null
-fi
-
-AC_INIT(vsn.mk)
-
-dnl <STANDALONE DIAMETER>
-dnl This is needed for diameters own environment to rock,
-dnl but since we are now integrated into OTP, we skip it.
-dnl In order to build stand-alone we need atleast 2.63...
-dnl AC_PREREQ(2.63)
-dnl </STANDALONE DIAMETER>
-
-dnl LM_PRECIOUS_VARS
-
-
-dnl The OTP source tree is the default "top",
-dnl but we can also define our own top: DIAMETER_TOP
-
-if test -n "$ERL_TOP" || test -d $ERL_TOP ; then
- erl_top=${ERL_TOP}
- AC_CONFIG_AUX_DIRS($erl_top/erts/autoconf)
- DIAMETER_TOP=${ERL_TOP}/lib/diameter
-else
- AC_ARG_VAR(DIAMETER_TOP, [Diameter top source directory])
- if test -n "$DIAMETER_TOP" || test -d $DIAMETER_TOP ; then
- AC_CONFIG_AUX_DIRS(autoconf)
- fi
-
- dnl <STANDALONE DIAMETER>
- dnl AC_ERLANG_SUBST_ROOT_DIR
- dnl AC_ERLANG_SUBST_LIB_DIR
- dnl AC_ERLANG_CHECK_LIB([erl_docgen],
- dnl [echo "erl_docgen version \"$ERLANG_LIB_VER_erl_docgen\""
- dnl echo "is installed in \"$ERLANG_LIB_DIR_erl_docgen\""],
- dnl [AC_MSG_ERROR([erl_docgen was not found!])])
- dnl AC_ERLANG_CHECK_LIB([test_server],
- dnl [echo "test_server version \"$ERLANG_LIB_VER_test_server\""
- dnl echo "is installed in \"$ERLANG_LIB_DIR_test_server\""],
- dnl [AC_MSG_ERROR([test_server was not found!])])
- dnl </STANDALONE DIAMETER>
-
-fi
-
-AC_SUBST(DIAMETER_TOP)
-export DIAMETER_TOP
-
-if test "X$host" != "Xfree_source" -a "X$host" != "Xwin32"; then
- AC_CANONICAL_HOST
-fi
-
-TARGET=$host
-AC_SUBST(TARGET)
-
-if test "x$erl_top" = "x"; then
- dnl STANDALONE DIAMETER
- AC_CHECK_PROGS(XSLTPROC, xsltproc)
- if test -z "$XSLTPROC"; then
- echo "xsltproc" >> doc/CONF_INFO
- AC_MSG_WARN([No 'xsltproc' command found: the documentation can not be built])
- fi
-
- AC_CHECK_PROGS(FOP, fop)
- if test -z "$FOP"; then
- AC_MSG_ERROR([No 'fop' command found: the documentation can not be built])
- fi
-fi
-
-dnl
-dnl We can live with Solaris /usr/ucb/install
-dnl
-case $host in
- *-*-solaris*|free_source)
- if test -x /usr/ucb/install; then
- INSTALL="/usr/ucb/install -c"
- fi
- ;;
- *)
- ;;
-esac
-AC_PROG_INSTALL
-LM_PROG_INSTALL_DIR
-
-case $host_os in
- darwin*)
- dnl Need to preserve modification time on archives;
- dnl otherwise, ranlib has to be run on archives
- dnl again after installation.
- INSTALL_DATA="$INSTALL_DATA -p";;
- *)
- ;;
-esac
-
-dnl
-dnl Fix for Tilera install permissions
-dnl
-
-case $build in
- *tile*)
- INSTALL_PROGRAM="$INSTALL_PROGRAM -m755"
- INSTALL_SCRIPT="$INSTALL_SCRIPT -m755"
- ;;
- *)
- ;;
-esac
-
-
-dnl <STANDALONE DIAMETER>
-dnl AC_ERLANG_NEED_ERL([$PATH])
-dnl AC_ERLANG_NEED_ERLC([$PATH])
-dnl </STANDALONE DIAMETER>
-
-AC_OUTPUT(
- Makefile:Makefile.in
- make/$host/rules.mk:make/rules.mk.in
- )
-
diff --git a/lib/diameter/doc/.gitignore b/lib/diameter/doc/.gitignore
new file mode 100644
index 0000000000..b634bdd7ba
--- /dev/null
+++ b/lib/diameter/doc/.gitignore
@@ -0,0 +1,4 @@
+
+/html/
+/man*/
+/pdf/
diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile
index 59ca660797..d1d5e8f869 100644
--- a/lib/diameter/doc/src/Makefile
+++ b/lib/diameter/doc/src/Makefile
@@ -16,13 +16,8 @@
#
# %CopyrightEnd%
-ifneq ($(ERL_TOP),)
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-else
-include $(DIAMETER_TOP)/make/target.mk
-include $(DIAMETER_TOP)/make/$(TARGET)/rules.mk
-endif
include ../../vsn.mk
@@ -155,11 +150,8 @@ info:
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
-ifneq ($(ERL_TOP),)
+
include $(ERL_TOP)/make/otp_release_targets.mk
-else
-include $(DIAMETER_TOP)/make/release_targets.mk
-endif
release_docs_spec: $(LOCAL)docs
$(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf"
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index b8652a7482..80863f8eff 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -375,10 +375,15 @@ is meant in the sense of <c>eval([E|A])</c>.</p>
<warning>
<p>
-Beware of using fun expressions of the form <c>fun Name/Arity</c> (not
-fun Mod:Name/Arity) in situations in which the fun is not short-lived
+Beware of using fun expressions of the form <c>fun Name/Arity</c> in
+situations in which the fun is not short-lived
and code is to be upgraded at runtime since any processes retaining
-such a fun will have a reference to old code.</p>
+such a fun will have a reference to old code.
+In particular, such a value is typically inappropriate in
+configuration passed to <seealso
+marker="#start_service">start_service/2</seealso> or
+<seealso
+marker="#add_transport">add_transport/2</seealso>.</p>
</warning>
<marker id="peer_filter"/>
@@ -699,6 +704,64 @@ the application's <seealso marker="diameter_dict">dictionary</seealso>
file.</p>
</item>
+<tag><c>{restrict_connections, false
+ | node
+ | nodes
+ | [node()]
+ | diameter:evaluable()}</c></tag>
+<item>
+<p>
+Specifies the degree to which multiple transport connections to the
+same peer are accepted by the service.</p>
+
+<p>
+If type <c>[node()]</c> then a connection is rejected if another already
+exists on any of the specified nodes.
+Values of type <c>false</c>, <c>node</c>, <c>nodes</c> or
+<c>diameter:evaluable()</c> are equivalent to values <c>[]</c>,
+<c>[node()]</c>, <c>[node()|nodes()]</c> and the evaluated value,
+respectively, evaluation of each expression taking place whenever a
+new connection is to be established.
+Note that <c>false</c> allows an unlimited number of connections to be
+established with the same peer.</p>
+
+<p>
+Multiple connections are independent and governed
+by their own peer and watchdog state machines.</p>
+
+<p>
+Defaults to <c>nodes</c>.</p>
+</item>
+
+<tag><c>{sequence, {H,N} | <seealso
+ marker="diameter#evaluable">diameter:evaluable()</seealso>}</c></tag>
+<item>
+<p>
+Specifies a constant value <c>H</c> for the topmost <c>32-N</c> bits of
+of 32-bit End-to-End and Hop-by-Hop identifiers generated
+by the service, either explicity or as a return value of a function
+to be evaluated at <seealso
+marker="diameter#start_service">diameter:start_service/2</seealso>.
+In particular, an identifier <c>Id</c> is mapped to a new identifier
+as follows.</p>
+<code>
+(H bsl N) bor (Id band ((1 bsl N) - 1))
+</code>
+<p>
+Note that RFC 3588 requires that End-to-End identifiers remain unique
+for a period of at least 4 minutes and that this and the call rate
+places a lower bound on the appropriate values of <c>N</c>:
+at a rate of <c>R</c> requests per second an <c>N</c>-bit counter
+traverses all of its values in <c>(1 bsl N) div (R*60)</c> minutes so
+the bound is <c>4*R*60 =&lt; 1 bsl N</c>.</p>
+
+<p><c>N</c> must lie in the range <c>0..32</c> and <c>H</c> must be a
+non-negative integer less than <c>1 bsl (32-N)</c>.</p>
+
+<p>
+Defaults to <c>{0,32}</c>.</p>
+</item>
+
</taglist>
<marker id="transport_opt"/>
@@ -850,7 +913,7 @@ reconnection attempts, as required by RFC 3539.</p>
For a listening transport, the timer specifies the time after which a
previously connected peer will be forgotten: a connection after this time is
regarded as an initial connection rather than a reestablishment,
-causing the RFC 3539 state machine to pass to state OPEN rather than
+causing the RFC 3539 state machine to pass to state OKAY rather than
REOPEN.
Note that these semantics are not goverened by the RFC and
that a listening transport's <c>reconnect_timer</c> should be greater
@@ -1149,6 +1212,12 @@ DPA or timeout.</p>
<desc>
<p>
Return information about a started service.
+Requesting info for an unknown service causes <c>undefined</c> to be
+returned.
+Requesting a list of items causes a tagged list to be
+returned.</p>
+
+<p>
<c>Item</c> can be one of the following.</p>
<taglist>
@@ -1419,13 +1488,27 @@ The Diameter-level statistics returned by <c>transport</c> and
<c>connections</c> info are based upon these entries.</p>
</item>
-</taglist>
-
+<tag><c><seealso marker="diameter_app#peer_ref">diameter_app:peer_ref()</seealso></c></tag>
+<item>
<p>
-Requesting info for an unknown service causes <c>undefined</c> to be
-returned.
-Requesting a list of items causes a tagged list to be
-returned.</p>
+Return transport configuration associated with a single peer, as
+passed to <seealso marker="#add_transport">add_transport/2</seealso>.
+The returned list is empty if the peer is unknown.
+Otherwise it contains the <c>ref</c>, <c>type</c> and <c>options</c>
+tuples as in <c>transport</c> and <c>connections</c> info above.
+For example:</p>
+
+<code>
+[{ref,#Ref&lt;0.0.0.61>},
+ {type,accept},
+ {options,[{transport_module,diameter_tcp},
+ {transport_config,[{reuseaddr,true},
+ {ip,{127,0,0,1}},
+ {port,3868}]}]}]
+</code>
+</item>
+
+</taglist>
<marker id="services"/>
</desc>
diff --git a/lib/diameter/doc/src/diameter_transport.xml b/lib/diameter/doc/src/diameter_transport.xml
index 9ab750e560..d9b36a1e09 100644
--- a/lib/diameter/doc/src/diameter_transport.xml
+++ b/lib/diameter/doc/src/diameter_transport.xml
@@ -54,14 +54,14 @@ parent).</p>
<funcs>
<func>
-<name>Mod:start({Type, Ref}, Svc, Opts)
+<name>Mod:start({Type, Ref}, Svc, Config)
-> {ok, Pid} | {ok, Pid, LAddrs} | {error, Reason}</name>
<fsummary>Start a transport process.</fsummary>
<type>
<v>Type = connect | accept</v>
<v>Ref = <seealso marker="diameter#transport_ref">diameter:transport_ref()</seealso></v>
<v>Svc = #diameter_service{}</v>
-<v>Opts = term()</v>
+<v>Config = term()</v>
<v>Pid = pid()</v>
<v>LAddrs = [<seealso marker="kernel:inet#type-ip_address">inet:ip_address()</seealso>]</v>
<v>Reason = term()</v>
@@ -75,38 +75,46 @@ order to establish or accept a transport connection respectively.
A transport process maintains a connection with a single remote peer.</p>
<p>
-The first argument indicates whether the transport process in question
+<c>Type</c> indicates whether the transport process in question
is being started for a connecting (<c>connect</c>) or listening
(<c>accept</c>) transport.
In the latter case, transport processes are started as required to
-accept connections from multiple peers.
-Ref is in each case the same value that was returned from the
-call to <seealso
-marker="diameter#add_transport">diameter:add_transport/2</seealso>
-that has lead to starting of a transport process.</p>
+accept connections from multiple peers.</p>
<p>
-A transport process must implement the message interface documented below.
-It should retain the pid of its parent, monitor the parent and terminate if
-it dies.
-It should not link to the parent.
-It should exit if its transport connection with its peer is lost.</p>
+Ref is the value that was returned from the call to <seealso
+marker="diameter#add_transport">diameter:add_transport/2</seealso>
+that has lead to starting of a transport process.</p>
<p>
-The capabilities in the <c>#diameter_service{}</c> record are as
-passed to <seealso
+<c>Svc</c> contains the capabilities passed to <seealso
marker="diameter#start_service">diameter:start_service/2</seealso> and
<seealso
marker="diameter#add_transport">diameter:add_transport/2</seealso>,
-values passed to the latter overriding those passed to the former.
+values passed to the latter overriding those passed to the former.</p>
+
+<p>
+<c>Config</c> is as passed in <c>transport_config</c> tuple in the
+<seealso marker="diameter#transport_opt">diameter:transport_opt()</seealso>
+list passed to <seealso
+marker="diameter#add_transport">diameter:add_transport/2</seealso>.</p>
+
+<p>
The start function should use the <c>Host-IP-Address</c> list and/or
-<c>Opts</c> to select an appropriate list of local IP addresses,
+<c>Config</c> to select an appropriate list of local IP addresses,
and should return this list if different from the
<c>#diameter_service{}</c> addresses.
The returned list is used to populate <c>Host-IP-Address</c> AVPs in
outgoing capabilities exchange messages, the
<c>#diameter_service{}</c> addresses being used otherwise.</p>
+<p>
+A transport process must implement the message interface documented below.
+It should retain the pid of its parent, monitor the parent and terminate if
+it dies.
+It should not link to the parent.
+It should exit if its transport connection with its peer is lost.</p>
+
<marker id="MESSAGES"/>
</desc>
</func>
diff --git a/lib/diameter/make/release_targets.mk b/lib/diameter/make/release_targets.mk
deleted file mode 100644
index 5a3b585cbc..0000000000
--- a/lib/diameter/make/release_targets.mk
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2011. All Rights Reserved.
-#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# %CopyrightEnd%
-#
-
-ifeq ($(TOPDOC),)
-$(HTMLDIR)/index.html: $(XML_FILES)
- date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --noout --stringparam outdir $(HTMLDIR) --stringparam docgen "$(DOCGEN)" --stringparam topdocdir "$(TOPDOCDIR)" \
- --stringparam pdfdir "$(PDFDIR)" \
- --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml
-endif
-
-$(HTMLDIR)/users_guide.html: $(XML_FILES)
- date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --noout --stringparam outdir $(HTMLDIR) --stringparam docgen "$(DOCGEN)" --stringparam topdocdir "$(TOPDOCDIR)" \
- --stringparam pdfdir "$(PDFDIR)" \
- --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml
-
-
-%.fo: $(XML_FILES)
- date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" \
- --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@
-
-
-
-# ------------------------------------------------------------------------
-# The following targets just exist in the documentation directory
-# ------------------------------------------------------------------------
-ifneq ($(XML_FILES),)
-
-# ----------------------------------------------------
-# Generation of application index data
-# ----------------------------------------------------
-$(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES)
- date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --stringparam docgen "$(DOCGEN)" \
- --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_eix.xsl book.xml > $@
-
-docs:
-#docs: $(HTMLDIR)/$(APPLICATION).eix
-
-# ----------------------------------------------------
-# Local documentation target for testing
-# ----------------------------------------------------
-local_docs: TOPDOCDIR=.
-local_docs: local_copy_of_topdefs docs
-
-local_html: TOPDOCDIR=.
-local_html: local_copy_of_topdefs html
-
-local_copy_of_topdefs:
- $(INSTALL) $(DOCGEN)/priv/css/otp_doc.css $(HTMLDIR)
- $(INSTALL) $(DOCGEN)/priv/images/erlang-logo.png $(HTMLDIR)
- $(INSTALL) $(DOCGEN)/priv/images/erlang-logo.gif $(HTMLDIR)
- $(INSTALL_DIR) $(HTMLDIR)/js/flipmenu
- $(INSTALL) $(DOCGEN)/priv/js/flipmenu/flip_closed.gif \
- $(DOCGEN)/priv/js/flipmenu/flip_open.gif \
- $(DOCGEN)/priv/js/flipmenu/flip_static.gif \
- $(DOCGEN)/priv/js/flipmenu/flipmenu.js $(HTMLDIR)/js/flipmenu
-
-endif
-
-# ----------------------------------------------------
-# Standard release target
-# ----------------------------------------------------
-
-ifneq ($(PREFIX),)
-
-release release_docs release_tests release_html:
- $(MAKE) $(MFLAGS) RELEASE_PATH=$(PREFIX) $(TARGET_MAKEFILE) $@_spec
-
-endif
diff --git a/lib/diameter/make/rules.mk.in b/lib/diameter/make/rules.mk.in
deleted file mode 100644
index cd3c297d75..0000000000
--- a/lib/diameter/make/rules.mk.in
+++ /dev/null
@@ -1,193 +0,0 @@
-#-*-makefile-*- ; force emacs to enter makefile-mode
-# ----------------------------------------------------
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2009-2011. All Rights Reserved.
-#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# %CopyrightEnd%
-
-.SUFFIXES: .erl .beam .yrl .hrl .xml .xmlsrc .html \
- .3 .1 .pdf .fo .el .elc
-
-# ----------------------------------------------------
-# Common macros
-# ----------------------------------------------------
-DEFAULT_TARGETS = opt debug release release_docs clean docs
-
-
-# Slash separated list of return values from $(origin VAR)
-# that are untrusted - set default in this file instead.
-# The list is not space separated since some return values
-# contain space, and we want to use $(findstring ...) to
-# search the list.
-DUBIOUS_ORIGINS = /undefined/environment/
-
-
-# # ----------------------------------------------------
-# # TARGET definition
-# # ----------------------------------------------------
-# # TARGET = @TARGET@
-# ifneq ($(OVERRIDE_TARGET),)
-# ifneq ($(TARGET), $(OVERRIDE_TARGET))
-# $(warning overriding $$(TARGET) = \
-# "$(TARGET)" \
-# with \
-# $$(OVERRIDE_TARGET) = \
-# "$(OVERRIDE_TARGET)")
-# override TARGET := $(OVERRIDE_TARGET)
-# endif
-# endif
-#
-
-# ----------------------------------------------------
-# Command macros
-# ----------------------------------------------------
-PREFIX = @prefix@
-INSTALL = @INSTALL@
-INSTALL_DIR = @INSTALL_DIR@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_DATA = @INSTALL_DATA@
-
-
-# ----------------------------------------------------
-# Erlang language section
-# ----------------------------------------------------
-ERL_ROOT_DIR = @ERLANG_ROOT_DIR@
-ERL_LIB_DIR = @ERLANG_LIB_DIR@
-DOCGEN_DIR = @ERLANG_LIB_DIR_erl_docgen@
-TEST_SERVER_DIR = @ERLANG_LIB_VER_test_server@
-EMULATOR = beam
-ERL_COMPILE_FLAGS += +debug_info
-ERLC_WFLAGS = -W
-ERLC = $(ERL_ROOT_DIR)/bin/erlc $(ERLC_WFLAGS) $(ERLC_FLAGS)
-ERL = $(ERL_ROOT_DIR)/bin/erl -boot start_clean
-#ERLC = @ERLC@ $(ERLC_WFLAGS) $(ERLC_FLAGS)
-#ERL = @ERL@ -boot start_clean
-
-ifneq (,$(findstring $(origin EBIN),$(DUBIOUS_ORIGINS)))
-EBIN = ../../ebin
-endif
-
-# Generated (non ebin) files...
-ifneq (,$(findstring $(origin EGEN),$(DUBIOUS_ORIGINS)))
-EGEN = .
-endif
-
-ifneq (,$(findstring $(origin ESRC),$(DUBIOUS_ORIGINS)))
-ESRC = .
-endif
-
-$(EBIN)/%.beam: $(EGEN)/%.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
-
-$(EBIN)/%.beam: $(ESRC)/%.erl
- $(ERLC) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
-
-.erl.beam:
- $(ERLC) $(ERL_COMPILE_FLAGS) -o$(dir $@) $<
-
-
-#
-# When .erl files are automatically created GNU make removes them if
-# they were the result of a chain of implicit rules. To prevent this
-# we say that all .erl files are "precious".
-#
-.PRECIOUS: %.erl %.fo
-
-
-# ----------------------------------------------------
-# Documentation section
-# ----------------------------------------------------
-# export VSN
-
-# TOPDOCDIR=../../../../doc
-
-DOCDIR = ..
-
-PDFDIR=$(DOCDIR)/pdf
-
-HTMLDIR = $(DOCDIR)/html
-
-MAN1DIR = $(DOCDIR)/man1
-MAN2DIR = $(DOCDIR)/man2
-MAN3DIR = $(DOCDIR)/man3
-MAN4DIR = $(DOCDIR)/man4
-MAN6DIR = $(DOCDIR)/man6
-MAN9DIR = $(DOCDIR)/man9
-
-# HTML & GIF files that always are generated and must be delivered
-XML_COLL_FILES = $(XML_APPLICATION_FILES) $(XML_PART_FILES)
-DEFAULT_HTML_FILES = \
- $(XML_COLL_FILES:%.xml=$(HTMLDIR)/%_frame.html) \
- $(XML_COLL_FILES:%.xml=$(HTMLDIR)/%_first.html) \
- $(XML_COLL_FILES:%.xml=$(HTMLDIR)/%_term.html) \
- $(XML_COLL_FILES:%.xml=$(HTMLDIR)/%_cite.html) \
- $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%_index.html) \
- $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.kwc) \
- $(HTMLDIR)/index.html
-
-DEFAULT_GIF_FILES = $(HTMLDIR)/min_head.gif
-
-#
-# Flags & Commands
-#
-XSLTPROC = @XSLTPROC@
-FOP = @FOP@
-
-DOCGEN=$(DOCGEN_DIR)
-
-$(MAN1DIR)/%.1:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-
-$(MAN2DIR)/%.2:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-
-$(MAN3DIR)/%.3:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-# left for compatibility
-$(MAN4DIR)/%.4:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-$(MAN4DIR)/%.5:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-# left for compatibility
-$(MAN6DIR)/%.6:: %_app.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-$(MAN6DIR)/%.7:: %_app.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-$(MAN9DIR)/%.9:: %.xml
- date=`date +"%B %e %Y"`; \
- xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-
-
-.xmlsrc.xml:
- escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
-
-.fo.pdf:
- $(FOP) -fo $< -pdf $@
-
diff --git a/lib/diameter/make/subdir.mk b/lib/diameter/make/subdir.mk
deleted file mode 100644
index 24b08080ae..0000000000
--- a/lib/diameter/make/subdir.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2011. All Rights Reserved.
-#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
-#
-# %CopyrightEnd%
-#
-# Make include file for otp
-
-.PHONY: debug opt release docs release_docs tests release_tests \
- clean depend valgrind
-
-#
-# Targets that don't affect documentation directories
-#
-opt debug release docs release_docs tests release_tests clean depend valgrind:
- @set -e ; \
- app_pwd=`pwd` ; \
- if test -f vsn.mk; then \
- echo "=== Entering application" `basename $$app_pwd` ; \
- fi ; \
- case "$(MAKE)" in *clearmake*) tflag="-T";; *) tflag="";; esac; \
- for d in $(SUB_DIRS); do \
- if test -f $$d/SKIP ; then \
- echo "=== Skipping subdir $$d, reason:" ; \
- cat $$d/SKIP ; \
- echo "===" ; \
- else \
- if test ! -d $$d ; then \
- echo "=== Skipping subdir $$d, it is missing" ; \
- else \
- xflag="" ; \
- if test -f $$d/ignore_config_record.inf; then \
- xflag=$$tflag ; \
- fi ; \
- (cd $$d && $(MAKE) $$xflag $@) || exit $$? ; \
- fi ; \
- fi ; \
- done ; \
- if test -f vsn.mk; then \
- echo "=== Leaving application" `basename $$app_pwd` ; \
- fi
diff --git a/lib/diameter/make/target.mk b/lib/diameter/make/target.mk
deleted file mode 100644
index 4ae470b9e2..0000000000
--- a/lib/diameter/make/target.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-ifeq ($(OVERRIDE_TARGET),)
-
-ifeq ($(TARGET),)
-
-TARGET := $(shell $(DIAMETER_TOP)/autoconf/config.guess)
-
-else
-
-endif
-
-else
-
-ifneq ($(TARGET),)
-
-ifneq ($(TARGET), $(OVERRIDE_TARGET))
-$(warning overriding $$(TARGET) = \
- "$(TARGET)" \
- with \
- $$(OVERRIDE_TARGET) = \
- "$(OVERRIDE_TARGET)")
-else
-endif
-
-override TARGET := $(OVERRIDE_TARGET)
-
-else
-
-TARGET := $(OVERRIDE_TARGET)
-
-endif
-
-endif
-
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 99c343275b..060659bce9 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -16,13 +16,8 @@
#
# %CopyrightEnd%
-ifeq ($(ERL_TOP),)
-include $(DIAMETER_TOP)/make/target.mk
-include $(DIAMETER_TOP)/make/$(TARGET)/rules.mk
-else
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-endif
# ----------------------------------------------------
# Application version
@@ -210,11 +205,7 @@ dialyze: opt $(PLT)
# Release targets
# ----------------------------------------------------
-ifeq ($(ERL_TOP),)
-include $(DIAMETER_TOP)/make/release_targets.mk
-else
include $(ERL_TOP)/make/otp_release_targets.mk
-endif
# Can't $(INSTALL_DIR) more than one directory at a time on Solaris.
diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl
index 4f90b741ae..3e3a6be0ef 100644
--- a/lib/diameter/src/base/diameter.erl
+++ b/lib/diameter/src/base/diameter.erl
@@ -44,6 +44,8 @@
stop/0]).
-export_type([evaluable/0,
+ restriction/0,
+ sequence/0,
app_alias/0,
service_name/0,
capability/0,
@@ -280,11 +282,23 @@ call(SvcName, App, Message) ->
| fun()
| maybe_improper_list(evaluable(), list()).
+-type sequence()
+ :: {'Unsigned32'(), 0..32}.
+
+-type restriction()
+ :: false
+ | node
+ | nodes
+ | [node()]
+ | evaluable().
+
%% Options passed to start_service/2
-type service_opt()
:: capability()
- | {application, [application_opt()]}.
+ | {application, [application_opt()]}
+ | {restrict_connections, restriction()}
+ | {sequence, sequence() | evaluable()}.
-type application_opt()
:: {alias, app_alias()}
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index d1916c26e6..63d28f25a2 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -97,6 +97,9 @@
-record(monitor, {mref = make_ref() :: reference(),
service}). %% name
+%% The default sequence mask.
+-define(NOMASK, {0,32}).
+
%% Time to lay low before restarting a dead service.
-define(RESTART_SLEEP, 2000).
@@ -549,9 +552,11 @@ make_config(SvcName, Opts) ->
ok = encode_CER(COpts),
- Os = split(Opts, [{[fun erlang:is_boolean/1], false, share_peers},
- {[fun erlang:is_boolean/1], false, use_shared_peers},
- {[fun erlang:is_pid/1, false], false, monitor}]),
+ Os = split(Opts, fun opt/2, [{false, share_peers},
+ {false, use_shared_peers},
+ {false, monitor},
+ {?NOMASK, sequence},
+ {nodes, restrict_connections}]),
%% share_peers and use_shared_peers are currently undocumented.
#service{name = SvcName,
@@ -559,6 +564,61 @@ make_config(SvcName, Opts) ->
capabilities = Caps},
options = Os}.
+split(Opts, F, Defs) ->
+ [{K, F(K, get_opt(K, Opts, D))} || {D,K} <- Defs].
+
+opt(K, false = B)
+ when K /= sequence ->
+ B;
+
+opt(K, true = B)
+ when K == share_peer;
+ K == use_shared_peers ->
+ B;
+
+opt(monitor, P)
+ when is_pid(P) ->
+ P;
+
+opt(restrict_connections, T)
+ when T == node;
+ T == nodes;
+ T == [];
+ is_atom(hd(T)) ->
+ T;
+
+opt(restrict_connections = K, F) ->
+ try diameter_lib:eval(F) of %% no guarantee that it won't fail later
+ Nodes when is_list(Nodes) ->
+ F;
+ V ->
+ ?THROW({value, {K,V}})
+ catch
+ E:R ->
+ ?THROW({value, {K, E, R, ?STACK}})
+ end;
+
+opt(sequence, {_,_} = T) ->
+ sequence(T);
+
+opt(sequence = K, F) ->
+ try diameter_lib:eval(F) of
+ T -> sequence(T)
+ catch
+ E:R ->
+ ?THROW({value, {K, E, R, ?STACK}})
+ end;
+
+opt(K, _) ->
+ ?THROW({value, K}).
+
+sequence({H,N} = T)
+ when 0 =< N, N =< 32, 0 =< H, 0 == H bsr N ->
+ T;
+
+sequence(_) ->
+ ?THROW({value, sequence}).
+
make_caps(Caps, Opts) ->
case diameter_capx:make_caps(Caps, Opts) of
{ok, T} ->
@@ -663,21 +723,6 @@ get_opt(Key, List, Def) ->
_ -> ?THROW({arity, Key})
end.
-split(Opts, Defs) ->
- [{K, value(D, Opts)} || {_,_,K} = D <- Defs].
-
-value({Preds, Def, Key}, Opts) ->
- V = get_opt(Key, Opts, Def),
- lists:any(fun(P) -> pred(P,V) end, Preds)
- orelse ?THROW({value, Key}),
- V.
-
-pred(F, V)
- when is_function(F) ->
- F(V);
-pred(T, V) ->
- T == V.
-
cb(M,F) ->
try M:F() of
V -> V
diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl
index 46b2ba9465..1b2f32ddff 100644
--- a/lib/diameter/src/base/diameter_peer.erl
+++ b/lib/diameter/src/base/diameter_peer.erl
@@ -76,7 +76,7 @@ notify(SvcName, T) ->
%%% # start/3
%%% ---------------------------------------------------------------------------
-%% From old code: make is restart.
+%% From old code: make it restart.
start(_T, _Opts, #diameter_service{}) ->
{error, restart}.
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 302540e76b..3f4945f7a6 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -55,10 +55,15 @@
-define(TLS, 1).
%% Keys in process dictionary.
--define(CB_KEY, cb). %% capabilities callback
--define(DWA_KEY, dwa). %% outgoing DWA
--define(Q_KEY, q). %% transport start queue
--define(START_KEY, start). %% start of connected transport
+-define(CB_KEY, cb). %% capabilities callback
+-define(DWA_KEY, dwa). %% outgoing DWA
+-define(Q_KEY, q). %% transport start queue
+-define(START_KEY, start). %% start of connected transport
+-define(SEQUENCE_KEY, mask). %% mask for sequence numbers
+-define(RESTRICT_KEY, restrict). %% nodes for connection check
+
+%% The default sequence mask.
+-define(NOMASK, {0,32}).
%% A 2xxx series Result-Code. Not necessarily 2001.
-define(IS_SUCCESS(N), 2 == (N) div 1000).
@@ -121,7 +126,10 @@
%%% Output: Pid
%%% ---------------------------------------------------------------------------
--spec start(T, [Opt], #diameter_service{})
+-spec start(T, [Opt], #diameter_service{} %% from old code
+ | {diameter:sequence(),
+ diameter:restriction(),
+ #diameter_service{}})
-> pid()
when T :: {connect|accept, diameter:transport_ref()},
Opt :: diameter:transport_opt().
@@ -131,10 +139,8 @@
%% specified on the transport in question. Check here that the list is
%% still non-empty.
-start({_,_} = Type, Opts, #diameter_service{applications = Apps} = Svc) ->
- [] /= Apps orelse ?ERROR({no_apps, Type, Opts}),
- T = {self(), Type, Opts, Svc},
- {ok, Pid} = diameter_peer_fsm_sup:start_child(T),
+start({_,_} = Type, Opts, MS) ->
+ {ok, Pid} = diameter_peer_fsm_sup:start_child({self(), Type, Opts, MS}),
Pid.
start_link(T) ->
@@ -153,12 +159,20 @@ init(T) ->
proc_lib:init_ack({ok, self()}),
gen_server:enter_loop(?MODULE, [], i(T)).
-i({WPid, T, Opts, #diameter_service{capabilities = Caps} = Svc}) ->
+i({WPid, Type, Opts, #diameter_service{} = Svc}) -> %% from old code
+ i({WPid, Type, Opts, {?NOMASK, [node() | nodes()], Svc}});
+
+i({WPid, T, Opts, {Mask, Nodes, #diameter_service{applications = Apps,
+ capabilities = Caps}
+ = Svc}}) ->
+ [] /= Apps orelse ?ERROR({no_apps, T, Opts}),
putr(?DWA_KEY, dwa(Caps)),
{M, Ref} = T,
diameter_stats:reg(Ref),
{[Ts], Rest} = proplists:split(Opts, [capabilities_cb]),
putr(?CB_KEY, {Ref, [F || {_,F} <- Ts]}),
+ putr(?SEQUENCE_KEY, Mask),
+ putr(?RESTRICT_KEY, Nodes),
erlang:monitor(process, WPid),
{TPid, Addrs} = start_transport(T, Rest, Svc),
#state{parent = WPid,
@@ -464,9 +478,24 @@ build_CER(#state{service = #diameter_service{capabilities = Caps}}) ->
%% encode/1
encode(Rec) ->
- #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Rec),
+ Seq = diameter_session:sequence(sequence()),
+ Hdr = #diameter_header{version = ?DIAMETER_VERSION,
+ end_to_end_id = Seq,
+ hop_by_hop_id = Seq},
+ Pkt = #diameter_packet{header = Hdr,
+ msg = Rec},
+ #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Pkt),
Bin.
+sequence() ->
+ case getr(?SEQUENCE_KEY) of
+ {_,_} = Mask ->
+ Mask;
+ undefined -> %% started in old code
+ putr(?SEQUENCE_KEY, ?NOMASK),
+ ?NOMASK
+ end.
+
%% recv/2
%% RFC 3588 has result code 5015 for an invalid length but if a
@@ -965,14 +994,35 @@ dpa_timer() ->
%% Register a term and ensure it's not registered elsewhere. Note that
%% two process that simultaneously register the same term may well
%% both fail to do so this isn't foolproof.
+%%
+%% Everywhere is no longer everywhere, it's where a
+%% restrict_connections service_opt() specifies.
register_everywhere(T) ->
- diameter_reg:add_new(T)
- andalso unregistered(T).
+ reg(getr(?RESTRICT_KEY), T).
+
+reg(Nodes, T) ->
+ add(lists:member(node(), Nodes), T) andalso unregistered(Nodes, T).
+
+add(true, T) ->
+ diameter_reg:add_new(T);
+add(false, T) ->
+ diameter_reg:add(T).
+
+%% unregistered
+%%
+%% Ensure that the term in question isn't registered on other nodes.
+
+unregistered(Nodes, T) ->
+ {ResL, _} = rpc:multicall(Nodes, ?MODULE, match, [{node(), T}]),
+ lists:all(fun nomatch/1, ResL).
+
+nomatch({badrpc, {'EXIT', {undef, _}}}) -> %% no diameter on remote node
+ true;
+nomatch(L) ->
+ [] == L.
-unregistered(T) ->
- {ResL, _} = rpc:multicall(?MODULE, match, [{node(), T}]),
- lists:all(fun(L) -> [] == L end, ResL).
+%% match/1
match({Node, _})
when Node == node() ->
diff --git a/lib/diameter/src/base/diameter_reg.erl b/lib/diameter/src/base/diameter_reg.erl
index 882b9da238..619b12ecad 100644
--- a/lib/diameter/src/base/diameter_reg.erl
+++ b/lib/diameter/src/base/diameter_reg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,7 +30,8 @@
add_new/1,
del/1,
repl/2,
- match/1]).
+ match/1,
+ wait/1]).
-export([start_link/0]).
@@ -65,27 +66,22 @@
%% Table entry containing the Term -> Pid mapping.
-define(MAPPING(Term, Pid), {Term, Pid}).
--record(state, {id = now()}).
-
-%%% ----------------------------------------------------------
-%%% # add(T)
-%%%
-%%% Input: Term = term()
-%%%
-%%% Output: true
-%%%
-%%% Description: Associate the specified term with self(). The list of pids
-%%% having this or other assocations can be retrieved using
-%%% match/1.
-%%%
-%%% An association is removed when the calling process dies
-%%% or as a result of calling del/1. Adding the same term
-%%% more than once is equivalent to adding it exactly once.
-%%%
-%%% Note that since match/1 takes a pattern as argument,
-%%% specifying a term that contains match variables is
-%%% probably not a good idea
-%%% ----------------------------------------------------------
+-record(state, {id = now(),
+ q = []}). %% [{From, Pat}]
+
+%% ===========================================================================
+%% # add(T)
+%%
+%% Associate the specified term with self(). The list of pids having
+%% this or other assocations can be retrieved using match/1.
+%%
+%% An association is removed when the calling process dies or as a
+%% result of calling del/1. Adding the same term more than once is
+%% equivalent to adding it exactly once.
+%%
+%% Note that since match/1 takes a pattern as argument, specifying a
+%% term that contains match variables is probably not a good idea
+%% ===========================================================================
-spec add(any())
-> true.
@@ -93,17 +89,12 @@
add(T) ->
call({add, fun ets:insert/2, T, self()}).
-%%% ----------------------------------------------------------
-%%% # add_new(T)
-%%%
-%%% Input: T = term()
-%%%
-%%% Output: true | false
-%%%
-%%% Description: Like add/1 but only one process is allowed to have the
-%%% the association, false being returned if an association
-%%% already exists.
-%%% ----------------------------------------------------------
+%% ===========================================================================
+%% # add_new(T)
+%%
+%% Like add/1 but only one process is allowed to have the the
+%% association, false being returned if an association already exists.
+%% ===========================================================================
-spec add_new(any())
-> boolean().
@@ -111,16 +102,12 @@ add(T) ->
add_new(T) ->
call({add, fun insert_new/2, T, self()}).
-%%% ----------------------------------------------------------
-%%% # repl(T, NewT)
-%%%
-%%% Input: T, NewT = term()
-%%%
-%%% Output: true | false
-%%%
-%%% Description: Like add/1 but only replace an existing association on T,
-%%% false being returned if it doesn't exist.
-%%% ----------------------------------------------------------
+%% ===========================================================================
+%% # repl(T, NewT)
+%%
+%% Like add/1 but only replace an existing association on T, false
+%% being returned if it doesn't exist.
+%% ===========================================================================
-spec repl(any(), any())
-> boolean().
@@ -128,15 +115,11 @@ add_new(T) ->
repl(T, U) ->
call({repl, T, U, self()}).
-%%% ----------------------------------------------------------
-%%% # del(Term)
-%%%
-%%% Input: Term = term()
-%%%
-%%% Output: true
-%%%
-%%% Description: Remove any existing association of Term with self().
-%%% ----------------------------------------------------------
+%% ===========================================================================
+%% # del(Term)
+%%
+%% Remove any existing association of Term with self().
+%% ===========================================================================
-spec del(any())
-> true.
@@ -144,20 +127,16 @@ repl(T, U) ->
del(T) ->
call({del, T, self()}).
-%%% ----------------------------------------------------------
-%%% # match(Pat)
-%%%
-%%% Input: Pat = pattern in the sense of ets:match_object/2.
-%%%
-%%% Output: list of {Term, Pid}
-%%%
-%%% Description: Return the list of associations whose Term, as specified
-%%% to add/1 or add_new/1, matches the specified pattern.
-%%%
-%%% Note that there's no guarantee that the returned processes
-%%% are still alive. (Although one that isn't will soon have
-%%% its associations removed.)
-%%% ----------------------------------------------------------
+%% ===========================================================================
+%% # match(Pat)
+%%
+%% Return the list of associations whose Term, as specified to add/1
+%% or add_new/1, matches the specified pattern.
+%%
+%% Note that there's no guarantee that the returned processes are
+%% still alive. (Although one that isn't will soon have its
+%% associations removed.)
+%% ===========================================================================
-spec match(tuple())
-> [{term(), pid()}].
@@ -165,9 +144,17 @@ del(T) ->
match(Pat) ->
ets:match_object(?TABLE, ?MAPPING(Pat, '_')).
-%% ---------------------------------------------------------
-%% EXPORTED INTERNAL FUNCTIONS
-%% ---------------------------------------------------------
+%% ===========================================================================
+%% # wait(Pat)
+%%
+%% Like match/1 but return only when the result is non-empty or fails.
+%% It's up to the caller to ensure that the wait won't be forever.
+%% ===========================================================================
+
+wait(Pat) ->
+ call({wait, Pat}).
+
+%% ===========================================================================
start_link() ->
ServerName = {local, ?SERVER},
@@ -182,7 +169,7 @@ uptime() ->
%% pids/0
%%
-%% Output: list of {Pid, [Term, ...]}
+%% Return: list of {Pid, [Term, ...]}
pids() ->
to_list(fun swap/1).
@@ -202,89 +189,100 @@ id(T) -> T.
%% terms/0
%%
-%% Output: list of {Term, [Pid, ...]}
+%% Return: list of {Term, [Pid, ...]}
terms() ->
to_list(fun id/1).
swap({X,Y}) -> {Y,X}.
-%%% ----------------------------------------------------------
-%%% # init(Role)
-%%%
-%%% Output: {ok, State}
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # init/1
+%% ----------------------------------------------------------
init(_) ->
ets:new(?TABLE, [bag, named_table]),
{ok, #state{}}.
-%%% ----------------------------------------------------------
-%%% # handle_call(Request, From, State)
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # handle_call/3
+%% ----------------------------------------------------------
-handle_call({add, Fun, Key, Pid}, _, State) ->
+handle_call(Req, From, S)
+ when not is_record(S, state) ->
+ handle_call(Req, From, upgrade(S));
+
+handle_call({add, Fun, Key, Pid}, _, S) ->
B = Fun(?TABLE, {Key, Pid}),
monitor(B andalso no_monitor(Pid), Pid),
- {reply, B, State};
+ {reply, B, pending(B, S)};
-handle_call({del, Key, Pid}, _, State) ->
- {reply, ets:delete_object(?TABLE, ?MAPPING(Key, Pid)), State};
+handle_call({del, Key, Pid}, _, S) ->
+ {reply, ets:delete_object(?TABLE, ?MAPPING(Key, Pid)), S};
-handle_call({repl, T, U, Pid}, _, State) ->
+handle_call({repl, T, U, Pid}, _, S) ->
MatchSpec = [{?MAPPING('$1', Pid),
[{'=:=', '$1', {const, T}}],
['$_']}],
- {reply, repl(ets:select(?TABLE, MatchSpec), U, Pid), State};
+ {reply, repl(ets:select(?TABLE, MatchSpec), U, Pid), S};
+
+handle_call({wait, Pat}, From, #state{q = Q} = S) ->
+ case find(Pat) of
+ {ok, L} ->
+ {reply, L, S};
+ false ->
+ {noreply, S#state{q = [{From, Pat} | Q]}}
+ end;
-handle_call(state, _, State) ->
- {reply, State, State};
+handle_call(state, _, S) ->
+ {reply, S, S};
-handle_call(uptime, _, #state{id = Time} = State) ->
- {reply, diameter_lib:now_diff(Time), State};
+handle_call(uptime, _, #state{id = Time} = S) ->
+ {reply, diameter_lib:now_diff(Time), S};
-handle_call(Req, From, State) ->
+handle_call(Req, From, S) ->
?UNEXPECTED([Req, From]),
- {reply, nok, State}.
+ {reply, nok, S}.
-%%% ----------------------------------------------------------
-%%% # handle_cast(Request, State)
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # handle_cast/2
+%% ----------------------------------------------------------
-handle_cast(Msg, State)->
+handle_cast(Msg, S)->
?UNEXPECTED([Msg]),
- {noreply, State}.
+ {noreply, S}.
-%%% ----------------------------------------------------------
-%%% # handle_info(Request, State)
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # handle_info/2
+%% ----------------------------------------------------------
-handle_info({'DOWN', MRef, process, Pid, _}, State) ->
+handle_info({'DOWN', MRef, process, Pid, _}, S) ->
ets:delete_object(?TABLE, ?MONITOR(Pid, MRef)),
ets:match_delete(?TABLE, ?MAPPING('_', Pid)),
- {noreply, State};
+ {noreply, S};
-handle_info(Info, State) ->
+handle_info(Info, S) ->
?UNEXPECTED([Info]),
- {noreply, State}.
+ {noreply, S}.
-%%% ----------------------------------------------------------
-%%% # terminate(Reason, State)
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # terminate/2
+%% ----------------------------------------------------------
terminate(_Reason, _State)->
ok.
-%%% ----------------------------------------------------------
-%%% # code_change(OldVsn, State, Extra)
-%%% ----------------------------------------------------------
+%% ----------------------------------------------------------
+%% # code_change/3
+%% ----------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-%% ---------------------------------------------------------
-%% INTERNAL FUNCTIONS
-%% ---------------------------------------------------------
+%% ===========================================================================
+
+upgrade(S) ->
+ #state{} = list_to_tuple(tuple_to_list(S) ++ [[]]).
monitor(true, Pid) ->
ets:insert(?TABLE, ?MONITOR(Pid, erlang:monitor(process, Pid)));
@@ -321,6 +319,37 @@ repl([?MAPPING(_, Pid) = M], Key, Pid) ->
repl([], _, _) ->
false.
+%% pending/1
+
+pending(true, #state{q = [_|_] = Q} = S) ->
+ S#state{q = q(lists:reverse(Q), [])}; %% retain reply order
+pending(_, S) ->
+ S.
+
+q([], Q) ->
+ Q;
+q([{From, Pat} = T | Rest], Q) ->
+ case find(Pat) of
+ {ok, L} ->
+ gen_server:reply(From, L),
+ q(Rest, Q);
+ false ->
+ q(Rest, [T|Q])
+ end.
+
+%% find/1
+
+find(Pat) ->
+ try match(Pat) of
+ [] ->
+ false;
+ L ->
+ {ok, L}
+ catch
+ _:_ ->
+ {ok, []}
+ end.
+
%% call/1
call(Request) ->
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 9955df42f0..cffba4fc94 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -64,7 +64,7 @@
-include_lib("diameter/include/diameter.hrl").
-include("diameter_internal.hrl").
-%% The "old" states maintained in this module historically.
+%% The states mirrored by peer_up/peer_down callbacks.
-define(STATE_UP, up).
-define(STATE_DOWN, down).
@@ -107,6 +107,12 @@
%% process.
-define(STATE_TABLE, ?MODULE).
+%% The default sequence mask.
+-define(NOMASK, {0,32}).
+
+%% The default restrict_connections.
+-define(RESTRICT, nodes).
+
%% Workaround for dialyzer's lack of understanding of match specs.
-type match(T)
:: T | '_' | '$1' | '$2' | '$3' | '$4'.
@@ -114,15 +120,18 @@
%% State of service gen_server.
-record(state,
{id = now(),
- service_name, %% as passed to start_service/2, key in ?STATE_TABLE
+ service_name, %% as passed to start_service/2, key in ?STATE_TABLE
service :: #diameter_service{},
- peerT = ets_new(peers) :: ets:tid(), %% #peer{} at start_fsm
- connT = ets_new(conns) :: ets:tid(), %% #conn{} at connection_up
- share_peers = false :: boolean(), %% broadcast peers to remote nodes?
- use_shared_peers = false :: boolean(), %% use broadcasted peers?
+ peerT = ets_new(peers) :: ets:tid(),%% #peer{} at start_fsm
+ connT = ets_new(conns) :: ets:tid(),%% #conn{} at connection_up/reopen
shared_peers = ?Dict:new(), %% Alias -> [{TPid, Caps}, ...]
local_peers = ?Dict:new(), %% Alias -> [{TPid, Caps}, ...]
- monitor = false :: false | pid()}). %% process to die with
+ monitor = false :: false | pid(), %% process to die with
+ options
+ :: [{sequence, diameter:sequence()} %% sequence mask
+ | {restrict_connections, diameter:restriction()}
+ | {share_peers, boolean()} %% broadcast peers to remote nodes?
+ | {use_shared_peers, boolean()}]}).%% use broadcasted peers?
%% shared_peers reflects the peers broadcast from remote nodes. Note
%% that the state term itself doesn't change, which is relevant for
%% the stateless application callbacks since the state is retrieved
@@ -130,7 +139,12 @@
%% service record is used to determine whether or not we need to call
%% the process for a pick_peer callback.
-%% Record representing a watchdog process.
+%% Record representing a watchdog process as implemented by
+%% diameter_watchdog. The term "peer" here is historical, made
+%% especially confusing by the fact that a peer_ref() in the
+%% documentation is the key of a #conn{} record, not a #peer{} record.
+%% The name is also unfortunate given the meaning of peer in the
+%% Diameter sense.
-record(peer,
{pid :: match(pid()),
type :: match(connect | accept),
@@ -140,9 +154,15 @@
:: match(op_state() | {op_state(), wd_state()}),
started = now(), %% at process start
conn = false :: match(boolean() | pid())}).
- %% true at accept, pid() at connection_up (connT key)
-
-%% Record representing a peer_fsm process.
+ %% true at accepted, pid() at connection_up or reopen
+
+%% Record representing a peer process as implemented by
+%% diameter_peer_fsm. The term "conn" is historical. Despite the name
+%% here, comments refer to watchdog and peer processes, that are keys
+%% in #peer{} and #conn{} records respectively. To add to the
+%% confusion, a #request.transport is a peer process = key in a
+%% #conn{} record. The actual transport process (that the peer process
+%% knows about and that has a transport connection) isn't seen here.
-record(conn,
{pid :: pid(),
apps :: [{0..16#FFFFFFFF, diameter:app_alias()}], %% {Id, Alias}
@@ -156,10 +176,9 @@
handler :: match(pid()), %% request process
transport :: match(pid()), %% peer process
caps :: match(#diameter_caps{}),
- app :: match(diameter:app_alias()), %% #diameter_app.alias
- dictionary :: match(module()), %% #diameter_app.dictionary
- module :: match([module() | list()]),
- %% #diameter_app.module
+ app :: match(diameter:app_alias()),%% #diameter_app.alias
+ dictionary :: match(module()), %% #diameter_app.dictionary
+ module :: match([module() | list()]), %% #diameter_app.module
filter :: match(diameter:peer_filter()),
packet :: match(#diameter_packet{})}).
@@ -170,20 +189,6 @@
timeout = ?DEFAULT_TIMEOUT :: 0..16#FFFFFFFF,
detach = false :: boolean()}).
-%% Since RFC 3588 requires that a Diameter agent not modify End-to-End
-%% Identifiers, the possibility of explicitly setting an End-to-End
-%% Identifier would be needed to be able to implement an agent in
-%% which one side of the communication is not implemented on top of
-%% diameter. For example, Diameter being sent or received encapsulated
-%% in some other protocol, or even another Diameter stack in a
-%% non-Erlang environment. (Not that this is likely to be a normal
-%% case.)
-%%
-%% The implemented solution is not an option but to respect any header
-%% values set in a diameter_header record returned from a
-%% prepare_request callback. A call to diameter:call/4 can communicate
-%% values to the callback using the 'extra' option if so desired.
-
%%% ---------------------------------------------------------------------------
%%% # start(SvcName)
%%% ---------------------------------------------------------------------------
@@ -236,20 +241,20 @@ stop_transport(SvcName, [_|_] = Refs) ->
%%% ---------------------------------------------------------------------------
info(SvcName, Item) ->
- case ets:lookup(?STATE_TABLE, SvcName) of
- [] ->
- undefined;
- [S] ->
- service_info(Item, S)
+ case find_state(SvcName) of
+ #state{} = S ->
+ service_info(Item, S);
+ false ->
+ undefined
end.
%%% ---------------------------------------------------------------------------
%%% # receive_message(TPid, Pkt, MessageData)
%%% ---------------------------------------------------------------------------
-%% Handle an incoming message in the watchdog process. This used to
-%% come through the service process but this avoids that becoming a
-%% bottleneck.
+%% Handle an incoming Diameter message in the watchdog process. This
+%% used to come through the service process but this avoids that
+%% becoming a bottleneck.
receive_message(TPid, Pkt, T)
when is_pid(TPid) ->
@@ -329,21 +334,39 @@ call_rc(_, _, Sent) ->
%% In the process spawned for the outgoing request.
call(SvcName, App, Msg, Opts, Caller) ->
- c(ets:lookup(?STATE_TABLE, SvcName), App, Msg, Opts, Caller).
+ c(find_state(SvcName), App, Msg, Opts, Caller).
-c([#state{service_name = SvcName} = S], App, Msg, Opts, Caller) ->
+c(#state{service_name = Svc, options = [{_, Mask} | _]} = S,
+ App,
+ Msg,
+ Opts,
+ Caller) ->
case find_transport(App, Msg, Opts, S) of
{_,_,_} = T ->
- send_request(T, Msg, Opts, Caller, SvcName);
+ send_request(T, Mask, Msg, Opts, Caller, Svc);
false ->
{error, no_connection};
{error, _} = No ->
No
end;
-c([], _, _, _, _) ->
+c(false, _, _, _, _) ->
{error, no_service}.
+%% find_state/1
+
+find_state(SvcName) ->
+ fs(ets:lookup(?STATE_TABLE, SvcName)).
+
+fs([#state{} = S]) ->
+ S;
+
+fs([S]) -> %% inserted from old code
+ upgrade(S);
+
+fs([]) ->
+ false.
+
%% make_options/1
make_options(Options) ->
@@ -439,6 +462,10 @@ i(_, false) ->
%%% # handle_call(Req, From, State)
%%% ---------------------------------------------------------------------------
+handle_call(T, From, S)
+ when not is_record(S, state) ->
+ handle_call(T, From, upgrade(S));
+
handle_call(state, _, S) ->
{reply, S, S};
@@ -473,6 +500,14 @@ handle_call(stop, _From, S) ->
%% gets the reply. We deal with this in the call to the server,
%% stating a monitor that waits for DOWN before returning.
+%% Watchdog is asking for the sequence mask.
+handle_call(sequence, _From, #state{options = [{_, Mask} | _]} = S) ->
+ {reply, Mask, S};
+
+%% Watchdog is asking for the nodes restriction.
+handle_call(restriction, _From, #state{options = [_,_,_,{_,R} | _]} = S) ->
+ {reply, R, S};
+
handle_call(Req, From, S) ->
unexpected(handle_call, [Req, From], S),
{reply, nok, S}.
@@ -489,15 +524,16 @@ handle_cast(Req, S) ->
%%% # handle_info(Req, State)
%%% ---------------------------------------------------------------------------
-handle_info(T,S) ->
+handle_info(T, #state{} = S) ->
case transition(T,S) of
ok ->
{noreply, S};
- #state{} = NS ->
- {noreply, NS};
{stop, Reason} ->
{stop, {shutdown, Reason}, S}
- end.
+ end;
+
+handle_info(T, S) ->
+ handle_info(T, upgrade(S)).
%% transition/2
@@ -508,15 +544,26 @@ transition({accepted, Pid, TPid}, S) ->
%% Peer process has a new open connection.
transition({connection_up, Pid, T}, S) ->
- connection_up(Pid, T, S);
+ connection_up(Pid, T, S),
+ ok;
-%% Peer process has left state open.
+%% Watchdog has a new connection that will be opened after DW[RA]
+%% exchange. This message was added long after connection_up, to
+%% communicate the information as soon as it's available. Leave
+%% connection_up as is it for now, duplicated information and all.
+transition({reopen, Pid, T}, S) ->
+ reopen(Pid, T, S),
+ ok;
+
+%% Watchdog has left state OKAY.
transition({connection_down, Pid}, S) ->
- connection_down(Pid, S);
+ connection_down(Pid, S),
+ ok;
-%% Peer process has returned to state open.
+%% Watchdog has returned to state OKAY.
transition({connection_up, Pid}, S) ->
- connection_up(Pid, S);
+ connection_up(Pid, S),
+ ok;
%% Accepting transport has lost connectivity.
transition({close, Pid}, S) ->
@@ -530,7 +577,7 @@ transition({reconnect, Pid}, S) ->
%% Watchdog is sending notification of a state transition. Note that
%% the connection_up/down messages are pre-date this message and are
-%% still used. A 'watchdog' message will follow these and communicate
+%% still used. A watchdog message will follow these and communicate
%% the same state as was set in handling connection_up/down.
transition({watchdog, Pid, {TPid, From, To}}, #state{service_name = SvcName,
peerT = PeerT}) ->
@@ -540,21 +587,22 @@ transition({watchdog, Pid, {TPid, From, To}}, #state{service_name = SvcName,
insert(PeerT, P#peer{op_state = {OS, To}}),
send_event(SvcName, {watchdog, Ref, TPid, {From, To}, {T, Opts}}),
ok;
-%% Death of a peer process results in the removal of it's peer and any
-%% associated conn record when 'DOWN' is received (after this) but the
-%% states will be {?STATE_UP, ?WD_DOWN} for a short time. (No real
-%% problem since ?WD_* is only used in service_info.) We set ?WD_OKAY
-%% as a consequence of connection_up since we know a watchdog is
-%% coming. We can't set anything at connection_down since we don't
-%% know if the subsequent watchdog message will be ?WD_DOWN or
-%% ?WD_SUSPECT. We don't (yet) set ?STATE_* as a consequence of a
-%% watchdog message since this requires changing some of the matching
-%% on ?STATE_*.
-%%
-%% Death of a conn process results in connection_down followed by
-%% watchdog ?WD_DOWN. The latter doesn't result in the conn record
-%% being deleted since 'DOWN' from death of its peer doesn't (yet)
-%% deal with the record having been removed.
+%% Death of a watchdog process (#peer.pid) results in the removal of
+%% it's peer and any associated conn record when 'DOWN' is received
+%% (after this) but the states will be {?STATE_UP, ?WD_DOWN} for a
+%% short time. (No real problem since ?WD_* is only used in
+%% service_info.) We set ?WD_OKAY as a consequence of connection_up
+%% since we know a watchdog is coming. We can't set anything at
+%% connection_down since we don't know if the subsequent watchdog
+%% message will be ?WD_DOWN or ?WD_SUSPECT. We don't (yet) set
+%% ?STATE_* as a consequence of a watchdog message since this requires
+%% changing some of the matching on ?STATE_*.
+%%
+%% Death of a peer process process (#conn.pid, #peer.conn) results in
+%% connection_down followed by watchdog ?WD_DOWN. The latter doesn't
+%% result in the conn record being deleted since 'DOWN' from death of
+%% its watchdog doesn't (yet) deal with the record having been
+%% removed.
%% Monitor process has died. Just die with a reason that tells
%% diameter_config about the happening. If a cleaner shutdown is
@@ -562,23 +610,26 @@ transition({watchdog, Pid, {TPid, From, To}}, #state{service_name = SvcName,
transition({'DOWN', MRef, process, _, Reason}, #state{monitor = MRef}) ->
{stop, {monitor, Reason}};
-%% Local peer process has died.
+%% Local watchdog process has died.
transition({'DOWN', _, process, Pid, Reason}, S)
when node(Pid) == node() ->
- peer_down(Pid, Reason, S);
+ peer_down(Pid, Reason, S),
+ ok;
-%% Remote service wants to know about shared transports.
+%% Remote service wants to know about shared peers.
transition({service, Pid}, S) ->
share_peers(Pid, S),
ok;
%% Remote service is communicating a shared peer.
transition({peer, TPid, Aliases, Caps}, S) ->
- remote_peer_up(TPid, Aliases, Caps, S);
+ remote_peer_up(TPid, Aliases, Caps, S),
+ ok;
%% Remote peer process has died.
transition({'DOWN', _, process, TPid, _}, S) ->
- remote_peer_down(TPid, S);
+ remote_peer_down(TPid, S),
+ ok;
%% Restart after tc expiry.
transition({tc_timeout, T}, S) ->
@@ -592,10 +643,39 @@ transition({failover, TRef, Seqs}, S) ->
failover(TRef, Seqs, S),
ok;
+%% Ensure upgraded state is stored in state table.
+transition(upgrade, _) ->
+ ok;
+
transition(Req, S) ->
unexpected(handle_info, [Req], S),
ok.
+%% upgrade/1
+
+upgrade({state, Id, Svc, Name, Svc, PT, CT, SB, UB, SD, LD, MPid}) ->
+ S = #state{id = Id,
+ service_name = Name,
+ service = Svc,
+ peerT = PT,
+ connT = CT,
+ shared_peers = SD,
+ local_peers = LD,
+ monitor = MPid,
+ options = [{sequence, ?NOMASK},
+ {share_peers, SB},
+ {use_shared_peers, UB},
+ {restrict_connections, ?RESTRICT}]},
+ upgrade_insert(S),
+ S.
+
+upgrade_insert(#state{service = #diameter_service{pid = Pid}} = S) ->
+ if Pid == self() ->
+ ets:insert(?STATE_TABLE, S);
+ true ->
+ Pid ! upgrade
+ end.
+
%%% ---------------------------------------------------------------------------
%%% # terminate(Reason, State)
%%% ---------------------------------------------------------------------------
@@ -711,16 +791,20 @@ shutdown(#state{peerT = PeerT}) ->
wait(Fun, T) ->
diameter_lib:wait(ets:foldl(Fun, [], T)).
-st(#peer{conn = B}, Acc)
- when is_boolean(B) ->
- Acc;
-st(#peer{conn = Pid}, Acc) ->
+st(#peer{op_state = {OS,_}} = P, Acc) ->
+ st(P#peer{op_state = OS}, Acc);
+st(#peer{op_state = ?STATE_UP, conn = Pid}, Acc) ->
Pid ! shutdown,
- [Pid | Acc].
+ [Pid | Acc];
+st(#peer{}, Acc) ->
+ Acc.
-sw(#peer{pid = Pid}, Acc) ->
+sw(#peer{pid = Pid}, Acc)
+ when is_pid(Pid) ->
exit(Pid, shutdown),
- [Pid | Acc].
+ [Pid | Acc];
+sw(#peer{}, Acc) ->
+ Acc.
%%% ---------------------------------------------------------------------------
%%% # call_service/2
@@ -780,9 +864,8 @@ cfg_acc({SvcName, #diameter_service{applications = Apps} = Rec, Opts},
lists:foreach(fun init_mod/1, Apps),
S = #state{service_name = SvcName,
service = Rec#diameter_service{pid = self()},
- share_peers = get_value(share_peers, Opts),
- use_shared_peers = get_value(use_shared_peers, Opts),
- monitor = mref(get_value(monitor, Opts))},
+ monitor = mref(get_value(monitor, Opts)),
+ options = service_options(Opts)},
{S, Acc};
cfg_acc({_Ref, Type, _Opts} = T, {S, Acc})
@@ -790,15 +873,24 @@ cfg_acc({_Ref, Type, _Opts} = T, {S, Acc})
Type == listen ->
{S, [T | Acc]}.
+service_options(Opts) ->
+ [{sequence, proplists:get_value(sequence, Opts, ?NOMASK)},
+ {share_peers, get_value(share_peers, Opts)},
+ {use_shared_peers, get_value(use_shared_peers, Opts)},
+ {restrict_connections, proplists:get_value(restrict_connections,
+ Opts,
+ ?RESTRICT)}].
+%% The order of options is significant since we match against the list.
+
mref(false = No) ->
No;
mref(P) ->
erlang:monitor(process, P).
-init_shared(#state{use_shared_peers = true,
+init_shared(#state{options = [_, _, {_, true} | _],
service_name = Svc}) ->
diameter_peer:notify(Svc, {service, self()});
-init_shared(#state{use_shared_peers = false}) ->
+init_shared(#state{options = [_, _, {_, false} | _]}) ->
ok.
init_mod(#diameter_app{alias = Alias,
@@ -861,9 +953,8 @@ start(Ref, Type, Opts, #state{peerT = PeerT,
Pid.
%% Note that the service record passed into the watchdog is the merged
-%% record so that each watchdog (and peer_fsm) may get a different
-%% record. This record is what is passed back into application
-%% callbacks.
+%% record so that each watchdog may get a different record. This
+%% record is what is passed back into application callbacks.
s(Type, Ref, T) ->
case diameter_watchdog:start({Type, Ref}, T) of
@@ -914,8 +1005,8 @@ accepted(Pid, _TPid, #state{peerT = PeerT} = S) ->
#peer{ref = Ref, type = accept = T, conn = false, options = Opts}
= P
= fetch(PeerT, Pid),
- insert(PeerT, P#peer{conn = true}), %% mark replacement transport started
- start(Ref, T, Opts, S). %% start new peer
+ insert(PeerT, P#peer{conn = true}), %% mark replacement as started
+ start(Ref, T, Opts, S). %% start new watchdog
fetch(Tid, Key) ->
[T] = ets:lookup(Tid, Key),
@@ -930,11 +1021,9 @@ fetch(Tid, Key) ->
%%% ---------------------------------------------------------------------------
%%% # connection_up/3
-%%%
-%%% Output: #state{}
%%% ---------------------------------------------------------------------------
-%% Peer process has reached the open state.
+%% Watchdog process has reached state OKAY.
connection_up(Pid, {TPid, {Caps, SApps, Pkt}}, #state{peerT = PeerT,
connT = ConnT}
@@ -949,9 +1038,29 @@ connection_up(Pid, {TPid, {Caps, SApps, Pkt}}, #state{peerT = PeerT,
connection_up([Pkt], P#peer{conn = TPid}, C, S).
%%% ---------------------------------------------------------------------------
+%%% # reopen/3
+%%% ---------------------------------------------------------------------------
+
+%% Note that this connection_up/3 rewrites the same #conn{} now
+%% written here. Both do so in case reopen has not happened in old
+%% code.
+
+reopen(Pid, {TPid, {Caps, SApps, _Pkt}}, #state{peerT = PeerT,
+ connT = ConnT}) ->
+ P = fetch(PeerT, Pid),
+ C = #conn{pid = TPid,
+ apps = SApps,
+ caps = Caps,
+ peer = Pid},
+
+ insert(ConnT, C),
+ #peer{op_state = {?STATE_DOWN, _}}
+ = P,
+ insert(PeerT, P#peer{op_state = {?STATE_DOWN, ?WD_REOPEN},
+ conn = TPid}).
+
+%%% ---------------------------------------------------------------------------
%%% # connection_up/2
-%%%
-%%% Output: #state{}
%%% ---------------------------------------------------------------------------
%% Peer process has transitioned back into the open state. Note that there
@@ -981,8 +1090,7 @@ connection_up(T, P, C, #state{peerT = PeerT,
request_peer_up(TPid),
insert_local_peer(SApps, {{TPid, Caps}, {SvcName, Apps}}, LDict),
- report_status(up, P, C, S, T),
- S.
+ report_status(up, P, C, S, T).
insert_local_peer(SApps, T, LDict) ->
lists:foldl(fun(A,D) -> ilp(A, T, D) end, LDict, SApps).
@@ -1024,11 +1132,9 @@ peer_cb(MFA, Alias) ->
%%% ---------------------------------------------------------------------------
%%% # connection_down/2
-%%%
-%%% Output: #state{}
%%% ---------------------------------------------------------------------------
-%% Peer process has transitioned out of the open state.
+%% Watchdog has transitioned out of state OKAY.
connection_down(Pid, #state{peerT = PeerT,
connT = ConnT}
@@ -1044,8 +1150,8 @@ connection_down(Pid, #state{peerT = PeerT,
%% connection_down/3
-connection_down(#peer{op_state = {?STATE_DOWN, _}}, _, S) ->
- S;
+connection_down(#peer{op_state = {?STATE_DOWN, _}}, _, _) ->
+ ok;
connection_down(#peer{conn = TPid,
op_state = {?STATE_UP, _}}
@@ -1059,8 +1165,7 @@ connection_down(#peer{conn = TPid,
= S) ->
report_status(down, P, C, S, []),
remove_local_peer(SApps, {{TPid, Caps}, {SvcName, Apps}}, LDict),
- request_peer_down(TPid, S),
- S.
+ request_peer_down(TPid, S).
remove_local_peer(SApps, T, LDict) ->
lists:foldl(fun(A,D) -> rlp(A, T, D) end, LDict, SApps).
@@ -1079,11 +1184,9 @@ down_conn(Id, Alias, TC, {SvcName, Apps}) ->
%%% ---------------------------------------------------------------------------
%%% # peer_down/3
-%%%
-%%% Output: #state{}
%%% ---------------------------------------------------------------------------
-%% Peer process has died.
+%% Watchdog process has died.
peer_down(Pid, Reason, #state{peerT = PeerT} = S) ->
P = fetch(PeerT, Pid),
@@ -1103,12 +1206,12 @@ closed({shutdown, {close, _TPid, Reason}},
closed(_, _, _) ->
ok.
-%% The peer has never come up ...
-peer_down(#peer{conn = B}, S)
+%% The watchdog has never reached OKAY ...
+peer_down(#peer{conn = B}, _)
when is_boolean(B) ->
- S;
+ ok;
-%% ... or it has.
+%% ... or maybe it has.
peer_down(#peer{conn = TPid} = P, #state{connT = ConnT} = S) ->
#conn{} = C = fetch(ConnT, TPid),
ets:delete_object(ConnT, C),
@@ -1136,7 +1239,7 @@ restart(#peer{ref = Ref,
started = Time}) ->
{Time, {Ref, T, Opts}};
-%% ... or it has: a replacement transport has already been spawned.
+%% ... or it has: a replacement has already been spawned.
restart(#peer{type = accept}) ->
false.
@@ -1162,8 +1265,8 @@ default_tc(connect, Opts) ->
default_tc(accept, _) ->
0.
-%% Bound tc below if the peer was restarted recently to avoid
-%% continuous in case of faulty config or other problems.
+%% Bound tc below if the watchdog was restarted recently to avoid
+%% continuous restarted in case of faulty config or other problems.
tc(Time, Tc) ->
choose(Tc > ?RESTART_TC
orelse timer:now_diff(now(), Time) > 1000*?RESTART_TC,
@@ -1285,7 +1388,7 @@ cm([_,_|_], _, _, _) ->
multiple.
%%% ---------------------------------------------------------------------------
-%%% # send_request/5
+%%% # send_request/6
%%% ---------------------------------------------------------------------------
%% Send an outgoing request in its dedicated process.
@@ -1298,11 +1401,11 @@ cm([_,_|_], _, _, _) ->
%% The mod field of the #diameter_app{} here includes any extra
%% arguments passed to diameter:call/2.
-send_request({TPid, Caps, App} = T, Msg, Opts, Caller, SvcName) ->
+send_request({TPid, Caps, App} = T, Mask, Msg, Opts, Caller, SvcName) ->
#diameter_app{module = ModX}
= App,
- Pkt = make_request_packet(Msg),
+ Pkt = make_prepare_packet(Mask, Msg),
send_req(cb(ModX, prepare_request, [Pkt, SvcName, {TPid, Caps}]),
Pkt,
@@ -1313,7 +1416,7 @@ send_request({TPid, Caps, App} = T, Msg, Opts, Caller, SvcName) ->
[]).
send_req({send, P}, Pkt, T, Opts, Caller, SvcName, Fs) ->
- send_request(make_request_packet(P, Pkt), T, Opts, Caller, SvcName, Fs);
+ send_req(make_request_packet(P, Pkt), T, Opts, Caller, SvcName, Fs);
send_req({discard, Reason} , _, _, _, _, _, _) ->
{error, Reason};
@@ -1327,48 +1430,60 @@ send_req({eval_packet, RC, F}, Pkt, T, Opts, Caller, SvcName, Fs) ->
send_req(E, _, {_, _, App}, _, _, _, _) ->
?ERROR({invalid_return, prepare_request, App, E}).
-%% make_request_packet/1
+%% make_prepare_packet/2
%%
%% Turn an outgoing request as passed to call/4 into a diameter_packet
%% record in preparation for a prepare_request callback.
-make_request_packet(Bin)
+make_prepare_packet(_, Bin)
when is_binary(Bin) ->
#diameter_packet{header = diameter_codec:decode_header(Bin),
bin = Bin};
-make_request_packet(#diameter_packet{msg = [#diameter_header{} = Hdr | Avps]}
- = Pkt) ->
- Pkt#diameter_packet{msg = [make_request_header(Hdr) | Avps]};
+make_prepare_packet(Mask, #diameter_packet{msg = [#diameter_header{} = Hdr
+ | Avps]}
+ = Pkt) ->
+ Pkt#diameter_packet{msg = [make_prepare_header(Mask, Hdr) | Avps]};
-make_request_packet(#diameter_packet{header = Hdr} = Pkt) ->
- Pkt#diameter_packet{header = make_request_header(Hdr)};
+make_prepare_packet(Mask, #diameter_packet{header = Hdr} = Pkt) ->
+ Pkt#diameter_packet{header = make_prepare_header(Mask, Hdr)};
-make_request_packet(Msg) ->
- make_request_packet(#diameter_packet{msg = Msg}).
+make_prepare_packet(Mask, Msg) ->
+ make_prepare_packet(Mask, #diameter_packet{msg = Msg}).
-%% make_request_header/1
+%% make_prepare_header/1
-make_request_header(undefined) ->
- Seq = diameter_session:sequence(),
- make_request_header(#diameter_header{end_to_end_id = Seq,
+make_prepare_header(Mask, undefined) ->
+ Seq = diameter_session:sequence(Mask),
+ make_prepare_header(#diameter_header{end_to_end_id = Seq,
hop_by_hop_id = Seq});
-make_request_header(#diameter_header{version = undefined} = Hdr) ->
- make_request_header(Hdr#diameter_header{version = ?DIAMETER_VERSION});
+make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined,
+ hop_by_hop_id = undefined}) ->
+ Seq = diameter_session:sequence(Mask),
+ make_prepare_header(#diameter_header{end_to_end_id = Seq,
+ hop_by_hop_id = Seq});
+
+make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined} = H) ->
+ Seq = diameter_session:sequence(Mask),
+ make_prepare_header(H#diameter_header{end_to_end_id = Seq});
+
+make_prepare_header(Mask, #diameter_header{hop_by_hop_id = undefined} = H) ->
+ Seq = diameter_session:sequence(Mask),
+ make_prepare_header(H#diameter_header{hop_by_hop_id = Seq});
-make_request_header(#diameter_header{end_to_end_id = undefined} = H) ->
- Seq = diameter_session:sequence(),
- make_request_header(H#diameter_header{end_to_end_id = Seq});
+make_prepare_header(_, Hdr) ->
+ make_prepare_header(Hdr).
-make_request_header(#diameter_header{hop_by_hop_id = undefined} = H) ->
- Seq = diameter_session:sequence(),
- make_request_header(H#diameter_header{hop_by_hop_id = Seq});
+%% make_prepare_header/1
-make_request_header(#diameter_header{} = Hdr) ->
+make_prepare_header(#diameter_header{version = undefined} = Hdr) ->
+ make_prepare_header(Hdr#diameter_header{version = ?DIAMETER_VERSION});
+
+make_prepare_header(#diameter_header{} = Hdr) ->
Hdr;
-make_request_header(T) ->
+make_prepare_header(T) ->
?ERROR({invalid_header, T}).
%% make_request_packet/2
@@ -1378,7 +1493,7 @@ make_request_header(T) ->
make_request_packet(Bin, _)
when is_binary(Bin) ->
- make_request_packet(Bin);
+ make_prepare_packet(false, Bin);
make_request_packet(#diameter_packet{msg = [#diameter_header{} | _]}
= Pkt,
@@ -1390,7 +1505,7 @@ make_request_packet(#diameter_packet{msg = [#diameter_header{} | _]}
%% This is primarily so that the end to end and hop by hop identifiers
%% are retained.
make_request_packet(#diameter_packet{header = Hdr} = Pkt,
- #diameter_packet{header = Hdr0}) ->
+ #diameter_packet{header = Hdr0}) ->
Pkt#diameter_packet{header = fold_record(Hdr0, Hdr)};
make_request_packet(Msg, Pkt) ->
@@ -1403,9 +1518,9 @@ fold_record(undefined, R) ->
fold_record(Rec, R) ->
diameter_lib:fold_tuple(2, Rec, R).
-%% send_request/6
+%% send_req/6
-send_request(Pkt, {TPid, Caps, App}, Opts, Caller, SvcName, Fs) ->
+send_req(Pkt, {TPid, Caps, App}, Opts, Caller, SvcName, Fs) ->
#diameter_app{alias = Alias,
dictionary = Dict,
module = ModX,
@@ -1693,10 +1808,13 @@ request_peer_down(TPid, S) ->
%%% recv_request/3
%%% ---------------------------------------------------------------------------
-recv_request(TPid, Pkt, {ConnT, SvcName, Apps}) ->
+recv_request(TPid, Pkt, {ConnT, SvcName, Apps}) -> %% upgrade
+ recv_request(TPid, Pkt, {ConnT, SvcName, Apps, ?NOMASK});
+
+recv_request(TPid, Pkt, {ConnT, SvcName, Apps, Mask}) ->
try ets:lookup(ConnT, TPid) of
[C] ->
- recv_request(C, TPid, Pkt, SvcName, Apps);
+ recv_request(C, TPid, Pkt, SvcName, Apps, Mask);
[] -> %% transport has gone down
ok
catch
@@ -1706,7 +1824,12 @@ recv_request(TPid, Pkt, {ConnT, SvcName, Apps}) ->
%% recv_request/5
-recv_request(#conn{apps = SApps, caps = Caps}, TPid, Pkt, SvcName, Apps) ->
+recv_request(#conn{apps = SApps, caps = Caps},
+ TPid,
+ Pkt,
+ SvcName,
+ Apps,
+ Mask) ->
#diameter_caps{origin_host = {OH,_},
origin_realm = {OR,_}}
= Caps,
@@ -1718,6 +1841,7 @@ recv_request(#conn{apps = SApps, caps = Caps}, TPid, Pkt, SvcName, Apps) ->
{SvcName, OH, OR},
TPid,
Apps,
+ Mask,
Caps,
Pkt).
@@ -1743,20 +1867,24 @@ keyfind([Key | Rest], Pos, L) ->
T
end.
-%% recv_request/6
+%% recv_request/7
-recv_request({Id, Alias}, T, TPid, Apps, Caps, Pkt) ->
+recv_request({Id, Alias}, T, TPid, Apps, Mask, Caps, Pkt) ->
#diameter_app{dictionary = Dict}
= A
= find_app(Alias, Apps),
- recv_request(T, {TPid, Caps}, A, diameter_codec:decode(Id, Dict, Pkt));
+ recv_request(T,
+ {TPid, Caps},
+ A,
+ Mask,
+ diameter_codec:decode(Id, Dict, Pkt));
%% Note that the decode is different depending on whether or not Id is
%% ?APP_ID_RELAY.
%% DIAMETER_APPLICATION_UNSUPPORTED 3007
%% A request was sent for an application that is not supported.
-recv_request(false, T, TPid, _, _, Pkt) ->
+recv_request(false, T, TPid, _, _, _, Pkt) ->
As = collect_avps(Pkt),
protocol_error(3007, T, TPid, Pkt#diameter_packet{avps = As}).
@@ -1768,7 +1896,7 @@ collect_avps(Pkt) ->
As
end.
-%% recv_request/4
+%% recv_request/5
%% Wrong number of bits somewhere in the message: reply.
%%
@@ -1777,7 +1905,7 @@ collect_avps(Pkt) ->
%% set to an unrecognized value, or that is inconsistent with the
%% AVP's definition.
%%
-recv_request(T, {TPid, _}, _, #diameter_packet{errors = [Bs | _]} = Pkt)
+recv_request(T, {TPid, _}, _, _, #diameter_packet{errors = [Bs | _]} = Pkt)
when is_bitstring(Bs) ->
protocol_error(3009, T, TPid, Pkt);
@@ -1792,6 +1920,7 @@ recv_request(T, {TPid, _}, _, #diameter_packet{errors = [Bs | _]} = Pkt)
recv_request(T,
{TPid, _},
#diameter_app{id = Id},
+ _,
#diameter_packet{header = #diameter_header{is_proxiable = P},
msg = M}
= Pkt)
@@ -1809,6 +1938,7 @@ recv_request(T,
recv_request(T,
{TPid, _},
_,
+ _,
#diameter_packet{header = #diameter_header{is_error = true}}
= Pkt) ->
protocol_error(3008, T, TPid, Pkt);
@@ -1817,15 +1947,16 @@ recv_request(T,
%% in the relay application. Don't distinguish between the two since
%% each application has its own callback config. That is, the user can
%% easily distinguish between the two cases.
-recv_request(T, TC, App, Pkt) ->
- request_cb(T, TC, App, examine(Pkt)).
+recv_request(T, TC, App, Mask, Pkt) ->
+ request_cb(T, TC, App, Mask, examine(Pkt)).
%% Note that there may still be errors but these aren't protocol
%% (3xxx) errors that lead to an answer-message.
-request_cb({SvcName, _OH, _OR} = T, TC, App, Pkt) ->
+request_cb({SvcName, _OH, _OR} = T, TC, App, Mask, Pkt) ->
request_cb(cb(App, handle_request, [Pkt, SvcName, TC]),
App,
+ Mask,
T,
TC,
[],
@@ -1849,7 +1980,7 @@ examine(#diameter_packet{errors = Es} = Pkt) ->
Pkt#diameter_packet{errors = [5011 | Es]}.
%% It's odd/unfortunate that this isn't a protocol error.
-%% request_cb/6
+%% request_cb/7
%% A reply may be an answer-message, constructed either here or by
%% the handle_request callback. The header from the incoming request
@@ -1859,13 +1990,14 @@ examine(#diameter_packet{errors = Es} = Pkt) ->
request_cb({reply, Ans},
#diameter_app{dictionary = Dict},
_,
+ _,
{TPid, _},
Fs,
Pkt) ->
reply(Ans, Dict, TPid, Fs, Pkt);
%% An 3xxx result code, for which the E-bit is set in the header.
-request_cb({protocol_error, RC}, _, T, {TPid, _}, Fs, Pkt)
+request_cb({protocol_error, RC}, _, _, T, {TPid, _}, Fs, Pkt)
when 3000 =< RC, RC < 4000 ->
protocol_error(RC, T, TPid, Fs, Pkt);
@@ -1873,7 +2005,7 @@ request_cb({protocol_error, RC}, _, T, {TPid, _}, Fs, Pkt)
%% unsupported. 'noreply' is undocumented (and inappropriately named)
%% backwards compatibility for this, protocol_error the documented
%% alternative.
-request_cb(noreply, _, T, {TPid, _}, Fs, Pkt) ->
+request_cb(noreply, _, _, T, {TPid, _}, Fs, Pkt) ->
protocol_error(3001, T, TPid, Fs, Pkt);
%% Relay a request to another peer. This is equivalent to doing an
@@ -1894,6 +2026,7 @@ request_cb(noreply, _, T, {TPid, _}, Fs, Pkt) ->
request_cb({A, Opts},
#diameter_app{id = Id}
= App,
+ Mask,
T,
TC,
Fs,
@@ -1901,16 +2034,16 @@ request_cb({A, Opts},
when A == relay, Id == ?APP_ID_RELAY;
A == proxy, Id /= ?APP_ID_RELAY;
A == resend ->
- resend(Opts, App, T, TC, Fs, Pkt);
+ resend(Opts, App, Mask, T, TC, Fs, Pkt);
-request_cb(discard, _, _, _, _, _) ->
+request_cb(discard, _, _, _, _, _, _) ->
ok;
-request_cb({eval_packet, RC, F}, App, T, TC, Fs, Pkt) ->
- request_cb(RC, App, T, TC, [F|Fs], Pkt);
+request_cb({eval_packet, RC, F}, App, Mask, T, TC, Fs, Pkt) ->
+ request_cb(RC, App, Mask, T, TC, [F|Fs], Pkt);
-request_cb({eval, RC, F}, App, T, TC, Fs, Pkt) ->
- request_cb(RC, App, T, TC, Pkt, Fs),
+request_cb({eval, RC, F}, App, Mask, T, TC, Fs, Pkt) ->
+ request_cb(RC, App, Mask, T, TC, Pkt, Fs),
diameter_lib:eval(F).
%% protocol_error/5
@@ -1925,20 +2058,19 @@ protocol_error(RC, {_, OH, OR}, TPid, Fs, Pkt) ->
protocol_error(RC, T, TPid, Pkt) ->
protocol_error(RC, T, TPid, [], Pkt).
-%% resend/6
+%% resend/7
%%
%% Resend a message as a relay or proxy agent.
resend(Opts,
#diameter_app{} = App,
+ Mask,
{_SvcName, OH, _OR} = T,
{_TPid, _Caps} = TC,
Fs,
#diameter_packet{avps = Avps} = Pkt) ->
{Code, _Flags, Vid} = ?BASE:avp_header('Route-Record'),
- resend(is_loop(Code, Vid, OH, Avps), Opts, App, T, TC, Fs, Pkt).
-
-%% resend/7
+ resend(is_loop(Code, Vid, OH, Avps), Opts, App, Mask, T, TC, Fs, Pkt).
%% DIAMETER_LOOP_DETECTED 3005
%% An agent detected a loop while trying to get the message to the
@@ -1946,7 +2078,7 @@ resend(Opts,
%% if one is available, but the peer reporting the error has
%% identified a configuration problem.
-resend(true, _, _, T, {TPid, _}, Fs, Pkt) -> %% Route-Record loop
+resend(true, _, _, _, T, {TPid, _}, Fs, Pkt) -> %% Route-Record loop
protocol_error(3005, T, TPid, Fs, Pkt);
%% 6.1.8. Relaying and Proxying Requests
@@ -1958,6 +2090,7 @@ resend(true, _, _, T, {TPid, _}, Fs, Pkt) -> %% Route-Record loop
resend(false,
Opts,
App,
+ Mask,
{SvcName, _, _} = T,
{TPid, #diameter_caps{origin_host = {_, OH}}},
Fs,
@@ -1965,7 +2098,7 @@ resend(false,
avps = Avps}
= Pkt) ->
Route = #diameter_avp{data = {?BASE, 'Route-Record', OH}},
- Seq = diameter_session:sequence(),
+ Seq = diameter_session:sequence(Mask),
Hdr = Hdr0#diameter_header{hop_by_hop_id = Seq},
Msg = [Hdr, Route | Avps],
resend(call(SvcName, App, Msg, Opts), T, TPid, Fs, Pkt).
@@ -2118,7 +2251,7 @@ rc([MsgName | _], {'Result-Code' = K, RC} = T, Dict) ->
rc(Rec, T, Dict) ->
rc([Dict:rec2msg(element(1, Rec))], T, Dict).
-
+
%% failed_avp/3
failed_avp(_, [] = No, _) ->
@@ -2354,7 +2487,7 @@ a(#diameter_packet{errors = Es} = Pkt, SvcName, AE, #request{transport = TPid,
when [] == Es;
callback == AE ->
cb(Req, handle_answer, [Pkt, msg(P), SvcName, {TPid, Caps}]);
-
+
a(Pkt, SvcName, report, Req) ->
x(errors, handle_answer, [SvcName, Req, Pkt]);
@@ -2516,7 +2649,7 @@ send_event(#diameter_event{service = SvcName} = E) ->
%%% # share_peer/5
%%% ---------------------------------------------------------------------------
-share_peer(up, Caps, Aliases, TPid, #state{share_peers = true,
+share_peer(up, Caps, Aliases, TPid, #state{options = [_, {_, true} | _],
service_name = Svc}) ->
diameter_peer:notify(Svc, {peer, TPid, Aliases, Caps});
@@ -2527,11 +2660,11 @@ share_peer(_, _, _, _, _) ->
%%% # share_peers/2
%%% ---------------------------------------------------------------------------
-share_peers(Pid, #state{share_peers = true,
+share_peers(Pid, #state{options = [_, {_, true} | _],
local_peers = PDict}) ->
?Dict:fold(fun(A,Ps,ok) -> sp(Pid, A, Ps), ok end, ok, PDict);
-share_peers(_, #state{share_peers = false}) ->
+share_peers(_, _) ->
ok.
sp(Pid, Alias, Peers) ->
@@ -2541,39 +2674,31 @@ sp(Pid, Alias, Peers) ->
%%% # remote_peer_up/4
%%% ---------------------------------------------------------------------------
-remote_peer_up(Pid, Aliases, Caps, #state{use_shared_peers = true,
+remote_peer_up(Pid, Aliases, Caps, #state{options = [_, _, {_, true} | _],
service = Svc,
- shared_peers = PDict}
- = S) ->
+ shared_peers = PDict}) ->
#diameter_service{applications = Apps} = Svc,
- Update = lists:filter(fun(A) ->
- lists:keymember(A, #diameter_app.alias, Apps)
- end,
- Aliases),
- S#state{shared_peers = rpu(Pid, Caps, PDict, Update)};
+ Key = #diameter_app.alias,
+ As = lists:filter(fun(A) -> lists:keymember(A, Key, Apps) end, Aliases),
+ rpu(Pid, Caps, PDict, As);
-remote_peer_up(_, _, _, #state{use_shared_peers = false} = S) ->
- S.
+remote_peer_up(_, _, _, #state{options = [_, _, {_, false} | _]}) ->
+ ok.
rpu(_, _, PDict, []) ->
PDict;
rpu(Pid, Caps, PDict, Aliases) ->
erlang:monitor(process, Pid),
T = {Pid, Caps},
- lists:foldl(fun(A,D) -> ?Dict:append(A, T, D) end,
- PDict,
- Aliases).
+ lists:foreach(fun(A) -> ?Dict:append(A, T, PDict) end, Aliases).
%%% ---------------------------------------------------------------------------
%%% # remote_peer_down/2
%%% ---------------------------------------------------------------------------
-remote_peer_down(Pid, #state{use_shared_peers = true,
- shared_peers = PDict}
- = S) ->
- S#state{shared_peers = lists:foldl(fun(A,D) -> rpd(Pid, A, D) end,
- PDict,
- ?Dict:fetch_keys(PDict))}.
+remote_peer_down(Pid, #state{options = [_, _, {_, true} | _],
+ shared_peers = PDict}) ->
+ lists:foreach(fun(A) -> rpd(Pid, A, PDict) end, ?Dict:fetch_keys(PDict)).
rpd(Pid, Alias, PDict) ->
?Dict:update(Alias, fun(Ps) -> lists:keydelete(Pid, 1, Ps) end, PDict).
@@ -2898,7 +3023,8 @@ transports(#state{peerT = PeerT}) ->
-define(ALL_INFO, [capabilities,
applications,
transport,
- pending]).
+ pending,
+ options]).
%% The rest.
-define(OTHER_INFO, [connections,
@@ -2925,6 +3051,19 @@ tagged_info(Item, S)
undefined
end;
+tagged_info(TPid, #state{peerT = PT, connT = CT})
+ when is_pid(TPid) ->
+ try
+ [#conn{peer = Pid}] = ets:lookup(CT, TPid),
+ [#peer{ref = Ref, type = Type, options = Opts}] = ets:lookup(PT, Pid),
+ [{ref, Ref},
+ {type, Type},
+ {options, Opts}]
+ catch
+ error:_ ->
+ []
+ end;
+
tagged_info(Items, S)
when is_list(Items) ->
[T || I <- Items, T <- [tagged_info(I,S)], T /= undefined, T /= []];
@@ -2975,6 +3114,7 @@ complete_info(Item, #state{service = Svc} = S) ->
capabilities -> service_info(?CAP_INFO, S);
applications -> info_apps(S);
transport -> info_transport(S);
+ options -> info_options(S);
pending -> info_pending(S);
keys -> ?ALL_INFO ++ ?CAP_INFO ++ ?OTHER_INFO;
all -> service_info(?ALL_INFO, S);
@@ -3074,6 +3214,9 @@ peer_acc(ConnT, Acc, #peer{pid = Pid,
| info_conn(ConnT, TPid, WS /= ?WD_DOWN)],
Acc).
+info_conn(ConnT, [TPid], B) ->
+ info_conn(ConnT, TPid, B);
+
info_conn(ConnT, TPid, true)
when is_pid(TPid) ->
try ets:lookup(ConnT, TPid) of
@@ -3216,3 +3359,8 @@ peer_acc(Peer, {PeerD, RefD}) ->
[{TPid, _}, [{origin_host, {_, OH}} | _]]
= [proplists:get_value(K, Peer) || K <- [peer, caps]],
{dict:append(OH, Peer, PeerD), dict:append(OH, TPid, RefD)}.
+
+%% info_options/1
+
+info_options(S) ->
+ S#state.options.
diff --git a/lib/diameter/src/base/diameter_session.erl b/lib/diameter/src/base/diameter_session.erl
index 4c468f207c..3b236f109a 100644
--- a/lib/diameter/src/base/diameter_session.erl
+++ b/lib/diameter/src/base/diameter_session.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,6 +20,7 @@
-module(diameter_session).
-export([sequence/0,
+ sequence/1,
session_id/1,
origin_state_id/0]).
@@ -30,7 +31,7 @@
-define(INT32, 16#FFFFFFFF).
%% ---------------------------------------------------------------------------
-%% # sequence/0
+%% # sequence/0-1
%%
%% Output: 32-bit
%% ---------------------------------------------------------------------------
@@ -77,6 +78,15 @@ sequence() ->
Instr = {_Pos = 2, _Incr = 1, _Threshold = ?INT32, _SetVal = 0},
ets:update_counter(diameter_sequence, sequence, Instr).
+-spec sequence(diameter:sequence())
+ -> diameter:'Unsigned32'().
+
+sequence({_,32}) ->
+ sequence();
+
+sequence({H,N}) ->
+ (H bsl N) bor (sequence() band (1 bsl N - 1)).
+
%% ---------------------------------------------------------------------------
%% # origin_state_id/0
%% ---------------------------------------------------------------------------
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index 53f5f42396..d814f1afe2 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -43,6 +43,7 @@
-include("diameter_internal.hrl").
-define(DEFAULT_TW_INIT, 30000). %% RFC 3539 ch 3.4.1
+-define(NOMASK, {0,32}). %% default sequence mask
-record(watchdog,
{%% PCB - Peer Control Block; see RFC 3539, Appendix A
@@ -56,7 +57,9 @@
parent = self() :: pid(),
transport :: pid() | undefined,
tref :: reference(), %% reference for current watchdog timer
- message_data}). %% term passed into diameter_service with message
+ message_data, %% term passed into diameter_service with message
+ sequence :: diameter:sequence(), %% mask
+ restrict :: {diameter:restriction(), boolean()}}).
%% start/2
%%
@@ -118,12 +121,23 @@ make_state({T, Pid, {RecvData,
random:seed(now()),
putr(restart, {T, Opts, Svc}), %% save seeing it in trace
putr(dwr, dwr(Caps)), %%
+ {_,_} = Mask = call(Pid, sequence),
+ Restrict = call(Pid, restriction),
+ Nodes = restrict_nodes(Restrict),
#watchdog{parent = Pid,
- transport = monitor(diameter_peer_fsm:start(T, Opts, Svc)),
+ transport = monitor(diameter_peer_fsm:start(T,
+ Opts,
+ {Mask, Nodes, Svc})),
tw = proplists:get_value(watchdog_timer,
Opts,
?DEFAULT_TW_INIT),
- message_data = {RecvData, SvcName, Apps}}.
+ message_data = {RecvData, SvcName, Apps, Mask},
+ sequence = Mask,
+ restrict = {Restrict, lists:member(node(), Nodes)}}.
+
+%% Retrieve the sequence mask from the parent from the parent, rather
+%% than having it passed into init/1, for upgrade reasons: the call to
+%% diameter_service:receive_message/3 passes back the mask.
%% handle_call/3
@@ -137,7 +151,7 @@ handle_cast(_, State) ->
%% handle_info/2
-handle_info(T, State) ->
+handle_info(T, #watchdog{} = State) ->
case transition(T, State) of
ok ->
{noreply, State};
@@ -148,7 +162,13 @@ handle_info(T, State) ->
?LOG(stop, T),
event(State, State#watchdog{status = down}),
{stop, {shutdown, T}, State}
- end.
+ end;
+
+handle_info(T, S) ->
+ handle_info(T, upgrade(S)).
+
+upgrade(S) ->
+ #watchdog{} = list_to_tuple(tuple_to_list(S) ++ [?NOMASK, {nodes, true}]).
event(#watchdog{status = T}, #watchdog{status = T}) ->
ok;
@@ -241,9 +261,10 @@ transition({close, TPid, _Reason}, #watchdog{transport = TPid}) ->
transition({open, TPid, Hosts, T} = Open,
#watchdog{transport = TPid,
status = initial,
- parent = Pid}
+ parent = Pid,
+ restrict = {_, R}}
= S) ->
- case okay(getr(restart), Hosts) of
+ case okay(getr(restart), Hosts, R) of
okay ->
open(Pid, {TPid, T}),
set_watchdog(S#watchdog{status = okay});
@@ -258,12 +279,15 @@ transition({open, TPid, Hosts, T} = Open,
transition({open = P, TPid, _Hosts, T},
#watchdog{transport = TPid,
+ parent = Pid,
status = down}
= S) ->
%% Store the info we need to notify the parent to reopen the
%% connection after the requisite DWA's are received, at which
- %% time we eraser(open).
+ %% time we eraser(open). The reopen message is a later addition,
+ %% to communicate the new capabilities as soon as they're known.
putr(P, {TPid, T}),
+ Pid ! {reopen, self(), {TPid, T}},
set_watchdog(send_watchdog(S#watchdog{status = reopen,
num_dwa = 0}));
@@ -312,6 +336,15 @@ transition({state, Pid}, #watchdog{status = S}) ->
%% ===========================================================================
+%% Only call "upwards", to the parent service.
+call(Pid, Req) ->
+ try
+ gen_server:call(Pid, Req, infinity)
+ catch
+ exit: Reason ->
+ exit({shutdown, {Req, Reason}})
+ end.
+
monitor(Pid) ->
erlang:monitor(process, Pid),
Pid.
@@ -325,26 +358,36 @@ getr(Key) ->
eraser(Key) ->
erase({?MODULE, Key}).
-%% encode/1
+%% encode/2
-encode(Msg) ->
- #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Msg),
+encode(Msg, Mask) ->
+ Seq = diameter_session:sequence(Mask),
+ Hdr = #diameter_header{version = ?DIAMETER_VERSION,
+ end_to_end_id = Seq,
+ hop_by_hop_id = Seq},
+ Pkt = #diameter_packet{header = Hdr,
+ msg = Msg},
+ #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Pkt),
Bin.
-%% okay/2
+%% okay/3
-okay({{accept, Ref}, _, _}, Hosts) ->
+okay({{accept, Ref}, _, _}, Hosts, Restrict) ->
T = {?MODULE, connection, Ref, Hosts},
diameter_reg:add(T),
- okay(diameter_reg:match(T));
+ if Restrict ->
+ okay(diameter_reg:match(T));
+ true ->
+ okay
+ end;
%% Register before matching so that at least one of two registering
-%% processes will match the other. (Which can't happen as long as
-%% diameter_peer_fsm guarantees at most one open connection to the same
-%% peer.)
+%% processes will match the other.
-okay({{connect, _}, _, _}, _) ->
+okay({{connect, _}, _, _}, _, _) ->
okay.
+%% okay/2
+
%% The peer hasn't been connected recently ...
okay([{_,P}]) ->
P = self(), %% assert
@@ -400,9 +443,10 @@ close(#watchdog{parent = Pid}) ->
%% send_watchdog/1
send_watchdog(#watchdog{pending = false,
- transport = TPid}
+ transport = TPid,
+ sequence = Mask}
= S) ->
- TPid ! {send, encode(getr(dwr))},
+ TPid ! {send, encode(getr(dwr), Mask)},
?LOG(send, 'DWR'),
S#watchdog{pending = true}.
@@ -600,19 +644,40 @@ restart(#watchdog{transport = undefined} = S) ->
restart(S) ->
S.
+%% restart/2
+%%
%% Only restart the transport in the connecting case. For an accepting
-%% transport, we've registered the peer connection when leaving state
-%% initial and this is used by a new accepting process to realize that
-%% it's actually in state down rather then initial when receiving
-%% notification of an open connection.
-
-restart({{connect, _} = T, Opts, Svc}, #watchdog{parent = Pid} = S) ->
+%% transport, there's no guarantee that an accepted connection in a
+%% restarted transport if from the peer we've lost contact with so
+%% have to be prepared for another watchdog to handle it. This is what
+%% the diameter_reg registration in this module is for: the peer
+%% connection is registered when leaving state initial and this is
+%% used by a new accepting watchdog to realize that it's actually in
+%% state down rather then initial when receiving notification of an
+%% open connection.
+
+restart({{connect, _} = T, Opts, Svc}, #watchdog{parent = Pid,
+ sequence = Mask,
+ restrict = {R,_}}
+ = S) ->
Pid ! {reconnect, self()},
- S#watchdog{transport = monitor(diameter_peer_fsm:start(T, Opts, Svc))};
+ Nodes = restrict_nodes(R),
+ S#watchdog{transport = monitor(diameter_peer_fsm:start(T,
+ Opts,
+ {Mask, Nodes, Svc})),
+ restrict = {R, lists:member(node(), Nodes)}};
+
+%% No restriction on the number of connections to the same peer: just
+%% die. Note that a state machine never enters state REOPEN in this
+%% case.
+restart({{accept, _}, _, _}, #watchdog{restrict = {_, false}}) ->
+ stop;
+
+%% Otherwise hang around until told to die.
restart({{accept, _}, _, _}, S) ->
S.
-%% Don't currently use Opts/Svc in the accept case but having them in
-%% the process dictionary is helpful if the process dies unexpectedly.
+
+%% Don't currently use Opts/Svc in the accept case.
%% dwr/1
@@ -622,3 +687,22 @@ dwr(#diameter_caps{origin_host = OH,
['DWR', {'Origin-Host', OH},
{'Origin-Realm', OR},
{'Origin-State-Id', OSI}].
+
+%% restrict_nodes/1
+
+restrict_nodes(false) ->
+ [];
+
+restrict_nodes(nodes) ->
+ [node() | nodes()];
+
+restrict_nodes(node) ->
+ [node()];
+
+restrict_nodes(Nodes)
+ when [] == Nodes;
+ is_atom(hd(Nodes)) ->
+ Nodes;
+
+restrict_nodes(F) ->
+ diameter_lib:eval(F).
diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile
index e3a57553c1..866d135bd9 100644
--- a/lib/diameter/test/Makefile
+++ b/lib/diameter/test/Makefile
@@ -16,13 +16,8 @@
#
# %CopyrightEnd%
-ifeq ($(ERL_TOP),)
-include $(DIAMETER_TOP)/make/target.mk
-include $(DIAMETER_TOP)/make/$(TARGET)/rules.mk
-else
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
-endif
# ----------------------------------------------------
# Application version
@@ -148,11 +143,7 @@ log:
/%: % force
sed -f release.sed $< > "$(RELSYSDIR)$@"
-ifeq ($(ERL_TOP),)
-include $(DIAMETER_TOP)/make/release_targets.mk
-else
include $(ERL_TOP)/make/otp_release_targets.mk
-endif
release_spec release_docs_spec:
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index dd07679764..5744ff0307 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -81,11 +81,11 @@
%% diameter callbacks
-export([peer_up/3,
peer_down/3,
- pick_peer/5, pick_peer/6,
- prepare_request/4, prepare_request/5,
- prepare_retransmit/4,
- handle_answer/5, handle_answer/6,
- handle_error/5,
+ pick_peer/6, pick_peer/7,
+ prepare_request/5, prepare_request/6,
+ prepare_retransmit/5,
+ handle_answer/6, handle_answer/7,
+ handle_error/6,
handle_request/3]).
-include("diameter.hrl").
@@ -108,10 +108,16 @@
-define(BASE, ?DIAMETER_DICT_COMMON).
-define(ACCT, ?DIAMETER_DICT_ACCOUNTING).
+%% Sequence mask for End-to-End and Hop-by-Hop identifiers.
+-define(CLIENT_MASK, {1,26}). %% 1 in top 6 bits
+
%% Run tests cases in different encoding variants. Send outgoing
%% messages as lists or records.
-define(ENCODINGS, [list, record]).
+%% Identifers for client connections.
+-define(CONNECTIONS, [c1,c2,c3]).
+
%% Not really what we should be setting unless the message is sent in
%% the common application but diameter doesn't care.
-define(APP_ID, ?DIAMETER_APP_ID_COMMON).
@@ -124,7 +130,8 @@
{'Vendor-Id', 12345},
{'Product-Name', "OTP/diameter"},
{'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]},
- {'Acct-Application-Id', [?DIAMETER_APP_ID_ACCOUNTING]}
+ {'Acct-Application-Id', [?DIAMETER_APP_ID_ACCOUNTING]},
+ {restrict_connections, false}
| [{application, [{dictionary, D},
{module, ?MODULE},
{answer_errors, callback}]}
@@ -175,12 +182,14 @@ suite() ->
all() ->
[start, start_services, add_transports, result_codes]
- ++ [{group, name([E]), P} || E <- ?ENCODINGS, P <- [[], [parallel]]]
+ ++ [{group, name([E,C]), P} || E <- ?ENCODINGS,
+ C <- ?CONNECTIONS,
+ P <- [[], [parallel]]]
++ [remove_transports, stop_services, stop].
groups() ->
Ts = tc(),
- [{name([E]), [], Ts} || E <- ?ENCODINGS].
+ [{name([E,C]), [], Ts} || E <- ?ENCODINGS, C <- ?CONNECTIONS].
init_per_group(Name, Config) ->
[{group, Name} | Config].
@@ -244,16 +253,17 @@ start(_Config) ->
start_services(_Config) ->
ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER)),
- ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT)).
+ ok = diameter:start_service(?CLIENT, [{sequence, ?CLIENT_MASK}
+ | ?SERVICE(?CLIENT)]).
add_transports(Config) ->
LRef = ?util:listen(?SERVER, tcp, [{capabilities_cb, fun capx/2}]),
- CRef = ?util:connect(?CLIENT, tcp, LRef),
- ?util:write_priv(Config, "transport", {LRef, CRef}).
+ Cs = [?util:connect(?CLIENT, tcp, LRef, [{id, C}]) || C <- ?CONNECTIONS],
+ ?util:write_priv(Config, "transport", [LRef | Cs]).
remove_transports(Config) ->
- {LRef, CRef} = ?util:read_priv(Config, "transport"),
- ?util:disconnect(?CLIENT, CRef, ?SERVER, LRef).
+ [LRef | Cs] = ?util:read_priv(Config, "transport"),
+ [?util:disconnect(?CLIENT, C, ?SERVER, LRef) || C <- Cs].
stop_services(_Config) ->
ok = diameter:stop_service(?CLIENT),
@@ -539,11 +549,11 @@ call(Config, Req) ->
call(Config, Req, Opts) ->
Name = proplists:get_value(testcase, Config),
- [Enc] = name(proplists:get_value(group, Config)),
+ [Encoding, Client] = name(proplists:get_value(group, Config)),
diameter:call(?CLIENT,
dict(Req),
- req(Req, Enc),
- [{extra, [Name]} | Opts]).
+ req(Req, Encoding),
+ [{extra, [Name, Client]} | Opts]).
req(['ACR' = H | T], record) ->
?ACCT:'#new-'(?ACCT:msg2rec(H), T);
@@ -580,7 +590,7 @@ set(_, _, _, Rec) ->
Rec.
%% Contruct and deconstruct names to work around group names being
-%% restricted to atoms. (Not really used yet.)
+%% restricted to atoms.
name(Names)
when is_list(Names) ->
@@ -603,27 +613,36 @@ peer_up(_SvcName, _Peer, State) ->
peer_down(_SvcName, _Peer, State) ->
State.
-%% pick_peer/5/6
+%% pick_peer/6-7
-pick_peer([Peer], _, ?CLIENT, _State, Name)
+pick_peer(Peers, _, ?CLIENT, _State, Name, Id)
when Name /= send_detach ->
- {ok, Peer}.
+ find(Id, Peers).
-pick_peer([_Peer], _, ?CLIENT, _State, send_nopeer, ?EXTRA) ->
+pick_peer(_Peers, _, ?CLIENT, _State, send_nopeer, _, ?EXTRA) ->
false;
-pick_peer([Peer], _, ?CLIENT, _State, send_detach, {_,_}) ->
- {ok, Peer}.
+pick_peer(Peers, _, ?CLIENT, _State, send_detach, Id, {_,_}) ->
+ find(Id, Peers).
+
+find(Id, Peers) ->
+ [P] = [P || P <- Peers, id(Id, P)],
+ {ok, P}.
+
+id(Id, {Pid, _Caps}) ->
+ [{ref, _}, {type, _}, {options, Opts} | _]
+ = diameter:service_info(?CLIENT, Pid),
+ lists:member({id, Id}, Opts).
-%% prepare_request/4/5
+%% prepare_request/5-6
-prepare_request(_Pkt, ?CLIENT, {_Ref, _Caps}, send_discard) ->
+prepare_request(_Pkt, ?CLIENT, {_Ref, _Caps}, send_discard, _) ->
{discard, unprepared};
-prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, Name) ->
+prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, Name, _) ->
{send, prepare(Pkt, Caps, Name)}.
-prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, send_detach, _) ->
+prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, send_detach, _, _) ->
{eval_packet, {send, prepare(Pkt, Caps)}, [fun log/2, detach]}.
log(#diameter_packet{} = P, T) ->
@@ -710,25 +729,25 @@ prepare(#diameter_packet{msg = Req}, Caps)
{'Destination-Realm', DR},
{'Auth-Application-Id', ?APP_ID}]).
-%% prepare_retransmit/4
+%% prepare_retransmit/5
-prepare_retransmit(_Pkt, false, _Peer, _Name) ->
+prepare_retransmit(_Pkt, false, _Peer, _Name, _Id) ->
discard.
-%% handle_answer/5/6
+%% handle_answer/6-7
-handle_answer(Pkt, Req, ?CLIENT, Peer, Name) ->
+handle_answer(Pkt, Req, ?CLIENT, Peer, Name, _Id) ->
answer(Pkt, Req, Peer, Name).
-handle_answer(Pkt, _Req, ?CLIENT, _Peer, send_detach, {Pid, Ref}) ->
+handle_answer(Pkt, _Req, ?CLIENT, _Peer, send_detach, _Id, {Pid, Ref}) ->
Pid ! {Ref, Pkt}.
answer(#diameter_packet{msg = Rec, errors = []}, _Req, _Peer, _) ->
Rec.
-%% handle_error/5
+%% handle_error/6
-handle_error(Reason, _Req, ?CLIENT, _Peer, _Name) ->
+handle_error(Reason, _Req, ?CLIENT, _Peer, _Name, _Id) ->
{error, Reason}.
%% handle_request/3
@@ -736,7 +755,13 @@ handle_error(Reason, _Req, ?CLIENT, _Peer, _Name) ->
%% Note that diameter will set Result-Code and Failed-AVPs if
%% #diameter_packet.errors is non-null.
-handle_request(#diameter_packet{msg = M}, ?SERVER, {_Ref, Caps}) ->
+handle_request(#diameter_packet{header = H, msg = M}, ?SERVER, {_Ref, Caps}) ->
+ #diameter_header{end_to_end_id = EI,
+ hop_by_hop_id = HI}
+ = H,
+ {V,B} = ?CLIENT_MASK,
+ V = EI bsr B, %% assert
+ V = HI bsr B, %%
request(M, Caps).
request(#diameter_base_accounting_ACR{'Accounting-Record-Number' = 0},
diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl
index ff40326947..7ce09e93ca 100644
--- a/lib/diameter/test/diameter_watchdog_SUITE.erl
+++ b/lib/diameter/test/diameter_watchdog_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,11 +30,21 @@
end_per_suite/1]).
%% testcases
--export([reopen/1, reopen/4]).
+-export([reopen/1, reopen/4, reopen/7]).
--export([start/3, %% diameter_transport callback
- id/1, %% jitter callback
- run/1]).
+-export([id/1, %% jitter callback
+ run1/1]).
+
+%% diameter_app callbacks
+-export([peer_up/3,
+ peer_down/3]).
+
+%% gen_tcp-ish interface
+-export([listen/2,
+ accept/1,
+ connect/3,
+ send/2,
+ setopts/2]).
-include("diameter.hrl").
-include("diameter_ct.hrl").
@@ -43,33 +53,21 @@
-define(util, diameter_util).
--define(BASE, diameter_gen_base_rfc3588).
--define(APPL_ID, diameter_gen_base_rfc3588:id()).
--define(SUCCESS, 2001). %% DIAMETER_SUCCESS
-
-%% Addresses for the local and remote diameter nodes. The values don't
-%% matter since we're faking transport.
--define(LOCALHOST, {127,0,0,1}).
--define(REMOTEHOST, {10,0,0,1}).
-
--define(CAPS, #diameter_caps{origin_host = "node.innan.com",
- origin_realm = "innan.com",
- host_ip_address = [?LOCALHOST],
- vendor_id = 1022,
- product_name = "remote",
- auth_application_id = [?APPL_ID]}).
-
--define(APPL, #diameter_app{alias = ?MODULE,
- dictionary = ?BASE,
- module = [?MODULE],
- init_state = now(),
- id = ?APPL_ID,
- mutable = false}).
-
-%% Service record maintained by our faked service process.
--define(SERVICE, #diameter_service{pid = self(),
- capabilities = ?CAPS,
- applications = [?APPL]}).
+-define(BASE, ?DIAMETER_DICT_COMMON).
+-define(REALM, "erlang.org").
+-define(ADDR, {127,0,0,1}).
+
+%% Config for diameter:start_service/2.
+-define(SERVICE(Name),
+ [{'Origin-Host', Name ++ "." ++ ?REALM},
+ {'Origin-Realm', ?REALM},
+ {'Host-IP-Address', [?ADDR]},
+ {'Vendor-Id', 42},
+ {'Product-Name', "OTP/diameter"},
+ {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]},
+ {application, [{alias, Name},
+ {dictionary, ?BASE},
+ {module, ?MODULE}]}]).
%% Watchdog timer as a callback.
-define(WD(T), {?MODULE, id, [T]}).
@@ -82,28 +80,28 @@
F_ <- [fun(T__) -> T__ end,
fun(T__) -> ?WD(T__) end]]]).
-%% Transport types.
--define(TRANSPORTS, [connect, accept]).
+%% Watchdog timer of the misbehaving peer.
+-define(PEER_WD, 10000).
-%% Message over the transport interface.
--define(TMSG(T), {diameter, T}).
-
-%% Receive a message within a specified time.
--define(RECV(T, Timeout),
- receive T -> now()
- after Timeout -> ?ERROR({timeout, Timeout})
+%% Receive a watchdog event within a specified time.
+-define(EVENT(T, Tmo),
+ receive #diameter_event{info = T} -> now()
+ after Tmo -> ?ERROR({timeout, Tmo})
end).
-%% Receive a message in a given number of watchdogs, plus or minus
+%% Receive an event in a given number of watchdogs, plus or minus
%% half. Note that the call to now_diff assumes left to right
%% evaluation order.
--define(RECV(T, N, WdL, WdH),
+-define(EVENT(T, N, WdL, WdH),
[?ERROR({received, _Elapsed_, _LowerBound_, N, WdL})
|| _UpperBound_ <- [(N)*(WdH) + (WdH) div 2],
- _Elapsed_ <- [now_diff(now(), ?RECV(T, _UpperBound_))],
+ _Elapsed_ <- [now_diff(now(), ?EVENT(T, _UpperBound_))],
_LowerBound_ <- [(N)*(WdL) - (WdL) div 2],
_Elapsed_ =< _LowerBound_*1000]).
+-define(EVENT(T, N, Wd),
+ ?EVENT(T, N, Wd, Wd)).
+
%% A timeout that ensures one watchdog. The ensure only one watchdog
%% requires (Wd + 2000) + 1000 < 2*(Wd - 2000) ==> 7000 < Wd for the
%% case with random jitter.
@@ -112,7 +110,7 @@
%% ===========================================================================
suite() ->
- [{timetrap, {minutes, 6}}].%% enough for 11 watchdogs @ 30 sec plus jitter
+ [{timetrap, {minutes, 10}}].%% enough for 17 watchdogs @ 30 sec plus jitter
all() ->
[reopen].
@@ -134,52 +132,97 @@ end_per_suite(_Config) ->
%% implement a transport process that plays the role of the peer
%% Diameter node.
+%reopen(_) ->
+% reopen(connect, ?WD(10000), 1, 'DWR');
+
reopen(_) ->
- [] = ?util:run([{?MODULE, [run, [reopen, Wd, T, N, M]]}
- || Wd <- ?WD_TIMERS,
- T <- ?TRANSPORTS,
- N <- [0,1,2],
- M <- ['DWR', 'DWA', other]]).
+ [] = run([[reopen, T, Wd, N, M]
+ || Wd <- ?WD_TIMERS, %% watchdog_timer value
+ T <- [listen, connect], %% watchdog to test
+ N <- [0,1,2], %% DWR's to answer before ignoring
+ M <- ['DWR', 'DWA', 'RAA']]). %% how to induce failback
-reopen(Wd, Type, N, What) ->
- Ref = make_ref(),
+reopen(Type, Wd, N, M) ->
+ Server = start_service(),
+ Client = start_service(),
- %% The maker of transport processes.
- TPid = start({N, Wd, What, Ref}),
+ %% The peer to the transport whose watchdog is tested is given a
+ %% long watchdog timeout so that it doesn't send DWR of its own.
+ {Node, Peer} = {{[], Wd}, {[{module, ?MODULE}], ?WD(?PEER_WD)}},
- %% Act like diameter_service and start the watchdog process, which
- %% in turn starts a peer_fsm process, which in turn starts a
- %% transport process by way of start/3. Messages received by the
- %% testcase are those sent by diameter_watchdog to the service
- %% process (= process starting the watchdog).
- WPid1 = watchdog(Type, Ref, TPid, Wd),
+ {{LH,LW},{CH,CW}} = case Type of
+ listen -> {Node, Peer};
+ connect -> {Peer, Node}
+ end,
- %% Low/high watchdog timeouts.
- WdL = jitter(Wd, -2000),
- WdH = jitter(Wd, 2000),
+ LO = [{transport_module, diameter_tcp},
+ {transport_config, LH ++ [{ip, ?ADDR}, {port, 0}]},
+ {watchdog_timer, LW}],
+
+ {ok, LRef} = diameter:add_transport(Server, {listen, LO}),
+
+ [LP] = ?util:lport(tcp, LRef, 20),
+
+ CO = [{transport_module, diameter_tcp},
+ {transport_config, CH ++ [{ip, ?ADDR}, {port, 0},
+ {raddr, ?ADDR}, {rport, LP}]},
+ {watchdog_timer, CW}],
+
+ %% Use a temporary process to ensure the connecting transport is
+ %% added only once events from the listening transport are
+ %% subscribed to.
+ Pid = spawn(fun() -> receive _ -> ok end end),
+
+ [] = run([[reopen, Type, T, LRef, Pid, Wd, N, M]
+ || T <- [{listen, Server}, {connect, Client, CO}]]).
+
+%% start_service/1
+
+start_service() ->
+ Name = hostname(),
+ ok = diameter:start_service(Name, [{monitor, self()} | ?SERVICE(Name)]),
+ Name.
+
+%% reopen/7
+reopen(Type, {listen = T, SvcName}, Ref, Pid, Wd, N, M) ->
+ diameter:subscribe(SvcName),
+ Pid ! ok,
+ recv(Type, T, SvcName, Ref, Wd, N, M);
+
+reopen(Type, {connect = T, SvcName, Opts}, _, Pid, Wd, N, M) ->
+ diameter:subscribe(SvcName),
+ MRef = erlang:monitor(process, Pid),
+ receive {'DOWN', MRef, process, _, _} -> ok end,
+ {ok, Ref} = diameter:add_transport(SvcName, {T, Opts}),
+ recv(Type, T, SvcName, Ref, Wd, N, M).
+
+%% recv/7
+
+%% The watchdog to be tested.
+recv(Type, Type, _SvcName, Ref, Wd, N, M) ->
%% Connection should come up immediately as a consequence of
%% starting the watchdog process. In the accepting case this
%% results in a new watchdog on a transport waiting for a new
%% connection.
- ?RECV({connection_up, WPid1, _}, 1000),
- WPid2 = case Type of
- connect ->
- WPid1;
- accept ->
- watchdog(Type, Ref, TPid, Wd)
- end,
+ ?EVENT({watchdog, Ref, _, {initial, okay}, _}, 2000),
+ ?EVENT({up, Ref, _, _, #diameter_packet{}}, 0),
+
+ %% Low/high watchdog timeouts.
+ WdL = jitter(Wd, -2000),
+ WdH = jitter(Wd, 2000),
%% OKAY Timer expires & Failover()
%% Pending SetWatchdog() SUSPECT
%%
- %% Since our transport is replying to N DWR's before becoming
- %% silent, we should go down after N+2 watchdog_timer expirations:
- %% that is, after the first unanswered DWR. Knowing the min/max
- %% watchdog timeout values gives the time interval in which the
- %% down message is expected.
- ?RECV({connection_down, WPid1}, N+2, WdL, WdH),
+ %% The peer replies to N DWR's before becoming silent, we should
+ %% go down after N+2 watchdog_timer expirations: that is, after
+ %% the first unanswered DWR. Knowing the min/max watchdog timeout
+ %% values gives the time interval in which the event is expected.
+
+ ?EVENT({watchdog, Ref, _, {okay, suspect}, _}, N+2, WdL, WdH),
+ ?EVENT({down, Ref, _, _}, 0),
%% SUSPECT Receive DWA Pending = FALSE
%% Failback()
@@ -188,9 +231,11 @@ reopen(Wd, Type, N, What) ->
%% SUSPECT Receive non-DWA Failback()
%% SetWatchdog() OKAY
%%
- %% The transport receives a message before the expiry of another
- %% watchdog to induce failback.
- ?RECV({connection_up, WPid1}, WdH),
+ %% The peer sends a message before the expiry of another watchdog
+ %% to induce failback.
+
+ ?EVENT({watchdog, Ref, _, {suspect, okay}, _}, WdH + 2000),
+ ?EVENT({up, Ref, _, _}, 0),
%% OKAY Timer expires & SendWatchdog()
%% !Pending SetWatchdog()
@@ -199,30 +244,35 @@ reopen(Wd, Type, N, What) ->
%% OKAY Timer expires & Failover()
%% Pending SetWatchdog() SUSPECT
%%
- %% The transport is still not responding to watchdogs so the
- %% connection should go back down after either one or two watchdog
- %% expiries, depending on whether or not DWA restored the connection.
- F = choose(What == 'DWA', 2, 1),
- ?RECV({connection_down, WPid1}, F, WdL, WdH),
+ %% The peer is now ignoring all watchdogs so the connection goes
+ %% back down after either one or two watchdog expiries, depending
+ %% on whether or not DWA restored the connection.
+
+ F = choose(M == 'DWA', 2, 1),
+ ?EVENT({watchdog, Ref, _, {okay, suspect}, _}, F, WdL, WdH),
+ ?EVENT({down, Ref, _, _}, 0),
%% SUSPECT Timer expires CloseConnection()
%% SetWatchdog() DOWN
%%
+ %% Non-response brings the connection down after another timeout.
+
+ ?EVENT({watchdog, Ref, _, {suspect, down}, _}, 1, WdL, WdH),
+
%% DOWN Timer expires AttemptOpen()
%% SetWatchdog() DOWN
%%
- %% Our transport tells us when the fake connection is
- %% reestablished, which should happen after another couple of
- %% watchdog expiries, the first bringing the watchdog to state
- %% DOWN, the second triggering an attempt to reopen the
- %% connection.
- ?RECV({reopen, Ref}, 2, WdL, WdH),
-
%% DOWN Connection up NumDWA = 0
%% SendWatchdog()
%% SetWatchdog()
%% Pending = TRUE REOPEN
%%
+ %% The connection is reestablished after another timeout.
+
+ recv_reopen(Type, Ref, WdL, WdH),
+
+ %% REOPEN Receive non-DWA Throwaway() REOPEN
+ %%
%% REOPEN Receive DWA & Pending = FALSE
%% NumDWA < 2 NumDWA++ REOPEN
%%
@@ -230,312 +280,259 @@ reopen(Wd, Type, N, What) ->
%% NumDWA == 2 NumDWA++
%% Failback() OKAY
%%
- %% Now the watchdog should require three received DWA's before
- %% taking the connection back up. The first DWR is sent directly
- %% after capabilities exchange so it should take no more than two
- %% watchdog expiries.
- ?RECV({connection_up, WPid2, _}, 2, WdL, WdH).
+ %% REOPEN Timer expires & SendWatchdog()
+ %% !Pending SetWatchdog()
+ %% Pending = TRUE REOPEN
+ %%
+ %% An exchange of 3 watchdogs (the first directly after
+ %% capabilities exchange) brings the connection back up.
-%% ===========================================================================
+ ?EVENT({watchdog, Ref, _, {reopen, okay}, _}, 2, WdL, WdH),
+ ?EVENT({up, Ref, _, _, #diameter_packet{}}, 0),
-%% Start the fake transport process. From diameter's point of view
-%% it's started when diameter calls start/3. We start it before this
-%% happens since we use the same fake transport each time diameter
-%% calls start/3. The process lives and dies with the test case.
-start(Config) ->
- Pid = self(),
- spawn(fun() -> loop(init(Pid, Config)) end).
-
-%% Transport start from diameter. This may be called multiple times
-%% depending on the testcase.
-start({Type, _Ref}, #diameter_service{}, Pid) ->
- Ref = make_ref(),
- MRef = erlang:monitor(process, Pid),
- Pid ! {start, self(), Type, Ref},
- {Ref, TPid} = receive
- {Ref, _} = T ->
- T;
- {'DOWN', MRef, process, _, _} = T ->
- T
- end,
- erlang:demonitor(MRef, [flush]),
- {ok, TPid}.
+ %% Non-response brings it down again.
-%% id/1
+ ?EVENT({watchdog, Ref, _, {okay, suspect}, _}, 2, WdL, WdH),
+ ?EVENT({down, Ref, _, _}, 0),
+ ?EVENT({watchdog, Ref, _, {suspect, down}, _}, 1, WdL, WdH),
-id(T) ->
- T.
+ %% Reestablish after another watchdog.
-%% ===========================================================================
+ recv_reopen(Type, Ref, WdL, WdH),
-choose(true, X, _) -> X;
-choose(false, _, X) -> X.
+ %% REOPEN Timer expires & NumDWA = -1
+ %% Pending & SetWatchdog()
+ %% NumDWA >= 0 REOPEN
+ %%
+ %% REOPEN Timer expires & CloseConnection()
+ %% Pending & SetWatchdog()
+ %% NumDWA < 0 DOWN
+ %%
+ %% Peer is now ignoring all watchdogs go down again after 2
+ %% timeouts.
-%% run/1
-%%
-%% A more useful badmatch in case of failure.
+ ?EVENT({watchdog, Ref, _, {reopen, down}, _}, 2, WdL, WdH);
-run([F|A]) ->
- ok = try
- apply(?MODULE, F, A),
- ok
- catch
- E:R ->
- {A, E, R, erlang:get_stacktrace()}
- end.
+%% The misbehaving peer.
+recv(_, Type, SvcName, Ref, Wd, N, M) ->
+ %% First transport process.
+ ?EVENT({watchdog, Ref, _, {initial, okay}, _}, 1000),
+ ?EVENT({up, Ref, _, _, #diameter_packet{}}, 0),
+ reg(Type, Ref, SvcName, {SvcName, {Wd,N,M}}),
+ ?EVENT({watchdog, Ref, _, {okay, down}, _}, infinity),
-%% now_diff/2
+ %% Second transport process.
+ ?EVENT({watchdog, Ref, _, {_, reopen}, _}, infinity),
+ reg(Type, Ref, SvcName, 3),
+ ?EVENT({watchdog, Ref, _, {_, down}, _}, infinity),
-now_diff(T1, T2) ->
- timer:now_diff(T2, T1).
+ %% Third transport process.
+ ?EVENT({watchdog, Ref, _, {_, reopen}, _}, infinity),
+ reg(Type, Ref, SvcName, 0),
+ ?EVENT({watchdog, Ref, _, {_, down}, _}, infinity),
-%% jitter/2
+ ok.
-jitter(?WD(T), _) ->
- T;
-jitter(T,D) ->
- T+D.
+%% recv_reopen/4
-%% watchdog/4
-%%
-%% Fake the call from diameter_service. The watchdog process will send
-%% messages to the calling "service" process so our tests are that the
-%% watchdog responds as expected.
-
-watchdog(Type, Ref, TPid, Wd) ->
- Opts = [{transport_module, ?MODULE},
- {transport_config, TPid},
- {watchdog_timer, Wd}],
- {_MRef, Pid} = diameter_watchdog:start({Type, Ref},
- {false, Opts, false, ?SERVICE}),
- Pid.
+recv_reopen(connect, Ref, WdL, WdH) ->
+ ?EVENT({watchdog, Ref, _, {_, reopen}, _}, 1, WdL, WdH),
+ ?EVENT({reconnect, Ref, _}, 0);
-%% ===========================================================================
+recv_reopen(listen, Ref, _, _) ->
+ ?EVENT({watchdog, Ref, _, {_, reopen}, _}, 1, ?PEER_WD).
-%% Transport process implmentation. Fakes reception of messages by
-%% sending fakes to the parent (peer fsm) process that called start/3.
-
--record(transport,
- {type, %% connect | accept | manager
- parent, %% pid() of peer_fsm/ervice process
- open = false, %% done with capabilities exchange?
- config}).%% testcase-specific config
-
-%% init/2
-
-%% Testcase starting the manager.
-init(SvcPid, {_,_,_,_} = Config) ->
- putr(peer, [{'Origin-Host', hostname() ++ ".utan.com"},
- {'Origin-Realm', "utan.com"}]),
- #transport{type = manager,
- parent = monitor(SvcPid),
- config = Config};
-
-%% Manager starting a transport.
-init(_, {Type, ParentPid, SvcPid, TwinPid, Peer, {N,_,_,_} = Config}) ->
- putr(peer, Peer),
- putr(service, SvcPid),
- putr(count, init(Type, ParentPid, TwinPid, N)),%% number of DWR's to answer
- #transport{type = Type,
- parent = monitor(ParentPid),
- config = Config}.
-
-init(Type, ParentPid, undefined, N) ->
- connected(ParentPid, Type),
- N;
-init(_, _, TPid, _) ->
- monitor(TPid),
- 3.
-
-monitor(Pid) ->
- erlang:monitor(process, Pid),
- Pid.
+%% reg/4
+%%
+%% Lookup the pid of the transport process and publish a term for
+%% send/2 to lookup.
+reg(Type, Ref, SvcName, T) ->
+ TPid = tpid(Type, Ref, diameter:service_info(SvcName, transport)),
+ true = diameter_reg:add_new({?MODULE, TPid, T}).
+
+%% tpid/3
+
+tpid(connect, Ref, [[{ref, Ref},
+ {type, connect},
+ {options, _},
+ {watchdog, _},
+ {peer, _},
+ {apps, _},
+ {caps, _},
+ {port, [{owner, TPid} | _]}
+ | _]]) ->
+ TPid;
+
+tpid(listen, Ref, [[{ref, Ref},
+ {type, listen},
+ {options, _},
+ {accept, As}
+ | _]]) ->
+ [[{watchdog, _},
+ {peer, _},
+ {apps, _},
+ {caps, _},
+ {port, [{owner, TPid} | _]}
+ | _]]
+ = lists:filter(fun([{watchdog, {_,_,S}} | _]) ->
+ S == okay orelse S == reopen
+ end,
+ As),
+ TPid.
-%% Generate a unique hostname for the faked peer.
-hostname() ->
- lists:flatten(io_lib:format("~p-~p-~p", tuple_to_list(now()))).
+%% ===========================================================================
-%% loop/1
-
-loop(S) ->
- loop(msg(receive T -> T end, S)).
-
-msg(T,S) ->
- case transition(T,S) of
- ok ->
- S;
- #transport{} = NS ->
- NS;
- {stop, Reason} ->
- x(Reason)
- end.
-
-x(Reason) ->
- exit(Reason).
-
-%% transition/2
-
-%% Manager is being asked for a new transport process.
-transition({start, Pid, Type, Ref}, #transport{type = manager,
- parent = SvcPid,
- config = Config}) ->
- TPid = start({Type, Pid, SvcPid, getr(transport), getr(peer), Config}),
- Pid ! {Ref, TPid},
- putr(transport, TPid),
+listen(PortNr, Opts) ->
+ gen_tcp:listen(PortNr, Opts).
+
+accept(LSock) ->
+ gen_tcp:accept(LSock).
+
+connect(Addr, Port, Opts) ->
+ gen_tcp:connect(Addr, Port, Opts).
+
+setopts(Sock, Opts) ->
+ inet:setopts(Sock, Opts).
+
+send(Sock, Bin) ->
+ send(getr(config), Sock, Bin).
+
+%% send/3
+
+%% First outgoing message from a new transport process is CER/CEA.
+%% Remaining outgoing messages are either DWR or DWA.
+send(undefined, Sock, Bin) ->
+ putr(config, init),
+ gen_tcp:send(Sock, Bin);
+
+%% Outgoing DWR: fake reception of DWA. Use the fact that AVP values
+%% are ignored. This is to ensure that the peer's watchdog state
+%% transitions are only induced by responses to messages it sends.
+send(_, Sock, <<_:32, 1:1, _:7, 280:24, _:32, EId:32, HId:32, _/binary>>) ->
+ Pkt = #diameter_packet{header = #diameter_header{version = 1,
+ end_to_end_id = EId,
+ hop_by_hop_id = HId},
+ msg = ['DWA', {'Result-Code', 2001},
+ {'Origin-Host', "XXX"},
+ {'Origin-Realm', ?REALM}]},
+ #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Pkt),
+ self() ! {tcp, Sock, Bin},
ok;
-%% Peer fsm or testcase process has died.
-transition({'DOWN', _, process, Pid, _} = T, #transport{parent = Pid}) ->
- {stop, T};
-
-%% Twin transport process has gone down. In the connect case, the
-%% transport isn't started until this happens in the first place so
-%% connect immediately. In the accept case, fake the peer reconnecting
-%% only after another watchdog expiry.
-transition({'DOWN', _, process, _, _}, #transport{type = Type,
- config = {_, Wd, _, _}}) ->
- Tmo = case Type of
- connect ->
- 0;
- accept ->
- ?ONE_WD(Wd)
- end,
- erlang:send_after(Tmo, self(), reconnect),
+%% First outgoing DWA.
+send(init, Sock, Bin) ->
+ [{{?MODULE, _, T}, _}] = diameter_reg:wait({?MODULE, self(), '_'}),
+ putr(config, T),
+ send(Sock, Bin);
+
+%% First transport process.
+send({SvcName, {_,_,_} = T}, Sock, Bin) ->
+ [{'Origin-Host', _} = OH, {'Origin-Realm', _} = OR | _]
+ = ?SERVICE(SvcName),
+ putr(origin, [OH, OR]),
+ putr(config, T),
+ send(Sock, Bin);
+
+%% Discard DWA, failback after another timeout in the peer.
+send({Wd, 0 = No, Msg}, Sock, Bin) ->
+ Origin = getr(origin),
+ spawn(fun() -> failback(?ONE_WD(Wd), Msg, Sock, Bin, Origin) end),
+ putr(config, No),
ok;
-transition(reconnect, #transport{type = Type,
- parent = Pid,
- config = {_,_,_,Ref}}) ->
- getr(service) ! {reopen, Ref},
- connected(Pid, Type),
- ok;
+%% Send DWA while we're in the mood (aka 0 < N).
+send({Wd, N, Msg}, Sock, Bin) ->
+ putr(config, {Wd, N-1, Msg}),
+ gen_tcp:send(Sock, Bin);
-%% Peer fsm process is sending CER: fake the peer's CEA.
-transition(?TMSG({send, Bin}), #transport{type = connect,
- open = false,
- parent = Pid}
- = S) ->
- {Code, Flags, _} = ?BASE:msg_header('CER'),
- <<_:32, Flags:8, Code:24, _:96, _/binary>> = Bin,
- Hdr = make_header(Bin),
- recv(Pid, {Hdr, make_cea()}),
- S#transport{open = true};
-
-%% Peer fsm process is sending CEA.
-transition(?TMSG({send, Bin}), #transport{type = accept,
- open = false}
- = S) ->
- {Code, Flags, _} = ?BASE:msg_header('CEA'),
- <<_:32, Flags:8, Code:24, _:96, _/binary>> = Bin,
- S#transport{open = true};
-
-%% Watchdog is sending DWR or DWA.
-transition(?TMSG({send, Bin}), #transport{open = true} = S) ->
- {Code, _, _} = ?BASE:msg_header('DWR'),
- {Code, _, _} = ?BASE:msg_header('DWA'),
- <<_:32, R:1, 0:7, Code:24, _:96, _/binary>> = Bin,
- Hdr = make_header(Bin),
- dwa(1 == R, S, Hdr),
+%% Discard DWA.
+send(0, _Sock, _Bin) ->
ok;
-%% We're telling ourselves to fake a received message.
-transition({recv, Msg}, #transport{parent = Pid}) ->
- recv(Pid, Msg),
- ok;
+%% Send DWA.
+send(N, Sock, <<_:32, 0:1, _:7, 280:24, _/binary>> = Bin) ->
+ putr(config, N-1),
+ gen_tcp:send(Sock, Bin).
-%% We're telling ourselves to receive a message to induce failback.
-transition(failback = T, #transport{parent = Pid}) ->
- recv(Pid, eraser(T)),
- ok.
+failback(Tmo, Msg, Sock, Bin, Origin) ->
+ timer:sleep(Tmo),
+ ok = gen_tcp:send(Sock, msg(Msg, Bin, Origin)).
-make_header(Bin) ->
- #diameter_header{end_to_end_id = E,
- hop_by_hop_id = H}
- = diameter_codec:decode_header(Bin),
- #diameter_header{end_to_end_id = E,
- hop_by_hop_id = H}.
-
-recv(Pid, Msg) ->
- Pid ! ?TMSG({recv, encode(Msg)}).
-
-%% Replace the end-to-end/hop-by-hop identifiers with those from an
-%% incoming request to which we're constructing a reply.
-encode({Hdr, [_|_] = Msg}) ->
- #diameter_header{hop_by_hop_id = HBH,
- end_to_end_id = E2E}
- = Hdr,
- #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Msg),
- <<H:12/binary, _:64, T/binary>> = Bin,
- <<H/binary, HBH:32, E2E:32, T/binary>>;
-
-encode([_|_] = Msg) ->
- #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Msg),
+%% msg/2
+
+msg('DWA', Bin, _Origin) ->
+ Bin;
+msg(Msg, _Bin, Origin) ->
+ #diameter_packet{bin = Bin}
+ = diameter_codec:encode(?BASE, msg(Msg, Origin)),
Bin.
-connected(Pid, connect) ->
- Pid ! ?TMSG({self(), connected, make_ref()});
-connected(Pid, accept) ->
- Pid ! ?TMSG({self(), connected}),
- recv(Pid, make_cer()).
+msg('DWR' = M, T) ->
+ [M | T];
-make_cer() ->
- ['CER' | getr(peer)] ++ [{'Host-IP-Address', [?REMOTEHOST]},
- {'Vendor-Id', 1028},
- {'Product-Name', "Utan"},
- {'Auth-Application-Id', [?APPL_ID]}].
+msg('RAA', T) ->
+ ['RAA', {'Session-Id', diameter:session_id("abc")},
+ {'Result-Code', 2001}
+ | T].
+%% An unexpected answer is discarded after passing through the
+%% watchdog state machine.
-make_cea() ->
- ['CER' | Rest] = make_cer(),
- ['CEA', {'Result-Code', ?SUCCESS} | Rest].
+%% ===========================================================================
-make_dwr() ->
- ['DWR' | getr(peer)].
+peer_up(_SvcName, _Peer, S) ->
+ S.
-make_dwa() ->
- ['DWR' | Rest] = make_dwr(),
- ['DWA', {'Result-Code', ?SUCCESS} | Rest].
+peer_down(_SvcName, _Peer, S) ->
+ S.
-dwa(false, _, _) -> %% outgoing was DWA ...
- ok;
-dwa(true, S, Hdr) -> %% ... or DWR
- dwa(getr(count), Hdr, S);
-
-%% React to the DWR only after another watchdog expiry. We shouldn't
-%% get another DWR while the answer is pending.
-dwa(0, Hdr, #transport{config = {_, Wd, What, _}}) ->
- erlang:send_after(?ONE_WD(Wd), self(), failback),
- putr(failback, make_msg(What, Hdr)),
- eraser(count);
-
-dwa(undefined, _, _) ->
- undefined = getr(failback), %% ensure this is after failback
- ok;
+%% ===========================================================================
-%% Reply with DWA.
-dwa(N, Hdr, #transport{parent = Pid}) ->
- putr(count, N-1),
- recv(Pid, {Hdr, make_dwa()}).
+choose(true, X, _) -> X;
+choose(false, _, X) -> X.
-%% Answer to received DWR.
-make_msg('DWA', Hdr) ->
- {Hdr, make_dwa()};
+%% id/1
+%%
+%% Jitter callback.
-%% DWR from peer.
-make_msg('DWR', _) ->
- make_dwr();
+id(T) ->
+ T.
-%% An unexpected answer is discarded after passing through the
-%% watchdog state machine.
-make_msg(other, _) ->
- ['RAA', {'Session-Id', diameter:session_id("abc")},
- {'Result-Code', 2001}
- | getr(peer)].
+%% run/1
+%%
+%% A more useful badmatch in case of failure.
+
+run(Fs) ->
+ ?util:run([{?MODULE, [run1, F]} || F <- Fs]).
+
+run1([F|A]) ->
+ ok = try
+ apply(?MODULE, F, A),
+ ok
+ catch
+ E:R ->
+ S = erlang:get_stacktrace(),
+ io:format("~p~n", [{A, E, R, S}]),
+ S
+ end.
+
+%% now_diff/2
+
+now_diff(T1, T2) ->
+ timer:now_diff(T2, T1).
+
+%% jitter/2
+
+jitter(?WD(T), _) ->
+ T;
+jitter(T,D) ->
+ T+D.
+
+%% Generate a unique hostname for the faked peer.
+hostname() ->
+ lists:flatten(io_lib:format("~p-~p-~p", tuple_to_list(now()))).
putr(Key, Val) ->
put({?MODULE, Key}, Val).
getr(Key) ->
get({?MODULE, Key}).
-
-eraser(Key) ->
- erase({?MODULE, Key}).
diff --git a/lib/stdlib/test/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl
index c46fc47b34..df9c769c67 100644
--- a/lib/stdlib/test/dict_SUITE.erl
+++ b/lib/stdlib/test/dict_SUITE.erl
@@ -53,7 +53,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_Case, Config) ->
- ?line Dog = ?t:timetrap(?t:minutes(5)),
+ Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
end_per_testcase(_Case, Config) ->
@@ -65,22 +65,22 @@ create(Config) when is_list(Config) ->
test_all(fun create_1/1).
create_1(M) ->
- ?line D0 = M:empty(),
- ?line [] = M:to_list(D0),
- ?line 0 = M:size(D0),
+ D0 = M(empty, []),
+ [] = M(to_list, D0),
+ 0 = M(size, D0),
D0.
store(Config) when is_list(Config) ->
test_all([{0,132},{253,258},{510,514}], fun store_1/2).
store_1(List, M) ->
- ?line D0 = M:from_list(List),
+ D0 = M(from_list, List),
%% Make sure that we get the same result by inserting
%% elements one at the time.
- ?line D1 = foldl(fun({K,V}, Dict) -> M:enter(K, V, Dict) end,
- M:empty(), List),
- ?line true = M:equal(D0, D1),
+ D1 = foldl(fun({K,V}, Dict) -> M(enter, {K,V,Dict}) end,
+ M(empty, []), List),
+ true = M(equal, {D0,D1}),
D0.
%%%
@@ -98,7 +98,7 @@ dict_mods() ->
[Orddict,Dict,Gb].
test_all(Tester) ->
- ?line Pids = [spawn_tester(M, Tester) || M <- dict_mods()],
+ Pids = [spawn_tester(M, Tester) || M <- dict_mods()],
collect_all(Pids, []).
spawn_tester(M, Tester) ->
@@ -106,7 +106,7 @@ spawn_tester(M, Tester) ->
spawn_link(fun() ->
random:seed(1, 2, 42),
S = Tester(M),
- Res = {M:size(S),lists:sort(M:to_list(S))},
+ Res = {M(size, S),lists:sort(M(to_list, S))},
Parent ! {result,self(),Res}
end).
diff --git a/lib/stdlib/test/dict_test_lib.erl b/lib/stdlib/test/dict_test_lib.erl
index 92a75dad89..7167014310 100644
--- a/lib/stdlib/test/dict_test_lib.erl
+++ b/lib/stdlib/test/dict_test_lib.erl
@@ -17,67 +17,48 @@
%% %CopyrightEnd%
%%
--module(dict_test_lib, [Mod,Equal]).
+-module(dict_test_lib).
--export([module/0,equal/2,empty/0,size/1,to_list/1,from_list/1,
- enter/3,delete/2,lookup/2]).
+-export([new/2]).
-module() ->
- Mod.
-
-equal(X, Y) ->
- Equal(X, Y).
+new(Mod, Eq) ->
+ fun (enter, {K,V,D}) -> enter(Mod, K, V, D);
+ (empty, []) -> empty(Mod);
+ (equal, {D1,D2}) -> Eq(D1, D2);
+ (from_list, L) -> from_list(Mod, L);
+ (module, []) -> Mod;
+ (size, D) -> Mod:size(D);
+ (to_list, D) -> to_list(Mod, D)
+ end.
-empty() ->
+empty(Mod) ->
case erlang:function_exported(Mod, new, 0) of
false -> Mod:empty();
true -> Mod:new()
end.
-size(S) ->
- Mod:size(S).
-
-to_list(S) ->
- Mod:to_list(S).
+to_list(Mod, D) ->
+ Mod:to_list(D).
-from_list(S) ->
+from_list(Mod, L) ->
case erlang:function_exported(Mod, from_orddict, 1) of
false ->
- Mod:from_list(S);
+ Mod:from_list(L);
true ->
%% The gb_trees module has no from_list/1 function.
%%
%% The keys in S are not unique. To make sure
%% that we pick the same key/value pairs as
%% dict/orddict, first convert the list to an orddict.
- Orddict = orddict:from_list(S),
+ Orddict = orddict:from_list(L),
Mod:from_orddict(Orddict)
end.
%% Store new value into dictionary or update previous value in dictionary.
-enter(Key, Val, Dict) ->
+enter(Mod, Key, Val, Dict) ->
case erlang:function_exported(Mod, store, 3) of
false ->
Mod:enter(Key, Val, Dict);
true ->
Mod:store(Key, Val, Dict)
end.
-
-%% Delete an EXISTING key.
-delete(Key, Dict) ->
- case erlang:function_exported(Mod, delete, 2) of
- true -> Mod:delete(Key, Dict);
- false -> Mod:erase(Key, Dict)
- end.
-
-%% -> none | {value,Value}
-lookup(Key, Dict) ->
- case erlang:function_exported(Mod, lookup, 2) of
- false ->
- case Mod:find(Key, Dict) of
- error -> none;
- {ok,Value} -> {value,Value}
- end;
- true ->
- Mod:lookup(Key, Dict)
- end.
diff --git a/lib/stdlib/test/sets_SUITE.erl b/lib/stdlib/test/sets_SUITE.erl
index f284276bd7..e2bcdd18ce 100644
--- a/lib/stdlib/test/sets_SUITE.erl
+++ b/lib/stdlib/test/sets_SUITE.erl
@@ -35,7 +35,7 @@
-import(lists, [foldl/3,reverse/1]).
init_per_testcase(_Case, Config) ->
- ?line Dog = ?t:timetrap(?t:minutes(5)),
+ Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
end_per_testcase(_Case, Config) ->
@@ -70,65 +70,65 @@ create(Config) when is_list(Config) ->
test_all(fun create_1/1).
create_1(M) ->
- ?line S0 = M:empty(),
- ?line [] = M:to_list(S0),
- ?line 0 = M:size(S0),
- ?line true = M:is_empty(S0),
+ S0 = M(empty, []),
+ [] = M(to_list, S0),
+ 0 = M(size, S0),
+ true = M(is_empty, S0),
E = make_ref(),
- ?line One = M:singleton(E),
- ?line 1 = M:size(One),
- ?line false = M:is_empty(One),
- [E] = M:to_list(One),
+ One = M(singleton, E),
+ 1 = M(size, One),
+ false = M(is_empty, One),
+ [E] = M(to_list, One),
S0.
add_element(Config) when is_list(Config) ->
test_all([{0,132},{253,258},{510,514}], fun add_element_1/2).
add_element_1(List, M) ->
- ?line S = M:from_list(List),
- ?line SortedSet = lists:usort(List),
- ?line SortedSet = lists:sort(M:to_list(S)),
+ S = M(from_list, List),
+ SortedSet = lists:usort(List),
+ SortedSet = lists:sort(M(to_list, S)),
%% Make sure that we get the same result by inserting
%% elements one at the time.
- ?line S2 = foldl(fun(El, Set) -> M:add_element(El, Set) end,
- M:empty(), List),
- ?line true = M:equal(S, S2),
+ S2 = foldl(fun(El, Set) -> M(add_element, {El,Set}) end,
+ M(empty, []), List),
+ true = M(equal, {S,S2}),
%% Insert elements, randomly delete inserted elements,
%% and re-inserted all deleted elements at the end.
- ?line S3 = add_element_del(List, M, M:empty(), [], []),
- ?line true = M:equal(S2, S3),
- ?line true = M:equal(S, S3),
+ S3 = add_element_del(List, M, M(empty, []), [], []),
+ true = M(equal, {S2,S3}),
+ true = M(equal, {S,S3}),
S.
add_element_del([H|T], M, S, Del, []) ->
- add_element_del(T, M, M:add_element(H, S), Del, [H]);
+ add_element_del(T, M, M(add_element, {H,S}), Del, [H]);
add_element_del([H|T], M, S0, Del, Inserted) ->
- S1 = M:add_element(H, S0),
+ S1 = M(add_element, {H,S0}),
case random:uniform(3) of
1 ->
OldEl = lists:nth(random:uniform(length(Inserted)), Inserted),
- S = M:del_element(OldEl, S1),
+ S = M(del_element, {OldEl,S1}),
add_element_del(T, M, S, [OldEl|Del], [H|Inserted]);
_ ->
add_element_del(T, M, S1, Del, [H|Inserted])
end;
add_element_del([], M, S, Del, _) ->
- M:union(S, M:from_list(Del)).
+ M(union, {S,M(from_list, Del)}).
del_element(Config) when is_list(Config) ->
test_all([{0,132},{253,258},{510,514},{1022,1026}], fun del_element_1/2).
del_element_1(List, M) ->
- ?line S0 = M:from_list(List),
- ?line Empty = foldl(fun(El, Set) -> M:del_element(El, Set) end, S0, List),
- ?line Empty = M:empty(),
- ?line M:is_empty(Empty),
- ?line S1 = foldl(fun(El, Set) ->
- M:add_element(El, Set)
- end, S0, reverse(List)),
- ?line true = M:equal(S0, S1),
+ S0 = M(from_list, List),
+ Empty = foldl(fun(El, Set) -> M(del_element, {El,Set}) end, S0, List),
+ Empty = M(empty, []),
+ true = M(is_empty, Empty),
+ S1 = foldl(fun(El, Set) ->
+ M(add_element, {El,Set})
+ end, S0, reverse(List)),
+ true = M(equal, {S0,S1}),
S1.
subtract(Config) when is_list(Config) ->
@@ -138,23 +138,23 @@ subtract(Config) when is_list(Config) ->
test_all([{2,69},{126,130},{253,258},511,512,{1023,1030}], fun subtract_1/2).
subtract_empty(M) ->
- ?line Empty = M:empty(),
- ?line true = M:is_empty(M:subtract(Empty, Empty)),
- M:subtract(Empty, Empty).
+ Empty = M(empty, []),
+ true = M(is_empty, M(subtract, {Empty,Empty})),
+ M(subtract, {Empty,Empty}).
subtract_1(List, M) ->
- ?line S0 = M:from_list(List),
- ?line Empty = M:empty(),
+ S0 = M(from_list, List),
+ Empty = M(empty, []),
%% Trivial cases.
- ?line true = M:is_empty(M:subtract(Empty, S0)),
- ?line true = M:equal(S0, M:subtract(S0, Empty)),
+ true = M(is_empty, M(subtract, {Empty,S0})),
+ true = M(equal, {S0,M(subtract, {S0,Empty})}),
%% Not so trivial.
- ?line subtract_check(List, mutate_some(remove_some(List, 0.4)), M),
- ?line subtract_check(List, rnd_list(length(List) div 2 + 5), M),
- ?line subtract_check(List, rnd_list(length(List) div 7 + 9), M),
- ?line subtract_check(List, mutate_some(List), M).
+ subtract_check(List, mutate_some(remove_some(List, 0.4)), M),
+ subtract_check(List, rnd_list(length(List) div 2 + 5), M),
+ subtract_check(List, rnd_list(length(List) div 7 + 9), M),
+ subtract_check(List, mutate_some(List), M).
subtract_check(A, B, M) ->
one_subtract_check(B, A, M),
@@ -163,12 +163,12 @@ subtract_check(A, B, M) ->
one_subtract_check(A, B, M) ->
ASorted = lists:usort(A),
BSorted = lists:usort(B),
- ASet = M:from_list(A),
- BSet = M:from_list(B),
- DiffSet = M:subtract(ASet, BSet),
+ ASet = M(from_list, A),
+ BSet = M(from_list, B),
+ DiffSet = M(subtract, {ASet,BSet}),
Diff = ASorted -- BSorted,
- true = M:equal(DiffSet, M:from_list(Diff)),
- Diff = lists:sort(M:to_list(DiffSet)),
+ true = M(equal, {DiffSet,M(from_list, Diff)}),
+ Diff = lists:sort(M(to_list, DiffSet)),
DiffSet.
intersection(Config) when is_list(Config) ->
@@ -176,60 +176,60 @@ intersection(Config) when is_list(Config) ->
test_all([{1,65},{126,130},{253,259},{499,513},{1023,1025}], fun intersection_1/2).
intersection_1(List, M) ->
- ?line S0 = M:from_list(List),
+ S0 = M(from_list, List),
%% Intersection with self.
- ?line true = M:equal(S0, M:intersection(S0, S0)),
- ?line true = M:equal(S0, M:intersection([S0,S0])),
- ?line true = M:equal(S0, M:intersection([S0,S0,S0])),
- ?line true = M:equal(S0, M:intersection([S0])),
+ true = M(equal, {S0,M(intersection, {S0,S0})}),
+ true = M(equal, {S0,M(intersection, [S0,S0])}),
+ true = M(equal, {S0,M(intersection, [S0,S0,S0])}),
+ true = M(equal, {S0,M(intersection, [S0])}),
%% Intersection with empty.
- ?line Empty = M:empty(),
- ?line true = M:equal(Empty, M:intersection(S0, Empty)),
- ?line true = M:equal(Empty, M:intersection([S0,Empty,S0,Empty])),
+ Empty = M(empty, []),
+ true = M(equal, {Empty,M(intersection, {S0,Empty})}),
+ true = M(equal, {Empty,M(intersection, [S0,Empty,S0,Empty])}),
%% The intersection of no sets is undefined.
- ?line {'EXIT',_} = (catch M:intersection([])),
+ {'EXIT',_} = (catch M(intersection, [])),
%% Disjoint sets.
- ?line Disjoint = [{El} || El <- List],
- ?line DisjointSet = M:from_list(Disjoint),
- ?line M:is_empty(M:intersection(S0, DisjointSet)),
+ Disjoint = [{El} || El <- List],
+ DisjointSet = M(from_list, Disjoint),
+ true = M(is_empty, M(intersection, {S0,DisjointSet})),
%% Disjoint, different sizes.
- ?line M:is_empty(M:intersection(S0, M:from_list(remove_some(Disjoint, 0.3)))),
- ?line M:is_empty(M:intersection(S0, M:from_list(remove_some(Disjoint, 0.7)))),
- ?line M:is_empty(M:intersection(S0, M:from_list(remove_some(Disjoint, 0.9)))),
- ?line M:is_empty(M:intersection(M:from_list(remove_some(List, 0.3)), DisjointSet)),
- ?line M:is_empty(M:intersection(M:from_list(remove_some(List, 0.5)), DisjointSet)),
- ?line M:is_empty(M:intersection(M:from_list(remove_some(List, 0.9)), DisjointSet)),
+ [begin
+ SomeRemoved = M(from_list, remove_some(Disjoint, HowMuch)),
+ true = M(is_empty, M(intersection, {S0,SomeRemoved})),
+ MoreRemoved = M(from_list, remove_some(List, HowMuch)),
+ true = M(is_empty, M(intersection, {MoreRemoved,DisjointSet}))
+ end || HowMuch <- [0.3,0.5,0.7,0.9]],
%% Partial overlap (one or more elements in result set).
%% The sets have almost the same size. (Almost because a duplicated
%% element in the original list could be mutated and not mutated
%% at the same time.)
- ?line PartialOverlap = mutate_some(List, []),
- ?line IntersectionSet = check_intersection(List, PartialOverlap, M),
- ?line false = M:is_empty(IntersectionSet),
+ PartialOverlap = mutate_some(List, []),
+ IntersectionSet = check_intersection(List, PartialOverlap, M),
+ false = M(is_empty, IntersectionSet),
%% Partial overlap, different set sizes. (Intersection possibly empty.)
- ?line check_intersection(List, remove_some(PartialOverlap, 0.1), M),
- ?line check_intersection(List, remove_some(PartialOverlap, 0.3), M),
- ?line check_intersection(List, remove_some(PartialOverlap, 0.5), M),
- ?line check_intersection(List, remove_some(PartialOverlap, 0.7), M),
- ?line check_intersection(List, remove_some(PartialOverlap, 0.9), M),
+ check_intersection(List, remove_some(PartialOverlap, 0.1), M),
+ check_intersection(List, remove_some(PartialOverlap, 0.3), M),
+ check_intersection(List, remove_some(PartialOverlap, 0.5), M),
+ check_intersection(List, remove_some(PartialOverlap, 0.7), M),
+ check_intersection(List, remove_some(PartialOverlap, 0.9), M),
IntersectionSet.
check_intersection(Orig, Mutated, M) ->
- OrigSet = M:from_list(Orig),
- MutatedSet = M:from_list(Mutated),
+ OrigSet = M(from_list, Orig),
+ MutatedSet = M(from_list, Mutated),
Intersection = [El || El <- Mutated, not is_tuple(El)],
SortedIntersection = lists:usort(Intersection),
- IntersectionSet = M:intersection(OrigSet, MutatedSet),
- true = M:equal(IntersectionSet, M:from_list(SortedIntersection)),
- SortedIntersection = lists:sort(M:to_list(IntersectionSet)),
+ IntersectionSet = M(intersection, {OrigSet,MutatedSet}),
+ true = M(equal, {IntersectionSet,M(from_list, SortedIntersection)}),
+ SortedIntersection = lists:sort(M(to_list, IntersectionSet)),
IntersectionSet.
@@ -239,63 +239,63 @@ union(Config) when is_list(Config) ->
test_all([{1,71},{125,129},{254,259},{510,513},{1023,1025}], fun union_1/2).
union_1(List, M) ->
- ?line S = M:from_list(List),
+ S = M(from_list, List),
%% Union with self and empty.
- ?line Empty = M:empty(),
- ?line true = M:equal(S, M:union(S, S)),
- ?line true = M:equal(S, M:union([S,S])),
- ?line true = M:equal(S, M:union([S,S,Empty])),
- ?line true = M:equal(S, M:union([S,Empty,S])),
- ?line true = M:equal(S, M:union(S, Empty)),
- ?line true = M:equal(S, M:union([S])),
- ?line true = M:is_empty(M:union([])),
+ Empty = M(empty, []),
+ true = M(equal, {S,M(union, {S,S})}),
+ true = M(equal, {S,M(union, [S,S])}),
+ true = M(equal, {S,M(union, [S,S,Empty])}),
+ true = M(equal, {S,M(union, [S,Empty,S])}),
+ true = M(equal, {S,M(union, {S,Empty})}),
+ true = M(equal, {S,M(union, [S])}),
+ true = M(is_empty, M(union, [])),
%% Partial overlap.
- ?line check_union(List, remove_some(mutate_some(List), 0.9), M),
- ?line check_union(List, remove_some(mutate_some(List), 0.7), M),
- ?line check_union(List, remove_some(mutate_some(List), 0.5), M),
- ?line check_union(List, remove_some(mutate_some(List), 0.3), M),
- ?line check_union(List, remove_some(mutate_some(List), 0.1), M),
-
- ?line check_union(List, mutate_some(remove_some(List, 0.9)), M),
- ?line check_union(List, mutate_some(remove_some(List, 0.7)), M),
- ?line check_union(List, mutate_some(remove_some(List, 0.5)), M),
- ?line check_union(List, mutate_some(remove_some(List, 0.3)), M),
- ?line check_union(List, mutate_some(remove_some(List, 0.1)), M).
+ check_union(List, remove_some(mutate_some(List), 0.9), M),
+ check_union(List, remove_some(mutate_some(List), 0.7), M),
+ check_union(List, remove_some(mutate_some(List), 0.5), M),
+ check_union(List, remove_some(mutate_some(List), 0.3), M),
+ check_union(List, remove_some(mutate_some(List), 0.1), M),
+
+ check_union(List, mutate_some(remove_some(List, 0.9)), M),
+ check_union(List, mutate_some(remove_some(List, 0.7)), M),
+ check_union(List, mutate_some(remove_some(List, 0.5)), M),
+ check_union(List, mutate_some(remove_some(List, 0.3)), M),
+ check_union(List, mutate_some(remove_some(List, 0.1)), M).
check_union(Orig, Other, M) ->
- OrigSet = M:from_list(Orig),
- OtherSet = M:from_list(Other),
+ OrigSet = M(from_list, Orig),
+ OtherSet = M(from_list, Other),
Union = Orig++Other,
SortedUnion = lists:usort(Union),
- UnionSet = M:union(OrigSet, OtherSet),
- SortedUnion = lists:sort(M:to_list(UnionSet)),
- M:equal(UnionSet, M:from_list(Union)),
+ UnionSet = M(union, {OrigSet,OtherSet}),
+ SortedUnion = lists:sort(M(to_list, UnionSet)),
+ M(equal, {UnionSet,M(from_list, Union)}),
UnionSet.
is_subset(Config) when is_list(Config) ->
test_all([{1,132},{253,270},{299,311}], fun is_subset_1/2).
is_subset_1(List, M) ->
- ?line S = M:from_list(List),
- ?line Empty = M:empty(),
+ S = M(from_list, List),
+ Empty = M(empty, []),
%% Subset of empty and self.
- ?line true = M:is_subset(Empty, Empty),
- ?line true = M:is_subset(Empty, S),
- ?line false = M:is_subset(S, Empty),
- ?line true = M:is_subset(S, S),
+ true = M(is_subset, {Empty,Empty}),
+ true = M(is_subset, {Empty,S}),
+ false = M(is_subset, {S,Empty}),
+ true = M(is_subset, {S,S}),
%% Other cases.
- Res = [?line false = M:is_subset(M:singleton(make_ref()), S),
- ?line true = M:is_subset(M:singleton(hd(List)), S),
- ?line true = check_subset(remove_some(List, 0.1), List, M),
- ?line true = check_subset(remove_some(List, 0.5), List, M),
- ?line true = check_subset(remove_some(List, 0.9), List, M),
- ?line check_subset(mutate_some(List), List, M),
- ?line check_subset(rnd_list(length(List) div 2 + 5), List, M),
- ?line subtract_check(List, rnd_list(length(List) div 7 + 9), M)
+ Res = [false = M(is_subset, {M(singleton, make_ref()),S}),
+ true = M(is_subset, {M(singleton, hd(List)),S}),
+ true = check_subset(remove_some(List, 0.1), List, M),
+ true = check_subset(remove_some(List, 0.5), List, M),
+ true = check_subset(remove_some(List, 0.9), List, M),
+ check_subset(mutate_some(List), List, M),
+ check_subset(rnd_list(length(List) div 2 + 5), List, M),
+ subtract_check(List, rnd_list(length(List) div 7 + 9), M)
],
res_to_set(Res, M, 0, []).
@@ -304,12 +304,12 @@ check_subset(X, Y, M) ->
check_one_subset(X, Y, M).
check_one_subset(X, Y, M) ->
- XSet = M:from_list(X),
- YSet = M:from_list(Y),
+ XSet = M(from_list, X),
+ YSet = M(from_list, Y),
SortedX = lists:usort(X),
SortedY = lists:usort(Y),
IsSubSet = length(SortedY--SortedX) =:= length(SortedY) - length(SortedX),
- IsSubSet = M:is_subset(XSet, YSet),
+ IsSubSet = M(is_subset, {XSet,YSet}),
IsSubSet.
%% Encode all test results as a set to return.
@@ -317,54 +317,54 @@ res_to_set([true|T], M, I, Acc) ->
res_to_set(T, M, I+1, [I|Acc]);
res_to_set([_|T], M, I, Acc) ->
res_to_set(T, M, I+1, Acc);
-res_to_set([], M, _, Acc) -> M:from_list(Acc).
+res_to_set([], M, _, Acc) -> M(from_list, Acc).
is_set(Config) when is_list(Config) ->
%% is_set/1 is tested in the other test cases when its argument
%% is a set. Here test some arguments that makes it return false.
- ?line false = gb_sets:is_set([a,b]),
- ?line false = gb_sets:is_set({a,very,bad,tuple}),
+ false = gb_sets:is_set([a,b]),
+ false = gb_sets:is_set({a,very,bad,tuple}),
- ?line false = sets:is_set([a,b]),
- ?line false = sets:is_set({a,very,bad,tuple}),
+ false = sets:is_set([a,b]),
+ false = sets:is_set({a,very,bad,tuple}),
- ?line false = ordsets:is_set([b,a]),
- ?line false = ordsets:is_set({bad,tuple}),
+ false = ordsets:is_set([b,a]),
+ false = ordsets:is_set({bad,tuple}),
%% Now test values that are known to be bad for all set representations.
test_all(fun is_set_1/1).
is_set_1(M) ->
- ?line false = M:is_set(self()),
- ?line false = M:is_set(blurf),
- ?line false = M:is_set(make_ref()),
- ?line false = M:is_set(<<1,2,3>>),
- ?line false = M:is_set(42),
- ?line false = M:is_set(math:pi()),
- ?line false = M:is_set({}),
- M:empty().
+ false = M(is_set, self()),
+ false = M(is_set, blurf),
+ false = M(is_set, make_ref()),
+ false = M(is_set, <<1,2,3>>),
+ false = M(is_set, 42),
+ false = M(is_set, math:pi()),
+ false = M(is_set, {}),
+ M(empty, []).
fold(Config) when is_list(Config) ->
test_all([{0,71},{125,129},{254,259},{510,513},{1023,1025},{9999,10001}],
fun fold_1/2).
fold_1(List, M) ->
- ?line S = M:from_list(List),
- ?line L = M:fold(fun(E, A) -> [E|A] end, [], S),
- ?line true = lists:sort(L) =:= lists:usort(List),
- M:empty().
+ S = M(from_list, List),
+ L = M(fold, {fun(E, A) -> [E|A] end,[],S}),
+ true = lists:sort(L) =:= lists:usort(List),
+ M(empty, []).
filter(Config) when is_list(Config) ->
test_all([{0,69},{126,130},{254,259},{510,513},{1023,1025},{7999,8000}],
fun filter_1/2).
filter_1(List, M) ->
- ?line S = M:from_list(List),
+ S = M(from_list, List),
IsNumber = fun(X) -> is_number(X) end,
- ?line M:equal(M:from_list(lists:filter(IsNumber, List)),
- M:filter(IsNumber, S)),
- ?line M:filter(fun(X) -> is_atom(X) end, S).
+ M(equal, {M(from_list, lists:filter(IsNumber, List)),
+ M(filter, {IsNumber,S})}),
+ M(filter, {fun(X) -> is_atom(X) end,S}).
%%%
%%% Test specifics for gb_sets.
@@ -375,26 +375,26 @@ take_smallest(Config) when is_list(Config) ->
fun take_smallest_1/2).
take_smallest_1(List, M) ->
- case M:module() of
+ case M(module, []) of
gb_sets -> take_smallest_2(List, M);
_ -> ok
end,
- M:empty().
+ M(empty, []).
take_smallest_2(List0, M) ->
- ?line List = lists:usort(List0),
- ?line S = M:from_list(List0),
+ List = lists:usort(List0),
+ S = M(from_list, List0),
take_smallest_3(S, List, M).
take_smallest_3(S0, List0, M) ->
- case M:is_empty(S0) of
+ case M(is_empty, S0) of
true -> ok;
false ->
- ?line Smallest = hd(List0),
- ?line Smallest = gb_sets:smallest(S0),
- ?line {Smallest,S} = gb_sets:take_smallest(S0),
- ?line List = tl(List0),
- ?line true = gb_sets:to_list(S) =:= List,
+ Smallest = hd(List0),
+ Smallest = gb_sets:smallest(S0),
+ {Smallest,S} = gb_sets:take_smallest(S0),
+ List = tl(List0),
+ true = gb_sets:to_list(S) =:= List,
take_smallest_3(S, List, M)
end.
@@ -403,26 +403,26 @@ take_largest(Config) when is_list(Config) ->
fun take_largest_1/2).
take_largest_1(List, M) ->
- case M:module() of
+ case M(module, []) of
gb_sets -> take_largest_2(List, M);
_ -> ok
end,
- M:empty().
+ M(empty, []).
take_largest_2(List0, M) ->
- ?line List = reverse(lists:usort(List0)),
- ?line S = M:from_list(List0),
+ List = reverse(lists:usort(List0)),
+ S = M(from_list, List0),
take_largest_3(S, List, M).
take_largest_3(S0, List0, M) ->
- case M:is_empty(S0) of
+ case M(is_empty, S0) of
true -> ok;
false ->
- ?line Largest = hd(List0),
- ?line Largest = gb_sets:largest(S0),
- ?line {Largest,S} = gb_sets:take_largest(S0),
- ?line List = tl(List0),
- ?line true = gb_sets:to_list(S) =:= reverse(List),
+ Largest = hd(List0),
+ Largest = gb_sets:largest(S0),
+ {Largest,S} = gb_sets:take_largest(S0),
+ List = tl(List0),
+ true = gb_sets:to_list(S) =:= reverse(List),
take_largest_3(S, List, M)
end.
@@ -441,23 +441,23 @@ sets_mods() ->
[Ordsets,Sets,Gb].
test_all(Tester) ->
- ?line Res = [begin
- random:seed(1, 2, 42),
- S = Tester(M),
- {M:size(S),lists:sort(M:to_list(S))}
- end || M <- sets_mods()],
- ?line all_same(Res).
+ Res = [begin
+ random:seed(1, 2, 42),
+ S = Tester(M),
+ {M(size, S),lists:sort(M(to_list, S))}
+ end || M <- sets_mods()],
+ all_same(Res).
test_all([{Low,High}|T], Tester) ->
test_all(lists:seq(Low, High)++T, Tester);
test_all([Sz|T], Tester) when is_integer(Sz) ->
List = rnd_list(Sz),
- ?line Res = [begin
+ Res = [begin
random:seed(19, 2, Sz),
S = Tester(List, M),
- {M:size(S),lists:sort(M:to_list(S))}
+ {M(size, S),lists:sort(M(to_list, S))}
end || M <- sets_mods()],
- ?line all_same(Res),
+ all_same(Res),
test_all(T, Tester);
test_all([], _) -> ok.
diff --git a/lib/stdlib/test/sets_test_lib.erl b/lib/stdlib/test/sets_test_lib.erl
index bdfb0d59d2..fd4ec2bac3 100644
--- a/lib/stdlib/test/sets_test_lib.erl
+++ b/lib/stdlib/test/sets_test_lib.erl
@@ -17,91 +17,89 @@
%% %CopyrightEnd%
%%
--module(sets_test_lib, [Mod,Equal]).
-
--export([module/0,equal/2,empty/0,from_list/1,to_list/1,singleton/1,
- add_element/2,del_element/2,size/1,is_empty/1,is_set/1,
- intersection/1,intersection/2,subtract/2,
- union/1,union/2,is_subset/2,fold/3,filter/2]).
-
-module() ->
- Mod.
-
-equal(X, Y) ->
- Equal(X, Y).
-
-empty() ->
- Mod:new().
-
-from_list(L) ->
- Mod:from_list(L).
-
-to_list(S) ->
- Mod:to_list(S).
+-module(sets_test_lib).
+
+-export([new/2]).
+
+new(Mod, Eq) ->
+ fun (add_element, {El,S}) -> add_element(Mod, El, S);
+ (del_element, {El,S}) -> del_element(Mod, El, S);
+ (empty, []) -> Mod:new();
+ (equal, {S1,S2}) -> Eq(S1, S2);
+ (filter, {F,S}) -> filter(Mod, F, S);
+ (fold, {F,A,S}) -> fold(Mod, F, A, S);
+ (from_list, L) -> Mod:from_list(L);
+ (intersection, {S1,S2}) -> intersection(Mod, Eq, S1, S2);
+ (intersection, Ss) -> intersection(Mod, Eq, Ss);
+ (is_empty, S) -> is_empty(Mod, S);
+ (is_set, S) -> Mod:is_set(S);
+ (is_subset, {S,Set}) -> is_subset(Mod, Eq, S, Set);
+ (module, []) -> Mod;
+ (singleton, E) -> singleton(Mod, E);
+ (size, S) -> Mod:size(S);
+ (subtract, {S1,S2}) -> subtract(Mod, S1, S2);
+ (to_list, S) -> Mod:to_list(S);
+ (union, {S1,S2}) -> union(Mod, Eq, S1, S2);
+ (union, Ss) -> union(Mod, Eq, Ss)
+ end.
-singleton(E) ->
+singleton(Mod, E) ->
case erlang:function_exported(Mod, singleton, 1) of
true -> Mod:singleton(E);
- false -> from_list([E])
+ false -> Mod:from_list([E])
end.
-add_element(El, S0) ->
+add_element(Mod, El, S0) ->
S = Mod:add_element(El, S0),
true = Mod:is_element(El, S),
- false = is_empty(S),
+ false = is_empty(Mod, S),
true = Mod:is_set(S),
S.
-del_element(El, S0) ->
+del_element(Mod, El, S0) ->
S = Mod:del_element(El, S0),
false = Mod:is_element(El, S),
true = Mod:is_set(S),
S.
-size(S) ->
- Mod:size(S).
-
-is_empty(S) ->
+is_empty(Mod, S) ->
true = Mod:is_set(S),
case erlang:function_exported(Mod, is_empty, 1) of
true -> Mod:is_empty(S);
false -> Mod:size(S) == 0
end.
-is_set(S) ->
- Mod:is_set(S).
-
-intersection(S1, S2) ->
+intersection(Mod, Equal, S1, S2) ->
S = Mod:intersection(S1, S2),
true = Equal(S, Mod:intersection(S2, S1)),
- Disjoint = is_empty(S),
+ Disjoint = is_empty(Mod, S),
Disjoint = Mod:is_disjoint(S1, S2),
Disjoint = Mod:is_disjoint(S2, S1),
S.
-intersection(Ss) ->
+intersection(Mod, Equal, Ss) ->
S = Mod:intersection(Ss),
true = Equal(S, Mod:intersection(lists:reverse(Ss))),
S.
-subtract(S1, S2) ->
+subtract(Mod, S1, S2) ->
S = Mod:subtract(S1, S2),
true = Mod:is_set(S),
true = Mod:size(S) =< Mod:size(S1),
S.
-union(S1, S2) ->
+union(Mod, Equal, S1, S2) ->
S = Mod:union(S1, S2),
true = Equal(S, Mod:union(S2, S1)),
true = Mod:is_set(S),
S.
-union(Ss) ->
+union(Mod, Equal, Ss) ->
S = Mod:union(Ss),
true = Equal(S, Mod:union(lists:reverse(Ss))),
S.
-is_subset(S, Set) ->
+is_subset(Mod, Equal, S, Set) ->
case Mod:is_subset(S, Set) of
false -> false;
true ->
@@ -115,10 +113,10 @@ is_subset(S, Set) ->
true
end.
-fold(F, A, S) ->
+fold(Mod, F, A, S) ->
true = Mod:is_set(S),
Mod:fold(F, A, S).
-filter(F, S) ->
+filter(Mod, F, S) ->
true = Mod:is_set(S),
Mod:filter(F, S).
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index abc85364d0..1d3394e0ca 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -20,9 +20,6 @@
-define(DEFAULT_TIMETRAP_SECS, 60).
-%%% START %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([start/1,start/2]).
-
%%% TEST_SERVER_CTRL INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([run_test_case_apply/1,init_target_info/0,init_purify/0]).
-export([cover_compile/1,cover_analyse/3]).
@@ -60,49 +57,11 @@
-export([]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--record(state,{controller,jobs=[]}).
-
-include("test_server_internal.hrl").
-include_lib("kernel/include/file.hrl").
-define(pl2a(M), test_server_sup:package_atom(M)).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%
-%% **** START *** CODE FOR REMOTE TARGET ONLY ***
-%%
-%% test_server
-%% This process is started only if the test is to be run on a remote target
-%% The process is then started on target
-%% A socket connection is established with the test_server_ctrl process
-%% on host, and information about target is sent to host.
-start([ControllerHost]) when is_atom(ControllerHost) ->
- start(atom_to_list(ControllerHost));
-start(ControllerHost) when is_list(ControllerHost) ->
- start(ControllerHost,?MAIN_PORT).
-start(ControllerHost,ControllerPort) ->
- S = self(),
- Pid = spawn(fun() -> init(ControllerHost,ControllerPort,S) end),
- receive {Pid,started} -> {ok,Pid};
- {Pid,Error} -> Error
- end.
-
-init(Host,Port,Starter) ->
- global:register_name(?MODULE,self()),
- process_flag(trap_exit,true),
- test_server_sup:cleanup_crash_dumps(),
- case gen_tcp:connect(Host,Port, [binary,
- {reuseaddr,true},
- {packet,2}]) of
- {ok,MainSock} ->
- Starter ! {self(),started},
- request(MainSock,{target_info,init_target_info()}),
- loop(#state{controller={Host,MainSock}});
- Error ->
- Starter ! {self(),{error,
- {could_not_contact_controller,Error}}}
- end.
-
init_target_info() ->
[$.|Emu] = code:objfile_extension(),
{_, OTPRel} = init:script_id(),
@@ -118,171 +77,10 @@ init_target_info() ->
username=test_server_sup:get_username(),
cookie=atom_to_list(erlang:get_cookie())}.
-
-loop(#state{controller={_,MainSock}} = State) ->
- receive
- {tcp, MainSock, <<1,Request/binary>>} ->
- State1 = decode_main(binary_to_term(Request),State),
- loop(State1);
- {tcp_closed, MainSock} ->
- gen_tcp:close(MainSock),
- halt();
- {'EXIT',Pid,Reason} ->
- case lists:keysearch(Pid,1,State#state.jobs) of
- {value,{Pid,Name}} ->
- case Reason of
- normal -> ignore;
- _other -> request(MainSock,{job_proc_killed,Name,Reason})
- end,
- NewJobs = lists:keydelete(Pid,1,State#state.jobs),
- loop(State#state{jobs = NewJobs});
- false ->
- loop(State)
- end
- end.
-
-%% Decode request on main socket
-decode_main({job,Port,Name},#state{controller={Host,_},jobs=Jobs}=State) ->
- S = self(),
- NewJob = spawn_link(fun() -> job(Host,Port,S) end),
- receive {NewJob,started} -> State#state{jobs=[{NewJob,Name}|Jobs]};
- {NewJob,_Error} -> State
- end.
-
init_purify() ->
purify_new_leaks().
-%% Temporary job process on target
-%% This process will live while all test cases in the job are executed.
-%% A socket connection is established with the job process on host.
-job(Host,Port,Starter) ->
- process_flag(trap_exit,true),
- init_purify(),
- case gen_tcp:connect(Host,Port, [binary,
- {reuseaddr,true},
- {packet,4},
- {active,false}]) of
- {ok,JobSock} ->
- Starter ! {self(),started},
- job(JobSock);
- Error ->
- Starter ! {self(),{error,
- {could_not_contact_controller,Error}}}
- end.
-
-job(JobSock) ->
- JobDir = get_jobdir(),
- ok = file:make_dir(JobDir),
- ok = file:make_dir(filename:join(JobDir,?priv_dir)),
- put(test_server_job_sock,JobSock),
- put(test_server_job_dir,JobDir),
- {ok,Cwd} = file:get_cwd(),
- job_loop(JobSock),
- ok = file:set_cwd(Cwd),
- send_privdir(JobDir,JobSock), % also recursively removes jobdir
- ok.
-
-
-get_jobdir() ->
- Now = now(),
- {{Y,M,D},{H,Mi,S}} = calendar:now_to_local_time(Now),
- Basename = io_lib:format("~w-~2.2.0w-~2.2.0w_~2.2.0w.~2.2.0w.~2.2.0w_~w",
- [Y,M,D,H,Mi,S,element(3,Now)]),
- %% if target has a file master, don't use prim_file to look up cwd
- case lists:keymember(master,1,init:get_arguments()) of
- true ->
- {ok,Cwd} = file:get_cwd(),
- Cwd ++ "/" ++ Basename;
- false ->
- filename:absname(Basename)
- end.
-
-send_privdir(JobDir,JobSock) ->
- LocalPrivDir = filename:join(JobDir,?priv_dir),
- case file:list_dir(LocalPrivDir) of
- {ok,List} when List/=[] ->
- Tarfile0 = ?priv_dir ++ ".tar.gz",
- Tarfile = filename:join(JobDir,Tarfile0),
- {ok,Tar} = erl_tar:open(Tarfile,[write,compressed,cooked]),
- ok = erl_tar:add(Tar,LocalPrivDir,?priv_dir,[]),
- ok = erl_tar:close(Tar),
- {ok,TarBin} = file:read_file(Tarfile),
- file:delete(Tarfile),
- ok = del_dir(JobDir),
- request(JobSock,{{privdir,Tarfile0},TarBin});
- _ ->
- ok = del_dir(JobDir),
- request(JobSock,{privdir,empty_priv_dir})
- end.
-
-del_dir(Dir) ->
- case file:read_file_info(Dir) of
- {ok,#file_info{type=directory}} ->
- {ok,Cont} = file:list_dir(Dir),
- lists:foreach(fun(F) -> del_dir(filename:join(Dir,F)) end, Cont),
- ok = file:del_dir(Dir);
- {ok,#file_info{}} ->
- ok = file:delete(Dir);
- _r ->
- %% This might be a symlink - let's try to delete it!
- catch file:delete(Dir),
- ok
- end.
-
-%%
-%% Receive and decode request on job socket
-%%
-job_loop(JobSock) ->
- Request = recv(JobSock),
- case decode_job(Request) of
- ok -> job_loop(JobSock);
- {stop,R} -> R
- end.
-
-decode_job({{beam,Mod,Which},Beam}) ->
- % FIXME, shared directory structure on host and target required,
- % "Library beams" are not loaded from HOST... /Patrik
- code:add_patha(filename:dirname(Which)),
- % End of Patriks uglyness...
- {module,Mod} = code:load_binary(Mod,Which,Beam),
- ok;
-decode_job({{datadir,Tarfile0},Archive}) ->
- JobDir = get(test_server_job_dir),
- Tarfile = filename:join(JobDir,Tarfile0),
- ok = file:write_file(Tarfile,Archive),
- % Cooked is temporary removed/broken
- % ok = erl_tar:extract(Tarfile,[compressed,{cwd,JobDir},cooked]),
- ok = erl_tar:extract(Tarfile,[compressed,{cwd,JobDir}]),
- ok = file:delete(Tarfile),
- ok;
-decode_job({test_case,Case}) ->
- Result = run_test_case_apply(Case),
- JobSock = get(test_server_job_sock),
- request(JobSock,{test_case_result,Result}),
- case test_server_sup:tar_crash_dumps() of
- {error,no_crash_dumps} -> request(JobSock,{crash_dumps,no_crash_dumps});
- {ok,TarFile} ->
- {ok,TarBin} = file:read_file(TarFile),
- file:delete(TarFile),
- request(JobSock,{{crash_dumps,filename:basename(TarFile)},TarBin})
- end,
- ok;
-decode_job({sync_apply,{M,F,A}}) ->
- R = apply(M,F,A),
- request(get(test_server_job_sock),{sync_result,R}),
- ok;
-decode_job(job_done) ->
- {stop,stopped}.
-
-%%
-%% **** STOP *** CODE FOR REMOTE TARGET ONLY ***
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% cover_compile({App,Include,Exclude,Cross}) ->
%% {ok,AnalyseModules} | {error,Reason}
@@ -606,33 +404,6 @@ run_test_case_apply({CaseNum,Mod,Func,Args,Name,
DetFail = get(test_server_detected_fail),
{Result,DetFail,ProcBef,ProcAft}.
-run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
- case get(test_server_job_dir) of
- undefined ->
- %% i'm a local target
- do_run_test_case_apply(Mod, Func, Args, Name, RunInit,
- TimetrapData);
- JobDir ->
- %% i'm a remote target
- case Args of
- [Config] when is_list(Config) ->
- {value,{data_dir,HostDataDir}} =
- lists:keysearch(data_dir, 1, Config),
- DataBase = filename:basename(HostDataDir),
- TargetDataDir = filename:join(JobDir, DataBase),
- Config1 = lists:keyreplace(data_dir, 1, Config,
- {data_dir,TargetDataDir}),
- TargetPrivDir = filename:join(JobDir, ?priv_dir),
- Config2 = lists:keyreplace(priv_dir, 1, Config1,
- {priv_dir,TargetPrivDir}),
- do_run_test_case_apply(Mod, Func, [Config2], Name, RunInit,
- TimetrapData);
- _other ->
- do_run_test_case_apply(Mod, Func, Args, Name, RunInit,
- TimetrapData)
- end
- end.
-
-type tc_status() :: 'starting' | 'running' | 'init_per_testcase' |
'end_per_testcase' | {'framework',atom(),atom()} |
'tc'.
@@ -649,7 +420,7 @@ run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
end_conf_pid :: pid() | 'undefined'
}).
-do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
+run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
{ok,Cwd} = file:get_cwd(),
Args2Print = case Args of
[Args1] when is_list(Args1) ->
@@ -1540,10 +1311,10 @@ fw_error_notify(Mod, Func, Args, Error, Loc) ->
%% is directed to console, major and/or minor log files.
print(Detail,Format,Args) ->
- local_or_remote_apply({test_server_ctrl,print,[Detail,Format,Args]}).
+ test_server_ctrl:print(Detail, Format, Args).
print(Detail,Format,Args,Printer) ->
- local_or_remote_apply({test_server_ctrl,print,[Detail,Format,Args,Printer]}).
+ test_server_ctrl:print(Detail, Format, Args, Printer).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% print_timsteamp(Detail,Leader) -> ok
@@ -1553,7 +1324,7 @@ print(Detail,Format,Args,Printer) ->
%% log files.
print_timestamp(Detail,Leader) ->
- local_or_remote_apply({test_server_ctrl,print_timestamp,[Detail,Leader]}).
+ test_server_ctrl:print_timestamp(Detail, Leader).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2683,7 +2454,7 @@ make_priv_dir() ->
%% Returns the OsType of the target node. OsType is
%% the same as returned from os:type()
os_type() ->
- test_server_ctrl:get_target_os_type().
+ os:type().
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2802,47 +2573,9 @@ purify_format(Format, Args) ->
%%
%% Generic send functions for communication with host
%%
-sync_local_or_remote_apply(Proxy,From,{M,F,A} = MFA) ->
- case get(test_server_job_sock) of
- undefined ->
- %% i'm a local target
- Result = apply(M,F,A),
- if is_pid(Proxy) -> Proxy ! {sync_result_proxy,From,Result};
- true -> From ! {sync_result,Result}
- end;
- JobSock ->
- %% i'm a remote target
- request(JobSock,{sync_apply,MFA}),
- {sync_result,Result} = recv(JobSock),
- if is_pid(Proxy) -> Proxy ! {sync_result_proxy,From,Result};
- true -> From ! {sync_result,Result}
- end
- end.
-local_or_remote_apply({M,F,A} = MFA) ->
- case get(test_server_job_sock) of
- undefined ->
- %% i'm a local target
- apply(M,F,A),
- ok;
- JobSock ->
- %% i'm a remote target
- request(JobSock,{apply,MFA}),
- ok
- end.
-
-request(Sock,Request) ->
- gen_tcp:send(Sock,<<1,(term_to_binary(Request))/binary>>).
-
-%%
-%% Generic receive function for communication with host
-%%
-recv(Sock) ->
- case gen_tcp:recv(Sock,0) of
- {error,closed} ->
- gen_tcp:close(Sock),
- exit(connection_lost);
- {ok,<<1,Request/binary>>} ->
- binary_to_term(Request);
- {ok,<<0,B/binary>>} ->
- B
+sync_local_or_remote_apply(Proxy, From, {M,F,A}) ->
+ %% i'm a local target
+ Result = apply(M, F, A),
+ if is_pid(Proxy) -> Proxy ! {sync_result_proxy,From,Result};
+ true -> From ! {sync_result,Result}
end.
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index fe9ee003d1..7b2ebcefc0 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -34,118 +34,6 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% ARCHITECTURE
-%%
-%% The Erlang Test Server can be run on the target machine (local target)
-%% or towards a remote target. The execution flow is mainly the same in
-%% both cases, but with a remote target the test cases are (obviously)
-%% executed on the target machine. Host and target communicates over
-%% socket connections because the host should not be introduced as an
-%% additional node in the distributed erlang system in which the test
-%% cases are run.
-%%
-%%
-%% Local Target:
-%% =============
-%%
-%% -----
-%% | | test_server_ctrl ({global,test_server})
-%% ----- (test_server_ctrl.erl)
-%% |
-%% |
-%% -----
-%% | | JobProc
-%% ----- (test_server_ctrl.erl and test_server.erl)
-%% |
-%% |
-%% -----
-%% | | CaseProc
-%% ----- (test_server.erl)
-%%
-%%
-%%
-%% test_server_ctrl is the main process in the system. It is a registered
-%% process, and it will always be alive when testing is ongoing.
-%% test_server_ctrl initiates testing and monitors JobProc(s).
-%%
-%% When target is local, and Test Server is *not* being used by a framework
-%% application (where it might cause duplicate name problems in a distributed
-%% test environment), the process is globally registered as 'test_server'
-%% to be able to simulate the {global,test_server} process on a remote target.
-%%
-%% JobProc is spawned for each 'job' added to the test_server_ctrl.
-%% A job can mean one test case, one test suite or one spec.
-%% JobProc creates and writes logs and presents results from testing.
-%% JobProc is the group leader for CaseProc.
-%%
-%% CaseProc is spawned for each test case. It runs the test case and
-%% sends results and any other information to its group leader - JobProc.
-%%
-%%
-%%
-%% Remote Target:
-%% ==============
-%%
-%% HOST TARGET
-%%
-%% ----- MainSock -----
-%% test_server_ctrl | |- - - - - - -| | {global,test_server}
-%% (test_server_ctrl.erl) ----- ----- (test_server.erl)
-%% | |
-%% | |
-%% ----- JobSock -----
-%% JobProcH | |- - - - - - -| | JobProcT
-%% (test_server_ctrl.erl) ----- ----- (test_server.erl)
-%% |
-%% |
-%% -----
-%% | | CaseProc
-%% ----- (test_server.erl)
-%%
-%%
-%%
-%%
-%% A separate test_server process only exists when target is remote. It
-%% is then the main process on target. It is started when test_server_ctrl
-%% is started, and a socket connection is established between
-%% test_server_ctrl and test_server. The following information can be sent
-%% over MainSock:
-%%
-%% HOST TARGET
-%% -> {target_info, TargetInfo} (during initiation)
-%% <- {job_proc_killed,Name,Reason} (if a JobProcT dies unexpectedly)
-%% -> {job,Port,Name} (to start a new JobProcT)
-%%
-%%
-%% When target is remote, JobProc is split into to processes: JobProcH
-%% executing on Host and JobProcT executing on Target. (The two processes
-%% execute the same code as JobProc does when target is local.) JobProcH
-%% and JobProcT communicates over a socket connection. The following
-%% information can be sent over JobSock:
-%%
-%% HOST TARGET
-%% -> {test_case, Case} To start a new test case
-%% -> {beam,Mod} .beam file as binary to be loaded
-%% on target, e.g. a test suite
-%% -> {datadir,Tarfile} Content of the datadir for a test suite
-%% <- {apply,MFA} MFA to be applied on host, ignore return;
-%% (apply is used for printing information in
-%% log or console)
-%% <- {sync_apply,MFA} MFA to be applied on host, wait for return
-%% (used for starting and stopping slave nodes)
-%% -> {sync_apply,MFA} MFA to be applied on target, wait for return
-%% (used for cover compiling and analysing)
-%% <-> {sync_result,Result} Return value from sync_apply
-%% <- {test_case_result,Result} When a test case is finished
-%% <- {crash_dumps,Tarfile} When a test case is finished
-%% -> job_done When a job is finished
-%% <- {privdir,Privdir} When a job is finished
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-
%%% SUPERVISOR INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([start/0, start/1, start_link/1, stop/0]).
@@ -177,7 +65,6 @@
-export([format/1, format/2, format/3, to_string/1]).
-export([get_target_info/0]).
-export([get_hosts/0]).
--export([get_target_os_type/0]).
-export([node_started/1]).
%%% DEBUGGER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -536,20 +423,6 @@ kill_slavenodes() ->
get_hosts() ->
get(test_server_hosts).
-get_target_os_type() ->
- case whereis(?MODULE) of
- undefined ->
- %% This is probably called on the target node
- os:type();
- Pid when Pid =:= self() ->
- os:type();
- _pid ->
- %% This is called on the controller, e.g. from a
- %% specification clause of a test case
- #target_info{os_type=OsType} = controller_call(get_target_info),
- OsType
- end.
-
%%--------------------------------------------------------------------
add_job(Name, TopCase) ->
@@ -605,7 +478,7 @@ controller_call(Arg, Timeout) ->
%% Mode 'lazy' ignores (and resets to []) any jobs in the state file
%%
-init([Param]) ->
+init([_]) ->
case os:getenv("TEST_SERVER_CALL_TRACE") of
false ->
ok;
@@ -631,104 +504,14 @@ init([Param]) ->
test_server_sup:cleanup_crash_dumps(),
State = #state{jobs=[],finish=false},
put(test_server_free_targets,[]),
- case contact_main_target(Param) of
- {ok,TI} ->
- ets:new(slave_tab, [named_table,set,public,{keypos,2}]),
- set_hosts([TI#target_info.host]),
- {ok,State#state{target_info=TI}};
- {error,Reason} ->
- {stop,Reason}
- end.
-
-
-%% If the test is to be run at a remote target, this function sets up
-%% a socket communication with the target.
-contact_main_target(local) ->
- %% When used by a general framework, global registration of
- %% test_server should not be required.
- case get_fw_mod(undefined) of
- undefined ->
- %% Local target! The global test_server process implemented by
- %% test_server.erl will not be started, so we simulate it by
- %% globally registering this process instead.
- global:sync(),
- case global:whereis_name(test_server) of
- undefined ->
- global:register_name(test_server, self());
- Pid ->
- case node() of
- N when N == node(Pid) ->
- io:format(user, "Warning: test_server already running!\n", []),
- global:re_register_name(test_server,self());
- _ ->
- ok
- end
- end;
- _ ->
- ok
- end,
- TI = test_server:init_target_info(),
+ TI0 = test_server:init_target_info(),
TargetHost = test_server_sup:hoststr(),
- {ok,TI#target_info{where=local,
- host=TargetHost,
- naming=naming(),
- master=TargetHost}};
-
-contact_main_target(ParameterFile) ->
- case read_parameters(ParameterFile) of
- {ok,Par} ->
- case test_server_node:start_remote_main_target(Par) of
- {ok,TI} ->
- {ok,TI};
- {error,Error} ->
- {error,{could_not_start_main_target,Error}}
- end;
- {error,Error} ->
- {error,{could_not_read_parameterfile,Error}}
- end.
-
-read_parameters(File) ->
- case file:consult(File) of
- {ok,Data} ->
- read_parameters(lists:flatten(Data), #par{naming=naming()});
- Error ->
- Error
- end.
-read_parameters([{type,Type}|Data], Par) -> % mandatory
- read_parameters(Data, Par#par{type=Type});
-read_parameters([{target,Target}|Data], Par) -> % mandatory
- read_parameters(Data, Par#par{target=cast_to_list(Target)});
-read_parameters([{slavetargets,SlaveTargets}|Data], Par) ->
- read_parameters(Data, Par#par{slave_targets=SlaveTargets});
-read_parameters([{longnames,Bool}|Data], Par) ->
- Naming = if Bool->"-name"; true->"-sname" end,
- read_parameters(Data, Par#par{naming=Naming});
-read_parameters([{master,{Node,Cookie}}|Data], Par) ->
- read_parameters(Data, Par#par{master=cast_to_list(Node),
- cookie=cast_to_list(Cookie)});
-read_parameters([Other|_Data], _Par) ->
- {error,{illegal_parameter,Other}};
-read_parameters([], Par) when Par#par.type==undefined ->
- {error, {missing_mandatory_parameter,type}};
-read_parameters([], Par) when Par#par.target==undefined ->
- {error, {missing_mandatory_parameter,target}};
-read_parameters([], Par0) ->
- Par =
- case {Par0#par.type, Par0#par.master} of
- {ose, undefined} ->
- %% Use this node as master and bootserver for target
- %% and slave nodes
- Par0#par{master = atom_to_list(node()),
- cookie = atom_to_list(erlang:get_cookie())};
- {ose, _Master} ->
- %% Master for target and slave nodes was defined in parameterfile
- Par0;
- _ ->
- %% Use target as master for slave nodes,
- %% (No master is used for target)
- Par0#par{master="test_server@" ++ Par0#par.target}
- end,
- {ok,Par}.
+ TI = TI0#target_info{host=TargetHost,
+ naming=naming(),
+ master=TargetHost},
+ ets:new(slave_tab, [named_table,set,public,{keypos,2}]),
+ set_hosts([TI#target_info.host]),
+ {ok,State#state{target_info=TI}}.
naming() ->
case lists:member($., test_server_sup:hoststr()) of
@@ -1209,25 +992,17 @@ handle_cast({node_started,Node}, State) ->
%% Pid = pid()
%% Reason = term()
%%
-%% Handles exit messages from linked processes. Only test suites and
-%% possibly a target client are expected to be linked.
-%% When a test suite terminates, it is removed from the job queue.
-%% If a target client terminates it means that we lost contact with
-%% target. The test_server_ctrl process is terminated, and teminate/2
-%% will do the cleanup
+%% Handles exit messages from linked processes. Only test suites are
+%% expected to be linked. When a test suite terminates, it is removed
+%% from the job queue. If a target client terminates it means that we
+%% lost contact with target. The test_server_ctrl process is
+%% terminated, and teminate/2 will do the cleanup
handle_info({'EXIT',Pid,Reason}, State) ->
case lists:keysearch(Pid,2,State#state.jobs) of
false ->
- TI = State#state.target_info,
- case TI#target_info.target_client of
- Pid ->
- %% The target client died - lost contact with target
- {stop,{lost_contact_with_target,Reason},State};
- _other ->
- %% not our problem
- {noreply,State}
- end;
+ %% not our problem
+ {noreply,State};
{value,{Name,_}} ->
NewJobs = lists:keydelete(Pid, 2, State#state.jobs),
case Reason of
@@ -1302,14 +1077,8 @@ handle_info({tcp_closed,Sock}, State=#state{trc=Sock}) ->
%%! Maybe print something???
{noreply,State#state{trc=false}};
handle_info({tcp_closed,Sock}, State) ->
- case test_server_node:nodedown(Sock,State#state.target_info) of
- target_died ->
- %% terminate/2 will do the cleanup
- {stop,target_died,State};
- _ ->
- {noreply,State}
- end;
-
+ test_server_node:nodedown(Sock, State#state.target_info),
+ {noreply,State};
handle_info(_, State) ->
%% dummy; accept all, do nothing.
{noreply, State}.
@@ -2318,9 +2087,7 @@ do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod) ->
%% Runs the specified tests, then displays/logs the summary.
run_test_cases(TestSpec, Config, TimetrapData) ->
-
- maybe_open_job_sock(),
-
+ test_server:init_purify(),
case lists:member(no_src, get(test_server_logopts)) of
true ->
ok;
@@ -2330,8 +2097,6 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
run_test_cases_loop(TestSpec, [Config], TimetrapData, [], []),
- maybe_get_privdir(),
-
{AllSkippedN,UserSkipN,AutoSkipN,SkipStr} =
case get(test_server_skipped) of
{0,0} -> {0,0,0,""};
@@ -2350,41 +2115,6 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
print(major, "=auto_skipped ~p", [AutoSkipN]),
exit(test_suites_done).
-%% If the test is run at a remote target, this function sets up a socket
-%% communication with the target for handling this particular job.
-maybe_open_job_sock() ->
- TI = get_target_info(),
- case TI#target_info.where of
- local ->
- %% local target
- test_server:init_purify();
- MainSock ->
- %% remote target
- {ok,LSock} = gen_tcp:listen(0, [binary,
- {reuseaddr,true},
- {packet,4},
- {active,false}]),
- {ok,Port} = inet:port(LSock),
- request(MainSock, {job,Port,get(test_server_name)}),
- case gen_tcp:accept(LSock, ?ACCEPT_TIMEOUT) of
- {ok,Sock} -> put(test_server_ctrl_job_sock, Sock);
- {error,Reason} -> exit({no_contact,Reason})
- end
- end.
-
-%% If the test is run at a remote target, this function waits for a
-%% tar packet containing the privdir created by the test case.
-maybe_get_privdir() ->
- case get(test_server_ctrl_job_sock) of
- undefined ->
- %% local target
- ok;
- Sock ->
- %% remote target
- request(Sock, job_done),
- gen_tcp:close(Sock)
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% run_test_cases_loop(TestCases, Config, TimetrapData, Mode, Status) -> ok
@@ -2899,7 +2629,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
end,
CurrMode = curr_mode(Ref, Mode0, Mode),
- ConfCaseResult = run_test_case(Ref, 0, Mod, Func, [ActualCfg], skip_init, target,
+ ConfCaseResult = run_test_case(Ref, 0, Mod, Func, [ActualCfg], skip_init,
TimetrapData, CurrMode),
case ConfCaseResult of
@@ -3023,7 +2753,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
end;
run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData, Mode, Status) ->
- case run_test_case(Ref, 0, Mod, Func, Args, skip_init, host, TimetrapData) of
+ case run_test_case(Ref, 0, Mod, Func, Args, skip_init, TimetrapData) of
{_,Why={'EXIT',_},_} ->
print(minor, "~n*** ~p failed.~n"
" Skipping all cases.", [Func]),
@@ -3068,7 +2798,7 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
end,
case run_test_case(undefined, Num+1, Mod, Func, Args,
- run_init, target, TimetrapData, Mode) of
+ run_init, TimetrapData, Mode) of
%% callback to framework module failed, exit immediately
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
print(minor, "~n*** ~p failed in ~p. Reason: ~p~n", [FwMod,FwFunc,Reason]),
@@ -3762,23 +3492,23 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) ->
%% RetVal is the result of executing the test case. It contains info
%% about the execution time and the return value of the test case function.
-run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, TimetrapData) ->
+run_test_case(Ref, Num, Mod, Func, Args, RunInit, TimetrapData) ->
file:set_cwd(filename:dirname(get(test_server_dir))),
- run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
+ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
TimetrapData, [], self()).
-run_test_case(Ref, Num, Mod, Func, Args, skip_init, Where, TimetrapData, Mode) ->
+run_test_case(Ref, Num, Mod, Func, Args, skip_init, TimetrapData, Mode) ->
%% a conf case is always executed by the main process
- run_test_case1(Ref, Num, Mod, Func, Args, skip_init, Where,
+ run_test_case1(Ref, Num, Mod, Func, Args, skip_init,
TimetrapData, Mode, self());
-run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, TimetrapData, Mode) ->
+run_test_case(Ref, Num, Mod, Func, Args, RunInit, TimetrapData, Mode) ->
file:set_cwd(filename:dirname(get(test_server_dir))),
Main = self(),
case check_prop(parallel, Mode) of
false ->
%% this is a sequential test case
- run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
+ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
TimetrapData, Mode, Main);
_Ref ->
%% this a parallel test case, spawn the new process
@@ -3790,11 +3520,11 @@ run_test_case(Ref, Num, Mod, Func, Args, RunInit, Where, TimetrapData, Mode) ->
[put(Key, Val) || {Key,Val} <- Dictionary],
set_io_buffering({tc,Main}),
run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
- Where, TimetrapData, Mode, Main)
+ TimetrapData, Mode, Main)
end)
end.
-run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
+run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
TimetrapData, Mode, Main) ->
group_leader(test_server_io:get_gl(Main == self()), self()),
@@ -3807,12 +3537,6 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
Main ! {started,Ref,self(),Num,Mod,Func}
end,
TSDir = get(test_server_dir),
- case Where of
- target ->
- maybe_send_beam_and_datadir(Mod);
- host ->
- ok
- end,
print(major, "=case ~p:~p", [Mod, Func]),
MinorName = start_minor_log_file(Mod, Func),
@@ -3870,7 +3594,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
%% run the test case
{Result,DetectedFail,ProcsBefore,ProcsAfter} =
run_test_case_apply(Num, Mod, Func, [UpdatedArgs], get_name(Mode),
- RunInit, Where, TimetrapData),
+ RunInit, TimetrapData),
{Time,RetVal,Loc,Opts,Comment} =
case Result of
Normal={_Time,_RetVal,_Loc,_Opts,_Comment} -> Normal;
@@ -3987,7 +3711,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
true ->
ok
end,
- check_new_crash_dumps(Where),
+ test_server_sup:check_new_crash_dumps(),
%% if io is being buffered, send finished message
%% (no matter if case runs on parallel or main process)
@@ -4015,109 +3739,6 @@ do_unless_parallel(Main, Action) when is_function(Action, 0) ->
num2str(0) -> "";
num2str(N) -> integer_to_list(N).
-%% If remote target, this function sends the test suite (if not already sent)
-%% and the content of datadir til target.
-maybe_send_beam_and_datadir(Mod) ->
- case get(test_server_ctrl_job_sock) of
- undefined ->
- %% local target
- ok;
- JobSock ->
- %% remote target
- case get(test_server_downloaded_suites) of
- undefined ->
- send_beam_and_datadir(Mod, JobSock),
- put(test_server_downloaded_suites, [Mod]);
- Suites ->
- case lists:member(Mod, Suites) of
- false ->
- send_beam_and_datadir(Mod, JobSock),
- put(test_server_downloaded_suites, [Mod|Suites]);
- true ->
- ok
- end
- end
- end.
-
-send_beam_and_datadir(Mod, JobSock) ->
- case code:which(Mod) of
- non_existing ->
- io:format("** WARNING: Suite ~w could not be found on host\n",
- [Mod]);
- BeamFile ->
- send_beam(JobSock, Mod, BeamFile)
- end,
- DataDir = get_data_dir(Mod),
- case file:read_file_info(DataDir) of
- {ok,_I} ->
- {ok,All} = file:list_dir(DataDir),
- AddTarFiles =
- case controller_call(get_target_info) of
- #target_info{os_family=ose} ->
- ObjExt = code:objfile_extension(),
- Wc = filename:join(DataDir, "*" ++ ObjExt),
- ModsInDatadir = filelib:wildcard(Wc),
- SendBeamFun = fun(X) -> send_beam(JobSock, X) end,
- lists:foreach(SendBeamFun, ModsInDatadir),
- %% No need to send C code or makefiles since
- %% no compilation can be done on target anyway.
- %% Compiled C code must exist on target.
- %% Beam files are already sent as binaries.
- %% Erlang source are sent in case the test case
- %% is to compile it.
- Filter = fun("Makefile") -> false;
- ("Makefile.src") -> false;
- (Y) ->
- case filename:extension(Y) of
- ".c" -> false;
- ObjExt -> false;
- _ -> true
- end
- end,
- lists:filter(Filter, All);
- _ ->
- All
- end,
- Tarfile = "data_dir.tar.gz",
- {ok,Tar} = erl_tar:open(Tarfile, [write,compressed]),
- ShortDataDir = filename:basename(DataDir),
- AddTarFun =
- fun(File) ->
- Long = filename:join(DataDir, File),
- Short = filename:join(ShortDataDir, File),
- ok = erl_tar:add(Tar, Long, Short, [])
- end,
- lists:foreach(AddTarFun, AddTarFiles),
- ok = erl_tar:close(Tar),
- {ok,TarBin} = file:read_file(Tarfile),
- file:delete(Tarfile),
- request(JobSock, {{datadir,Tarfile}, TarBin});
- {error,_R} ->
- ok
- end.
-
-send_beam(JobSock, BeamFile) ->
- Mod=filename:rootname(filename:basename(BeamFile), code:objfile_extension()),
- send_beam(JobSock, list_to_atom(Mod), BeamFile).
-send_beam(JobSock, Mod, BeamFile) ->
- {ok,BeamBin} = file:read_file(BeamFile),
- request(JobSock, {{beam,Mod,BeamFile}, BeamBin}).
-
-check_new_crash_dumps(Where) ->
- case Where of
- target ->
- case get(test_server_ctrl_job_sock) of
- undefined ->
- ok;
- Socket ->
- read_job_sock_loop(Socket)
- end;
- _ ->
- ok
- end,
- test_server_sup:check_new_crash_dumps().
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% progress(Result, CaseNum, Mod, Func, Location, Reason, Time,
%% Comment, TimeFormat) -> Result
@@ -4485,11 +4106,10 @@ do_format_exception(Reason={Error,Stack}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit,
-%% Where, TimetrapData) ->
+%% TimetrapData) ->
%% {{Time,RetVal,Loc,Opts,Comment},DetectedFail,ProcessesBefore,ProcessesAfter} |
%% {{died,Reason,unknown,Comment},DetectedFail,ProcessesBefore,ProcessesAfter}
%% Name = atom()
-%% Where = target | host
%% Time = float() (seconds)
%% RetVal = term()
%% Loc = term()
@@ -4504,23 +4124,10 @@ do_format_exception(Reason={Error,Stack}) ->
%% sent over socket to target, and test_server runs the case and sends the
%% result back over the socket. Else test_server runs the case directly on host.
-run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, host,
+run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit,
TimetrapData) ->
test_server:run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit,
- TimetrapData});
-run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit, target,
- TimetrapData) ->
- case get(test_server_ctrl_job_sock) of
- undefined ->
- %% local target
- test_server:run_test_case_apply({CaseNum,Mod,Func,Args,Name,RunInit,
- TimetrapData});
- JobSock ->
- %% remote target
- request(JobSock, {test_case,{CaseNum,Mod,Func,Args,Name,RunInit,
- TimetrapData}}),
- read_job_sock_loop(JobSock)
- end.
+ TimetrapData}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% print(Detail, Format, Args) -> ok
@@ -5187,60 +4794,6 @@ stop_node(Slave) ->
controller_call({stop_node,Slave}).
-%%--------------------------------------------------------------------
-%% Functions handling target communication over socket
-
-%% Generic send function for communication with target
-request(Sock,Request) ->
- gen_tcp:send(Sock,<<1,(term_to_binary(Request))/binary>>).
-
-%% Receive and decode request on job specific socket
-%% Used when test is running on a remote target
-read_job_sock_loop(Sock) ->
- case gen_tcp:recv(Sock,0) of
- {error,Reason} ->
- gen_tcp:close(Sock),
- exit({controller,connection_lost,Reason});
- {ok,<<1,Request/binary>>} ->
- case decode(binary_to_term(Request)) of
- ok ->
- read_job_sock_loop(Sock);
- {stop,Result} ->
- Result
- end
- end.
-
-decode({apply,{M,F,A}}) ->
- apply(M,F,A),
- ok;
-decode({sync_apply,{M,F,A}}) ->
- R = apply(M,F,A),
- request(get(test_server_ctrl_job_sock),{sync_result,R}),
- ok;
-decode({sync_result,Result}) ->
- {stop,Result};
-decode({test_case_result,Result}) ->
- {stop,Result};
-decode({privdir,empty_priv_dir}) ->
- {stop,ok};
-decode({{privdir,PrivDirTar},TarBin}) ->
- Root = get(test_server_log_dir_base),
- unpack_tar(Root,PrivDirTar,TarBin),
- {stop,ok};
-decode({crash_dumps,no_crash_dumps}) ->
- {stop,ok};
-decode({{crash_dumps,CrashDumpTar},TarBin}) ->
- Dir = test_server_sup:crash_dump_dir(),
- unpack_tar(Dir,CrashDumpTar,TarBin),
- {stop,ok}.
-
-unpack_tar(Dir,TarFileName0,TarBin) ->
- TarFileName = filename:join(Dir,TarFileName0),
- ok = file:write_file(TarFileName,TarBin),
- ok = erl_tar:extract(TarFileName,[compressed,{cwd,Dir}]),
- ok = file:delete(TarFileName).
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% DEBUGGER INTERFACE %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -5385,16 +4938,7 @@ cover_compile({App,CoverFile}) ->
cover_compile1({App,Exclude,Include,Cross}).
cover_compile1(What) ->
- case get(test_server_ctrl_job_sock) of
- undefined ->
- %% local target
- test_server:cover_compile(What);
- JobSock ->
- %% remote target
- request(JobSock, {sync_apply,{test_server,cover_compile,[What]}}),
- read_job_sock_loop(JobSock)
- end.
-
+ test_server:cover_compile(What).
%% Read the coverfile for an application and return a list of modules
%% that are members of the application but shall not be compiled
@@ -5496,17 +5040,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
cover_analyse(Analyse, AnalyseMods, Stop) ->
TestDir = get(test_server_log_dir_base),
- case get(test_server_ctrl_job_sock) of
- undefined ->
- %% local target
- test_server:cover_analyse({Analyse,TestDir}, AnalyseMods, Stop);
- JobSock ->
- %% remote target
- request(JobSock, {sync_apply,{test_server,
- cover_analyse,
- [Analyse,AnalyseMods, Stop]}}),
- read_job_sock_loop(JobSock)
- end.
+ test_server:cover_analyse({Analyse,TestDir}, AnalyseMods, Stop).
%% Cover analysis, cross application
diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl
index b58b42805e..d204c35293 100644
--- a/lib/test_server/src/test_server_internal.hrl
+++ b/lib/test_server/src/test_server_internal.hrl
@@ -24,8 +24,7 @@
%% Target information generated by test_server:init_target_info/0 and
%% test_server_ctrl:contact_main_target/2
%% Once initiated, this information will never change!!
--record(target_info, {where, % local | Socket
- os_family, % atom(); win32 | unix
+-record(target_info, {os_family, % atom(); win32 | unix
os_type, % result of os:type()
host, % string(); the name of the target machine
version, % string()
@@ -43,7 +42,6 @@
% itself is master for slave nodes
%% The following are only used for remote targets
- target_client, % reference to a client talking to target
slave_targets=[]}).% list() of atom(); all available
% targets for starting slavenodes
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 872f15f2be..b307d93c7d 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -26,7 +26,7 @@
%% Test Controller interface
-export([is_release_available/1]).
--export([start_remote_main_target/1,stop/1]).
+-export([stop/1]).
-export([start_tracer_node/2,trace_nodes/2,stop_tracer_node/1]).
-export([start_node/5, stop_node/2]).
-export([kill_nodes/1, nodedown/2]).
@@ -57,79 +57,8 @@ is_release_available(Rel) ->
false
end.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%% Start main target node on remote host
-%%% The target node must not know the controller node via erlang distribution.
-start_remote_main_target(Parameters) ->
- #par{type=TargetType,
- target=TargetHost,
- naming=Naming,
- master=MasterNode,
- cookie=MasterCookie,
- slave_targets=SlaveTargets} = Parameters,
-
- lists:foreach(fun(T) -> maybe_reboot_target({TargetType,T}) end,
- [list_to_atom(TargetHost)|SlaveTargets]),
-
- Cmd0 = get_main_target_start_command(TargetType,TargetHost,Naming,
- MasterNode,MasterCookie),
- Cmd =
- case os:getenv("TEST_SERVER_FRAMEWORK") of
- FW when FW =:= false; FW =:= "undefined" -> Cmd0;
- FW -> Cmd0 ++ " -env TEST_SERVER_FRAMEWORK " ++ FW
- end,
-
- {ok,LSock} = gen_tcp:listen(?MAIN_PORT,[binary,{reuseaddr,true},{packet,2}]),
- case start_target(TargetType,TargetHost,Cmd) of
- {ok,TargetClient,AcceptTimeout} ->
- case gen_tcp:accept(LSock,AcceptTimeout) of
- {ok,Sock} ->
- gen_tcp:close(LSock),
- receive
- {tcp,Sock,Bin} when is_binary(Bin) ->
- case unpack(Bin) of
- error ->
- gen_tcp:close(Sock),
- close_target_client(TargetClient),
- {error,bad_message};
- {ok,{target_info,TI}} ->
- put(test_server_free_targets,SlaveTargets),
- {ok, TI#target_info{where=Sock,
- host=TargetHost,
- naming=Naming,
- master=MasterNode,
- target_client=TargetClient,
- slave_targets=SlaveTargets}}
- end;
- {tcp_closed,Sock} ->
- gen_tcp:close(Sock),
- close_target_client(TargetClient),
- {error,could_not_contact_target}
- after AcceptTimeout ->
- gen_tcp:close(Sock),
- close_target_client(TargetClient),
- {error,timeout}
- end;
- Error ->
- %%! maybe something like kill_target(...)???
- gen_tcp:close(LSock),
- close_target_client(TargetClient),
- {error,{could_not_contact_target,Error}}
- end;
- Error ->
- gen_tcp:close(LSock),
- {error,{could_not_start_target,Error}}
- end.
-
stop(TI) ->
- kill_nodes(TI),
- case TI#target_info.where of
- local -> % there is no remote target to stop
- ok;
- Sock -> % stop remote target
- gen_tcp:close(Sock),
- close_target_client(TI#target_info.target_client)
- end.
+ kill_nodes(TI).
nodedown(Sock, TI) ->
Match = #slave_info{name='$1',socket=Sock,client='$2',_='_'},
@@ -146,14 +75,8 @@ nodedown(Sock, TI) ->
false -> ok
end,
slave_died;
- [] ->
- case TI#target_info.where of
- Sock ->
- %% test_server_ctrl will do the cleanup
- target_died;
- _ ->
- ignore
- end
+ [] ->
+ ok
end.
@@ -167,10 +90,7 @@ start_tracer_node(TraceFile,TI) ->
Match = #slave_info{name='$1',_='_'},
SlaveNodes = lists:map(fun([N]) -> [" ",N] end,
ets:match(slave_tab,Match)),
- TargetNode = case TI#target_info.where of
- local -> node();
- _ -> "test_server@" ++ TI#target_info.host
- end,
+ TargetNode = node(),
Cookie = TI#target_info.cookie,
{ok,LSock} = gen_tcp:listen(0,[binary,{reuseaddr,true},{packet,2}]),
{ok,TracePort} = inet:port(LSock),
@@ -471,129 +391,29 @@ start_node_slave(SlaveName, OptList, From, TI) ->
Ret =
case start_which_node(OptList) of
{error,Reason} -> {{error,Reason},undefined,undefined};
- Host0 -> do_start_node_slave(Host0,SlaveName,Args,Prog,Cleanup,TI)
+ Host0 -> do_start_node_slave(Host0,SlaveName,Args,Prog,Cleanup)
end,
gen_server:reply(From,Ret).
-do_start_node_slave(Host0, SlaveName, Args, Prog, Cleanup, TI) ->
- case TI#target_info.where of
- local ->
- Host =
- case Host0 of
- local -> test_server_sup:hoststr();
- _ -> cast_to_list(Host0)
- end,
- Cmd = Prog ++ " " ++ Args,
- %% Can use slave.erl here because I'm both controller and target
- %% so I will ping the new node anyway
- case slave:start(Host, SlaveName, Args, no_link, Prog) of
- {ok,Nodename} ->
- case Cleanup of
- true -> ets:insert(slave_tab,#slave_info{name=Nodename});
- false -> ok
- end,
- {{ok,Nodename}, Host, Cmd, [], []};
- Ret ->
- {Ret, Host, Cmd}
- end;
-
- _Sock ->
- %% Cannot use slave.erl here because I'm only controller, and will
- %% not ping the new node. Only target shall contact the new node!!
- no_contact_start_slave(Host0,SlaveName,Args,Prog,Cleanup,TI)
- end.
-
-
-
-no_contact_start_slave(Host, Name, Args0, Prog, Cleanup,TI) ->
- Args1 = case string:str(Args0,"-setcookie") of
- 0 -> "-setcookie " ++ TI#target_info.cookie ++ " " ++ Args0;
- _ -> Args0
+do_start_node_slave(Host0, SlaveName, Args, Prog, Cleanup) ->
+ Host =
+ case Host0 of
+ local -> test_server_sup:hoststr();
+ _ -> cast_to_list(Host0)
+ end,
+ Cmd = Prog ++ " " ++ Args,
+ %% Can use slave.erl here because I'm both controller and target
+ %% so I will ping the new node anyway
+ case slave:start(Host, SlaveName, Args, no_link, Prog) of
+ {ok,Nodename} ->
+ case Cleanup of
+ true -> ets:insert(slave_tab,#slave_info{name=Nodename});
+ false -> ok
end,
- Args = TI#target_info.naming ++ " " ++ cast_to_list(Name) ++ " " ++ Args1,
- case Host of
- local ->
- case get(test_server_free_targets) of
- [] ->
- io:format("Starting slave ~p on HOST~n", [Name]),
- TargetType = test_server_sup:get_os_family(),
- Cmd0 = get_slave_node_start_command(TargetType,
- Prog,
- TI#target_info.master),
- Cmd = Cmd0 ++ " " ++ Args,
- do_no_contact_start_slave(TargetType,
- test_server_sup:hoststr(),
- Cmd, Cleanup,TI, false);
- [H|T] ->
- TargetType = TI#target_info.os_family,
- Cmd0 = get_slave_node_start_command(TargetType,
- Prog,
- TI#target_info.master),
- Cmd = Cmd0 ++ " " ++ Args,
- case do_no_contact_start_slave(TargetType,H,Cmd,Cleanup,
- TI,true) of
- {error,remove} ->
- io:format("Cannot start node on ~p, "
- "removing from slave "
- "target list.", [H]),
- put(test_server_free_targets,T),
- no_contact_start_slave(Host,Name,Args,Prog,
- Cleanup,TI);
- {error,keep} ->
- %% H is added to the END OF THE LIST
- %% in order to avoid the same target to
- %% be selected each time
- put(test_server_free_targets,T++[H]),
- no_contact_start_slave(Host,Name,Args,Prog,
- Cleanup,TI);
- R ->
- put(test_server_free_targets,T),
- R
- end
- end;
- _ ->
- TargetType = TI#target_info.os_family,
- Cmd0 = get_slave_node_start_command(TargetType,
- Prog,
- TI#target_info.master),
- Cmd = Cmd0 ++ " " ++ Args,
- do_no_contact_start_slave(TargetType, Host, Cmd, Cleanup, TI, false)
- end.
-
-do_no_contact_start_slave(TargetType,Host0,Cmd0,Cleanup,TI,Retry) ->
- %% Must use TargetType instead of TI#target_info.os_familiy here
- %% because if there were no free_targets we will be starting the
- %% slave node on host which might have a different os_familiy
- Host = cast_to_list(Host0),
- {ok,LSock} = gen_tcp:listen(0,[binary,
- {reuseaddr,true},
- {packet,2}]),
- {ok,WaitPort} = inet:port(LSock),
- Cmd = lists:concat([Cmd0, " -s ", ?MODULE, " node_started ",
- test_server_sup:hoststr(), " ", WaitPort]),
-
- case start_target(TargetType,Host,Cmd) of
- {ok,Client,AcceptTimeout} ->
- case wait_for_node_started(LSock,AcceptTimeout,
- Client,Cleanup,TI,self()) of
- {error,_}=WaitError ->
- if Retry ->
- case maybe_reboot_target(Client) of
- {error,_} -> {error,remove};
- ok -> {error,keep}
- end;
- true ->
- {WaitError,Host,Cmd}
- end;
- {Ok,Warning} ->
- {Ok,Host,Cmd,[],Warning}
- end;
- StartError ->
- gen_tcp:close(LSock),
- if Retry -> {error,remove};
- true -> {{error,{could_not_start_target,StartError}},Host,Cmd}
- end
+ {{ok,Nodename}, Host, Cmd, [], []};
+ Ret ->
+ {Ret, Host, Cmd}
end.
@@ -777,40 +597,10 @@ kill_node(SI,TI) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Platform specific code
-start_target(unix,TargetHost,Cmd0) ->
- Cmd =
- case test_server_sup:hoststr() of
- TargetHost -> Cmd0;
- _ -> lists:concat(["rsh ",TargetHost, " ", Cmd0])
- end,
- open_port({spawn, Cmd}, [stream]),
- {ok,undefined,?ACCEPT_TIMEOUT}.
-
-maybe_reboot_target(_) ->
- {error, cannot_reboot_target}.
-
close_target_client(undefined) ->
ok.
-
-%%
-%% Command for starting main target
-%%
-get_main_target_start_command(unix,_TargetHost,Naming,
- _MasterNode,_MasterCookie) ->
- Prog = pick_erl_program(default),
- Prog ++ " " ++ Naming ++ " test_server" ++
- " -boot start_sasl -sasl errlog_type error"
- " -s test_server start " ++ test_server_sup:hoststr().
-
-%%
-%% Command for starting slave nodes
-%%
-get_slave_node_start_command(unix, Prog, MasterNode) ->
- cast_to_list(Prog) ++ " -detached -master " ++ MasterNode.
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% cast_to_list(X) -> string()
%%% X = list() | atom() | void()