diff options
507 files changed, 31723 insertions, 28997 deletions
diff --git a/.gitignore b/.gitignore index eb14036789..18a54c21ca 100644 --- a/.gitignore +++ b/.gitignore @@ -186,6 +186,29 @@ JAVADOC-GENERATED /lib/*/config.status # +# Files generated by "./otp_build autoconf" +# + +/lib/configure.in +/aclocal.m4 +/lib/common_test/priv/auxdir/config.guess +/lib/common_test/priv/auxdir/config.sub +/lib/common_test/priv/auxdir/install-sh +/lib/erl_interface/aclocal.m4 +/lib/erl_interface/src/auxdir/config.guess +/lib/erl_interface/src/auxdir/config.sub +/lib/erl_interface/src/auxdir/install-sh +/lib/megaco/aclocal.m4 +/lib/odbc/aclocal.m4 +/lib/test_server/src/config.guess +/lib/test_server/src/config.sub +/lib/test_server/src/install-sh +/lib/wx/aclocal.m4 +/lib/wx/autoconf/config.guess +/lib/wx/autoconf/config.sub +/lib/wx/autoconf/install-sh + +# # Files generated when building/running tests (especially if # a directory in $ERL_TOP/release/tests has been symlinked to # a test directory in lib). @@ -389,4 +412,3 @@ JAVADOC-GENERATED /lib/xmerl/src/xmerl_xpath_parse.erl /lib/xmerl/test/xmerl_test.erl /lib/erl_interface/config.h.in -/lib/configure.in diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md index 7a7e63164c..53b1b8cd8a 100644 --- a/HOWTO/INSTALL.md +++ b/HOWTO/INSTALL.md @@ -409,6 +409,30 @@ Some of the available `configure` options are: If you or your system has special requirements please read the `Makefile` for additional configuration information. +#### Atomic Memory Operations and the VM #### + +The VM with SMP support makes quite a heavy use of atomic memory operations. +An implementation providing native atomic memory operations is therefore very +important when building Erlang/OTP. By default the VM will refuse to build +if native atomic memory operations are not available. + +Erlang/OTP itself provides implementations of native atomic memory operations +that can be used when compiling with a `gcc` compatible compiler on 32-bit +and 64-bit x86, 32-bit and 64-bit SPARC V9, and 32-bit PowerPC. When compiling +with a `gcc` compatible compiler on other architectures, the VM may be able to +make use of native atomic operations using the `__sync_*` primitives, but this +should only be used as a last resort since this wont give you optimal +performance. When compiling on Windows using a MicroSoft Visual C++ compiler +native atomic memory operations are provided by Windows APIs. + +You are recommended to use the native atomic implementation provided by +Erlang/OTP, or the API provided by Windows. If these do not provide native +atomics on your platform, you are recommended to build and install +[libatomic_ops][] before building Erlang/OTP. The `libatomic_ops` library +provides native atomic memory operations for a variety of platforms and +compilers. When building Erlang/OTP you need to inform the build system of +where the `libatomic_ops` library is installed using the +`--with-libatomic_ops=PATH` configure switch. ### Building ### @@ -862,3 +886,4 @@ under the License. [Optional Utilities]: #Optional-Utilities [Building on a Mac]: #Advanced-configuration-and-build-of-ErlangOTP_Building_OS-X-Darwin [Building with wxErlang]: #Advanced-configuration-and-build-of-ErlangOTP_Building_Building-with-wxErlang + [libatomic_ops]: https://github.com/ivmai/libatomic_ops/ diff --git a/OTP_VERSION b/OTP_VERSION index 9f09b58414..ae704d6db7 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -17.4-rc0 +17.4.1 diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index ed492d55ff..0000000000 --- a/aclocal.m4 +++ /dev/null @@ -1,1954 +0,0 @@ -dnl -dnl %CopyrightBegin% -dnl -dnl Copyright Ericsson AB 1998-2013. 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 - -AC_DEFUN(LM_PRECIOUS_VARS, -[ - -dnl ERL_TOP -AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) - -dnl Tools -AC_ARG_VAR(CC, [C compiler]) -AC_ARG_VAR(CFLAGS, [C compiler flags]) -AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) -AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) -AC_ARG_VAR(CPP, [C/C++ preprocessor]) -AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) -AC_ARG_VAR(CXX, [C++ compiler]) -AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) -AC_ARG_VAR(LD, [linker (is often overridden by configure)]) -AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) -AC_ARG_VAR(LIBS, [libraries]) -AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) -AC_ARG_VAR(RANLIB, [ranlib]) -AC_ARG_VAR(AR, [ar]) -AC_ARG_VAR(GETCONF, [getconf]) - -dnl Cross system root -AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) - -dnl Cross compilation variables -AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) - -dnl Cross compilation variables for OSE -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file]) -AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) - -]) - -AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, -[ -erl_xcomp_without_sysroot=no -if test "$cross_compiling" = "yes"; then - test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes - test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" -else - erl_xcomp_sysroot= - erl_xcomp_isysroot= -fi -]) - -AC_DEFUN(LM_CHECK_GETCONF, -[ -if test "$cross_compiling" != "yes"; then - AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) -else - dnl First check if we got a `<HOST>-getconf' in $PATH - host_getconf="$host_alias-getconf" - AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) - if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then - dnl We should perhaps give up if we have'nt found it by now, but at - dnl least in one Tilera MDE `getconf' under sysroot is a bourne - dnl shell script which we can use. We try to find `<HOST>-getconf' - dnl or `getconf' under sysconf, but only under sysconf since - dnl `getconf' in $PATH is almost guaranteed to be for the build - dnl machine. - GETCONF= - prfx="$erl_xcomp_sysroot" - AC_PATH_TOOL([GETCONF], [getconf], [false], - ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) - fi -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_WINDOWS_ENVIRONMENT -dnl -dnl -dnl Tries to determine thw windows build environment, i.e. -dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC -dnl - -AC_DEFUN(LM_WINDOWS_ENVIRONMENT, -[ -MIXED_CYGWIN=no -MIXED_MSYS=no - -AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) -if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([Cygwin and VC]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - elif test -x /usr/bin/msysinfo; then - CFLAGS="-O2" - MIXED_MSYS=yes - AC_MSG_RESULT([MSYS and VC]) - MIXED_MSYS_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no - MIXED_MSYS_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) -AC_SUBST(MIXED_MSYS_VC) - -MIXED_VC=no -if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then - MIXED_VC=yes -fi - -AC_SUBST(MIXED_VC) - -if test "x$MIXED_MSYS" != "xyes"; then - AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) - if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi - else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no - fi -else - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) - -AC_MSG_CHECKING(if we mix msys with another native compiler) -if test "X$MIXED_MSYS" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_MSYS) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_FIND_EMU_CC -dnl -dnl -dnl Tries fairly hard to find a C compiler that can handle jump tables. -dnl Defines the @EMU_CC@ variable for the makefiles and -dnl inserts NO_JUMP_TABLE in the header if one cannot be found... -dnl - -AC_DEFUN(LM_FIND_EMU_CC, - [AC_CACHE_CHECK(for a compiler that handles jumptables, - ac_cv_prog_emu_cc, - [ -AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; -lbl1: - return 1; -lbl2: - return 2; -],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - -if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc-4.2 gcc; do - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_progname; then - ac_cv_prog_emu_cc=$ac_dir/$ac_progname - break - fi - done - IFS="$ac_save_ifs" - if test $ac_cv_prog_emu_cc != no; then - break - fi - done -fi - -if test $ac_cv_prog_emu_cc != no; then - save_CC=$CC - save_CFLAGS=$CFLAGS - save_CPPFLAGS=$CPPFLAGS - CC=$ac_cv_prog_emu_cc - CFLAGS="" - CPPFLAGS="" - AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; - lbl1: - return 1; - lbl2: - return 2; - ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - CC=$save_CC - CFLAGS=$save_CFLAGS - CPPFLAGS=$save_CPPFLAGS -fi -]) -if test $ac_cv_prog_emu_cc = no; then - AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) - EMU_CC=$CC -else - EMU_CC=$ac_cv_prog_emu_cc -fi -AC_SUBST(EMU_CC) -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_INSTALL_DIR -dnl -dnl This macro may be used by any OTP application. -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 -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_PERL5 -dnl -dnl Try to find perl version 5. If found set PERL to the absolute path -dnl of the program, if not found set PERL to false. -dnl -dnl On some systems /usr/bin/perl is perl 4 and e.g. -dnl /usr/local/bin/perl is perl 5. We try to handle this case by -dnl putting a couple of -dnl Tries to handle the case that there are two programs called perl -dnl in the path and one of them is perl 5 and the other isn't. -dnl -AC_DEFUN(LM_PROG_PERL5, -[AC_PATH_PROGS(PERL, perl5 perl, false, - /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) -changequote(, )dnl -dnl[ That bracket is needed to balance the right bracket below -if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then -changequote([, ])dnl - ac_cv_path_PERL=false - PERL=false -dnl AC_MSG_WARN(perl version 5 not found) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SO_BSDCOMPAT -dnl -dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) -dnl -AC_DEFUN(LM_DECL_SO_BSDCOMPAT, -[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, -AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], - ac_cv_decl_so_bsdcompat=yes, - ac_cv_decl_so_bsdcompat=no)) - -case "${ac_cv_decl_so_bsdcompat}" in - "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], - [Define if you have SO_BSDCOMPAT flag on sockets]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_INADDR_LOOPBACK -dnl -dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default -dnl - -AC_DEFUN(LM_DECL_INADDR_LOOPBACK, -[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], - ac_cv_decl_inaddr_loopback, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], -ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) -]) - -if test ${ac_cv_decl_inaddr_loopback} = no; then - AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], - ac_cv_decl_inaddr_loopback_rpc, - AC_TRY_COMPILE([#include <rpc/types.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_rpc=yes, - ac_cv_decl_inaddr_loopback_rpc=no)) - - case "${ac_cv_decl_inaddr_loopback_rpc}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], - [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; - * ) - AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], - ac_cv_decl_inaddr_loopback_winsock2, - AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN - #include <winsock2.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_winsock2=yes, - ac_cv_decl_inaddr_loopback_winsock2=no)) - case "${ac_cv_decl_inaddr_loopback_winsock2}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], - [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; - * ) - # couldn't find it anywhere - AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], - [Define if you don't have a definition of INADDR_LOOPBACK]) ;; - esac;; - esac -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_SOCKADDR_SA_LEN -dnl -dnl Check if the sockaddr structure has the field sa_len -dnl - -AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, -[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], - ac_cv_struct_sockaddr_sa_len, -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], - ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) - -dnl FIXME convbreak -case ${ac_cv_struct_sockaddr_sa_len} in - "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; - *) ;; -esac -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_EXCEPTION -dnl -dnl Check to see whether the system supports the matherr function -dnl and its associated type "struct exception". -dnl - -AC_DEFUN(LM_STRUCT_EXCEPTION, -[AC_CACHE_CHECK([for struct exception (and matherr function)], - ac_cv_struct_exception, -AC_TRY_COMPILE([#include <math.h>], - [struct exception x; x.type = DOMAIN; x.type = SING;], - ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) - -case "${ac_cv_struct_exception}" in - "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_IPV6 -dnl -dnl Check for ipv6 support and what the in6_addr structure is called. -dnl (early linux used in_addr6 insted of in6_addr) -dnl - -AC_DEFUN(LM_SYS_IPV6, -[AC_MSG_CHECKING(for IP version 6 support) -AC_CACHE_VAL(ac_cv_sys_ipv6_support, -[ok_so_far=yes - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) - -if test $ok_so_far = yes; then - ac_cv_sys_ipv6_support=yes -else - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in_addr6 a6; struct sockaddr_in6 s6;], - ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) -fi -])dnl - -dnl -dnl Have to use old style AC_DEFINE due to BC with old autoconf. -dnl - -case ${ac_cv_sys_ipv6_support} in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - ;; - in_addr6) - AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) - ;; - *) - AC_MSG_RESULT(no) - ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_MULTICAST -dnl -dnl Check for multicast support. Only checks for multicast options in -dnl setsockopt(), no check is performed that multicasting actually works. -dnl If options are found defines HAVE_MULTICAST_SUPPORT -dnl - -AC_DEFUN(LM_SYS_MULTICAST, -[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, -[AC_EGREP_CPP(yes, -[#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) -yes -#endif -], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) -if test $ac_cv_sys_multicast_support = yes; then - AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], - [Define if setsockopt() accepts multicast options]) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SYS_ERRLIST -dnl -dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared -dnl in a system header file, stdio.h or errno.h. -dnl - -AC_DEFUN(LM_DECL_SYS_ERRLIST, -[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], - ac_cv_decl_sys_errlist, -[AC_TRY_COMPILE([#include <stdio.h> -#include <errno.h>], [char *msg = *(sys_errlist + 1);], - ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) -if test $ac_cv_decl_sys_errlist = yes; then - AC_DEFINE(SYS_ERRLIST_DECLARED,[], - [define if the variable sys_errlist is declared in a system header file]) -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes -dnl [, action-if-found [, action-if-not-found]]] ) -dnl -dnl Checks if the declaration "declaration" of "funname" conflicts -dnl with the header files idea of how the function should be -dnl declared. It is useful on systems which lack prototypes and you -dnl need to provide your own (e.g. when you want to take the address -dnl of a function). The 4'th argument is expanded if conflicting, -dnl the 5'th argument otherwise -dnl -dnl - -AC_DEFUN(LM_CHECK_FUNC_DECL, -[AC_MSG_CHECKING([for conflicting declaration of $1]) -AC_CACHE_VAL(ac_cv_func_decl_$1, -[AC_TRY_COMPILE([#include <stdio.h> -$3],[$2 -char *c = (char *)$1; -], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) -if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then - AC_MSG_RESULT(yes) - ifelse([$4], , :, [$4]) -else - AC_MSG_RESULT(no) -ifelse([$5], , , [$5 -])dnl -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl AC_DOUBLE_MIDDLE_ENDIAN -dnl -dnl Checks whether doubles are represented in "middle-endian" format. -dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly, -dnl as well as DOUBLE_MIDDLE_ENDIAN. -dnl -dnl - -AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN], -[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian, -[# It does not; compile a test program. -AC_RUN_IFELSE( -[AC_LANG_SOURCE([[#include <stdlib.h> - -int -main(void) -{ - int i = 0; - int zero = 0; - int bigendian; - int zero_index = 0; - - union - { - long int l; - char c[sizeof (long int)]; - } u; - - /* we'll use the one with 32-bit words */ - union - { - double d; - unsigned int c[2]; - } vint; - - union - { - double d; - unsigned long c[2]; - } vlong; - - union - { - double d; - unsigned short c[2]; - } vshort; - - - /* Are we little or big endian? From Harbison&Steele. */ - u.l = 1; - bigendian = (u.c[sizeof (long int) - 1] == 1); - - zero_index = bigendian ? 1 : 0; - - vint.d = 1.0; - vlong.d = 1.0; - vshort.d = 1.0; - - if (sizeof(unsigned int) == 4) - { - if (vint.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned long) == 4) - { - if (vlong.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned short) == 4) - { - if (vshort.c[zero_index] != 0) - zero = 1; - } - - exit (zero); -} -]])], - [ac_cv_c_double_middle_endian=no], - [ac_cv_c_double_middle_endian=yes], - [ac_cv_c_double_middle=unknown])]) -case $ac_cv_c_double_middle_endian in - yes) - m4_default([$1], - [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1, - [Define to 1 if your processor stores the words in a double in - middle-endian format (like some ARMs).])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_WARN([unknown double endianness -presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;; -esac -])# AC_C_DOUBLE_MIDDLE_ENDIAN - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_THR_LIB -dnl -dnl This macro may be used by any OTP application. -dnl -dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also -dnl checks for some pthread headers which will appear in DEFS or config.h. -dnl - -AC_DEFUN(LM_CHECK_THR_LIB, -[ - -NEED_NPTL_PTHREAD_H=no - -dnl win32? -AC_MSG_CHECKING([for native win32 threads]) -if test "X$host_os" = "Xwin32"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DWIN32_THREADS" - THR_LIBS= - THR_LIB_NAME=win32_threads - THR_LIB_TYPE=win32_threads -elif test "X$host_os" = "Xose"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DOSE_THREADS" - THR_LIBS= - THR_LIB_NAME=ose_threads - THR_LIB_TYPE=ose_threads -else - AC_MSG_RESULT(no) - THR_DEFS= - THR_LIBS= - THR_LIB_NAME= - THR_LIB_TYPE=posix_unknown - -dnl Try to find POSIX threads - -dnl The usual pthread lib... - AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") - -dnl Very old versions of FreeBSD have pthreads in special c library, c_r... - if test "x$THR_LIBS" = "x"; then - AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") - fi - -dnl QNX has pthreads in standard C library - if test "x$THR_LIBS" = "x"; then - AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed") - fi - -dnl On ofs1 the '-pthread' switch should be used - if test "x$THR_LIBS" = "x"; then - AC_MSG_CHECKING([if the '-pthread' switch can be used]) - saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -pthread" - AC_TRY_LINK([#include <pthread.h>], - pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, - [THR_DEFS="-pthread" - THR_LIBS="-pthread"]) - CFLAGS=$saved_cflags - if test "x$THR_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - fi - - if test "x$THR_LIBS" != "x"; then - THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" - THR_LIB_NAME=pthread - if test "x$THR_LIBS" = "xnone_needed"; then - THR_LIBS= - fi - case $host_os in - solaris*) - THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; - linux*) - THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" - - LM_CHECK_GETCONF - AC_MSG_CHECKING(for Native POSIX Thread Library) - libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` - if test $? -eq 0; then - case "$libpthr_vsn" in - *nptl*|*NPTL*) nptl=yes;; - *) nptl=no;; - esac - elif test "$cross_compiling" = "yes"; then - case "$erl_xcomp_linux_nptl" in - "") nptl=cross;; - yes|no) nptl=$erl_xcomp_linux_nptl;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; - esac - else - nptl=no - fi - AC_MSG_RESULT($nptl) - if test $nptl = cross; then - nptl=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $nptl = yes; then - THR_LIB_TYPE=posix_nptl - need_nptl_incldir=no - AC_CHECK_HEADER(nptl/pthread.h, - [need_nptl_incldir=yes - NEED_NPTL_PTHREAD_H=yes]) - if test $need_nptl_incldir = yes; then - # Ahh... - nptl_path="$C_INCLUDE_PATH:$CPATH" - if test X$cross_compiling != Xyes; then - nptl_path="$nptl_path:/usr/local/include:/usr/include" - else - IROOT="$erl_xcomp_isysroot" - test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" - test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) - nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" - fi - nptl_ws_path= - save_ifs="$IFS"; IFS=":" - for dir in $nptl_path; do - if test "x$dir" != "x"; then - nptl_ws_path="$nptl_ws_path $dir" - fi - done - IFS=$save_ifs - nptl_incldir= - for dir in $nptl_ws_path; do - AC_CHECK_HEADER($dir/nptl/pthread.h, - nptl_incldir=$dir/nptl) - if test "x$nptl_incldir" != "x"; then - THR_DEFS="$THR_DEFS -isystem $nptl_incldir" - break - fi - done - if test "x$nptl_incldir" = "x"; then - AC_MSG_ERROR(Failed to locate nptl system include directory) - fi - fi - fi - ;; - *) ;; - esac - - dnl We sometimes need THR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $THR_DEFS" - - dnl - dnl Check for headers - dnl - - AC_CHECK_HEADER(pthread.h, - AC_DEFINE(HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - fi -fi - -]) - -AC_DEFUN(ERL_INTERNAL_LIBS, -[ - -ERTS_INTERNAL_X_LIBS= - -AC_CHECK_LIB(kstat, kstat_open, -[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) -ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) - -AC_SUBST(ERTS_INTERNAL_X_LIBS) - -]) - -AC_DEFUN(ETHR_CHK_SYNC_OP, -[ - AC_MSG_CHECKING([for $3-bit $1()]) - case "$2" in - "1") sync_call="$1(&var);";; - "2") sync_call="$1(&var, ($4) 0);";; - "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; - esac - have_sync_op=no - AC_TRY_LINK([], - [ - $4 res; - volatile $4 var; - res = $sync_call - ], - [have_sync_op=yes]) - test $have_sync_op = yes && $5 - AC_MSG_RESULT([$have_sync_op]) -]) - -AC_DEFUN(ETHR_CHK_INTERLOCKED, -[ - ilckd="$1" - AC_MSG_CHECKING([for ${ilckd}()]) - case "$2" in - "1") ilckd_call="${ilckd}(var);";; - "2") ilckd_call="${ilckd}(var, ($3) 0);";; - "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; - "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; - esac - have_interlocked_op=no - AC_TRY_LINK( - [ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <intrin.h> - ], - [ - volatile $3 *var; - volatile $3 arr[2]; - - $ilckd_call - return 0; - ], - [have_interlocked_op=yes]) - test $have_interlocked_op = yes && $4 - AC_MSG_RESULT([$have_interlocked_op]) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_FIND_ETHR_LIB -dnl -dnl NOTE! This macro may be changed at any time! Should *only* be used by -dnl ERTS! -dnl -dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link -dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS -dnl except that the ethread lib itself is not included), ETHR_DEFS to -dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the -dnl thread library which the ethread library is based on, and ETHR_LIB_NAME -dnl to the name of the library where the ethread implementation is located. -dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and -dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, -dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the -dnl empty string. -dnl - -AC_DEFUN(ERL_FIND_ETHR_LIB, -[ - -AC_ARG_ENABLE(native-ethr-impls, - AS_HELP_STRING([--disable-native-ethr-impls], - [disable native ethread implementations]), -[ case "$enableval" in - no) disable_native_ethr_impls=yes ;; - *) disable_native_ethr_impls=no ;; - esac ], disable_native_ethr_impls=no) - -test "X$disable_native_ethr_impls" = "Xyes" && - AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) - -AC_ARG_ENABLE(x86-out-of-order, - AS_HELP_STRING([--enable-x86-out-of-order], - [enable x86/x84_64 out of order support (default disabled)])) - -AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, - AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [prefer gcc native ethread implementations]), -[ case "$enableval" in - yes) enable_prefer_gcc_native_ethr_impls=yes ;; - *) enable_prefer_gcc_native_ethr_impls=no ;; - esac ], enable_prefer_gcc_native_ethr_impls=no) - -test $enable_prefer_gcc_native_ethr_impls = yes && - AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) - -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [specify and prefer usage of libatomic_ops in the ethread library])) - -AC_ARG_WITH(with_sparc_memory_order, - AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], - [specify sparc memory order (defaults to RMO)])) - -LM_CHECK_THR_LIB -ERL_INTERNAL_LIBS - -ethr_have_native_atomics=no -ethr_have_native_spinlock=no -ETHR_THR_LIB_BASE="$THR_LIB_NAME" -ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" -ETHR_DEFS="$THR_DEFS" -ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" -ETHR_LIBS= -ETHR_LIB_NAME= - -ethr_modified_default_stack_size= - -dnl Name of lib where ethread implementation is located -ethr_lib_name=ethread - -case "$THR_LIB_NAME" in - - win32_threads) - ETHR_THR_LIB_BASE_DIR=win - # * _WIN32_WINNT >= 0x0400 is needed for - # TryEnterCriticalSection - # * _WIN32_WINNT >= 0x0403 is needed for - # InitializeCriticalSectionAndSpinCount - # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. - # - # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it - # and save it in ETHR_DEFS. - found_win32_winnt=no - for cppflag in $CPPFLAGS; do - case $cppflag in - -DWINVER*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - ;; - -D_WIN32_WINNT*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - found_win32_winnt=yes - ;; - *) - ;; - esac - done - if test $found_win32_winnt = no; then - AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) - fi - - AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) - - if test "X$disable_native_ethr_impls" = "Xyes"; then - have_interlocked_op=no - ethr_have_native_atomics=no - else - ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) - fi - test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes - ;; - - pthread|ose_threads) - case "$THR_LIB_NAME" in - pthread) - ETHR_THR_LIB_BASE_DIR=pthread - AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) - ;; - ose_threads) - AC_DEFINE(ETHR_OSE_THREADS, 1, - [Define if you have OSE style threads]) - ETHR_THR_LIB_BASE_DIR=ose - AC_CHECK_HEADER(ose_spi/ose_spi.h, - AC_DEFINE(HAVE_OSE_SPI_H, 1, - [Define if you have the "ose_spi/ose_spi.h" header file.])) - ;; - esac - if test "x$THR_LIB_NAME" = "xpthread"; then - case $host_os in - openbsd*) - # The default stack size is insufficient for our needs - # on OpenBSD. We increase it to 256 kilo words. - ethr_modified_default_stack_size=256;; - linux*) - ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" - - if test X$cross_compiling = Xyes; then - case X$erl_xcomp_linux_usable_sigusrx in - X) usable_sigusrx=cross;; - Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; - esac - case X$erl_xcomp_linux_usable_sigaltstack in - X) usable_sigaltstack=cross;; - Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; - esac - else - # FIXME: Test for actual problems instead of kernel versions - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) - usable_sigusrx=no - usable_sigaltstack=no;; - 2.[[2-3]]|2.[[2-3]].*) - usable_sigusrx=yes - usable_sigaltstack=no;; - *) - usable_sigusrx=yes - usable_sigaltstack=yes;; - esac - fi - - AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) - AC_MSG_RESULT($usable_sigusrx) - if test $usable_sigusrx = cross; then - usable_sigusrx=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigusrx = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" - fi - - AC_MSG_CHECKING(if sigaltstack can be used) - AC_MSG_RESULT($usable_sigaltstack) - if test $usable_sigaltstack = cross; then - usable_sigaltstack=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigaltstack = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" - fi - ;; - *) ;; - esac - - fi - dnl We sometimes need ETHR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ETHR_DEFS" - - dnl We need the thread library in order to find some functions - saved_libs="$LIBS" - LIBS="$LIBS $ETHR_X_LIBS" - - dnl - dnl Check for headers - dnl - AC_CHECK_HEADER(pthread.h, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - if test $NEED_NPTL_PTHREAD_H = yes; then - AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ -[Define if you need the <nptl/pthread.h> header file.]) - fi - - AC_CHECK_HEADER(sched.h, \ - AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ -[Define if you have the <sched.h> header file.])) - - AC_CHECK_HEADER(sys/time.h, \ - AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ -[Define if you have the <sys/time.h> header file.])) - - AC_TRY_COMPILE([#include <time.h> - #include <sys/time.h>], - [struct timeval *tv; return 0;], - AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ -[Define if you can safely include both <sys/time.h> and <time.h>.])) - - - dnl - dnl Check for functions - dnl - if test "x$THR_LIB_NAME" = "xpthread"; then - AC_CHECK_FUNC(pthread_spin_lock, \ - [ethr_have_native_spinlock=yes \ - AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ -[Define if you have the pthread_spin_lock function.])]) - - have_sched_yield=no - have_librt_sched_yield=no - AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) - if test $have_sched_yield = no; then - AC_CHECK_LIB(rt, sched_yield, - [have_librt_sched_yield=yes - ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) - fi - if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then - AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) - AC_MSG_CHECKING([whether sched_yield() returns an int]) - sched_yield_ret_int=no - AC_TRY_COMPILE([ - #ifdef ETHR_HAVE_SCHED_H - #include <sched.h> - #endif - ], - [int sched_yield();], - [sched_yield_ret_int=yes]) - AC_MSG_RESULT([$sched_yield_ret_int]) - if test $sched_yield_ret_int = yes; then - AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) - fi - fi - - have_pthread_yield=no - AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) - if test $have_pthread_yield = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) - AC_MSG_CHECKING([whether pthread_yield() returns an int]) - pthread_yield_ret_int=no - AC_TRY_COMPILE([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [int pthread_yield();], - [pthread_yield_ret_int=yes]) - AC_MSG_RESULT([$pthread_yield_ret_int]) - if test $pthread_yield_ret_int = yes; then - AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) - fi - fi - - have_pthread_rwlock_init=no - AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) - if test $have_pthread_rwlock_init = yes; then - - ethr_have_pthread_rwlockattr_setkind_np=no - AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, - [ethr_have_pthread_rwlockattr_setkind_np=yes]) - - if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ -[Define if you have the pthread_rwlockattr_setkind_np() function.]) - - AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) - ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no - AC_TRY_LINK([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [ - pthread_rwlockattr_t *attr; - return pthread_rwlockattr_setkind_np(attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - ], - [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) - AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) - if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ -[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) - fi - fi - fi - - if test "$force_pthread_rwlocks" = "yes"; then - - AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ -[Define if you want to force usage of pthread rwlocks]) - - if test $have_pthread_rwlock_init = yes; then - AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) - else - AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) - fi - fi - - AC_CHECK_FUNC(pthread_attr_setguardsize, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ -[Define if you have the pthread_attr_setguardsize function.])) - - linux_futex=no - AC_MSG_CHECKING([for Linux futexes]) - AC_TRY_LINK([ - #include <sys/syscall.h> - #include <unistd.h> - #include <linux/futex.h> - #include <sys/time.h> - ], - [ - int i = 1; - syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, - (void*)0,(void*)0, 0); - syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, - (void*)0,(void*)0, 0); - return 0; - ], - linux_futex=yes) - AC_MSG_RESULT([$linux_futex]) - test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) - - fi - - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int128_t) - - if test "$ac_cv_sizeof_int" = "4"; then - int32="int" - elif test "$ac_cv_sizeof_long" = "4"; then - int32="long" - elif test "$ac_cv_sizeof_long_long" = "4"; then - int32="long long" - else - AC_MSG_ERROR([No 32-bit type found]) - fi - - if test "$ac_cv_sizeof_int" = "8"; then - int64="int" - elif test "$ac_cv_sizeof_long" = "8"; then - int64="long" - elif test "$ac_cv_sizeof_long_long" = "8"; then - int64="long long" - else - AC_MSG_ERROR([No 64-bit type found]) - fi - - int128=no - if test "$ac_cv_sizeof___int128_t" = "16"; then - int128="__int128_t" - fi - - if test "X$disable_native_ethr_impls" = "Xyes"; then - ethr_have_native_atomics=no - else - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) - - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) - - if test $int128 != no; then - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) - fi - - AC_MSG_CHECKING([for a usable libatomic_ops implementation]) - case "x$with_libatomic_ops" in - xno | xyes | x) - libatomic_ops_include= - ;; - *) - if test -d "${with_libatomic_ops}/include"; then - libatomic_ops_include="-I$with_libatomic_ops/include" - CPPFLAGS="$CPPFLAGS $libatomic_ops_include" - else - AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) - fi;; - esac - ethr_have_libatomic_ops=no - AC_TRY_LINK([#include "atomic_ops.h"], - [ - volatile AO_t x; - AO_t y; - int z; - - AO_nop_full(); - AO_store(&x, (AO_t) 0); - z = AO_load(&x); - z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); - ], - [ethr_have_native_atomics=yes - ethr_have_libatomic_ops=yes]) - AC_MSG_RESULT([$ethr_have_libatomic_ops]) - if test $ethr_have_libatomic_ops = yes; then - AC_CHECK_SIZEOF(AO_t, , - [ - #include <stdio.h> - #include "atomic_ops.h" - ]) - AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) - - AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) - if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) - fi - ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" - elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_MSG_ERROR([No usable libatomic_ops implementation found]) - fi - - case "$host_cpu" in - sparc | sun4u | sparc64 | sun4v) - case "$with_sparc_memory_order" in - "TSO") - AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; - "PSO") - AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; - "RMO"|"") - AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; - *) - AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; - esac - ethr_have_native_atomics=yes;; - i86pc | i*86 | x86_64 | amd64) - if test "$enable_x86_out_of_order" = "yes"; then - AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) - fi - ethr_have_native_atomics=yes;; - macppc | ppc | powerpc | "Power Macintosh") - ethr_have_native_atomics=yes;; - tile) - ethr_have_native_atomics=yes;; - *) - ;; - esac - - fi - - test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes - - dnl Restore LIBS - LIBS=$saved_libs - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - ;; - *) - ;; -esac - -AC_MSG_CHECKING([whether default stack size should be modified]) -if test "x$ethr_modified_default_stack_size" != "x"; then - AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) - AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) -else - AC_MSG_RESULT([no]) -fi - -if test "x$ETHR_THR_LIB_BASE" != "x"; then - ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" - ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" - ETHR_LIB_NAME=$ethr_lib_name -fi - -AC_CHECK_SIZEOF(void *) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) - -AC_CHECK_SIZEOF(int) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) -AC_CHECK_SIZEOF(long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) -AC_CHECK_SIZEOF(long long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) -AC_CHECK_SIZEOF(__int64) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) -AC_CHECK_SIZEOF(__int128_t) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) - - -case X$erl_xcomp_bigendian in - X) ;; - Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; - *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; -esac - -AC_C_BIGENDIAN - -if test "$ac_cv_c_bigendian" = "yes"; then - AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) -fi - -case X$erl_xcomp_double_middle_endian in - X) ;; - Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;; - *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);; -esac - -AC_C_DOUBLE_MIDDLE_ENDIAN - -ETHR_X86_SSE2_ASM=no -case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in - yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) - AC_MSG_CHECKING([for gcc sse2 asm support]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -msse2" - gcc_sse2_asm=no - AC_TRY_COMPILE([], - [ - long long x, *y; - __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); - ], - [gcc_sse2_asm=yes]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$gcc_sse2_asm]) - if test "$gcc_sse2_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) - ETHR_X86_SSE2_ASM=yes - fi - ;; - *) - ;; -esac - -case "$GCC-$host_cpu" in - yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) - gcc_dw_cmpxchg_asm=no - AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; - __asm__ __volatile__( -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "pushl %%ebx\n\t" - "movl %8, %%ebx\n\t" -#endif -#if ETHR_SIZEOF_PTR == 4 - "lock; cmpxchg8b %0\n\t" -#else - "lock; cmpxchg16b %0\n\t" -#endif - "setz %3\n\t" -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "popl %%ebx\n\t" -#endif - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "r"(new[0]) -#else - "b"(new[0]) -#endif - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; -#if !defined(__PIC__) || !__PIC__ -# error nope -#endif - __asm__ __volatile__( - "pushl %%ebx\n\t" - "movl (%7), %%ebx\n\t" - "movl 4(%7), %%ecx\n\t" - "lock; cmpxchg8b %0\n\t" - "setz %3\n\t" - "popl %%ebx\n\t" - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) - fi - fi - AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) - fi;; - *) - ;; -esac - -AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ -[Define if you have all ethread defines]) - -AC_SUBST(ETHR_X_LIBS) -AC_SUBST(ETHR_LIBS) -AC_SUBST(ETHR_LIB_NAME) -AC_SUBST(ETHR_DEFS) -AC_SUBST(ETHR_THR_LIB_BASE) -AC_SUBST(ETHR_THR_LIB_BASE_DIR) -AC_SUBST(ETHR_X86_SSE2_ASM) - -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_TIME_CORRECTION -dnl -dnl In the presence of a high resolution realtime timer Erlang can adapt -dnl its view of time relative to this timer. On solaris such a timer is -dnl available with the syscall gethrtime(). On other OS's a fallback -dnl solution using times() is implemented. (However on e.g. FreeBSD times() -dnl is implemented using gettimeofday so it doesn't make much sense to -dnl use it there...) On second thought, it seems to be safer to do it the -dnl other way around. I.e. only use times() on OS's where we know it will -dnl work... -dnl - -AC_DEFUN(ERL_TIME_CORRECTION, -[if test x$ac_cv_func_gethrtime = x; then - AC_CHECK_FUNC(gethrtime) -fi -if test x$clock_gettime_correction = xunknown; then - AC_TRY_COMPILE([#include <time.h>], - [struct timespec ts; - long long result; - clock_gettime(CLOCK_MONOTONIC,&ts); - result = ((long long) ts.tv_sec) * 1000000000LL + - ((long long) ts.tv_nsec);], - clock_gettime_compiles=yes, - clock_gettime_compiles=no) -else - clock_gettime_compiles=no -fi - - -AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, -[ -case $clock_gettime_correction in - yes) - erl_cv_time_correction=clock_gettime;; - no|unknown) - case $ac_cv_func_gethrtime in - yes) - erl_cv_time_correction=hrtime ;; - no) - case $host_os in - linux*) - case $clock_gettime_correction in - unknown) - if test x$clock_gettime_compiles = xyes; then - if test X$cross_compiling != Xyes; then - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) - erl_cv_time_correction=times ;; - *) - erl_cv_time_correction=clock_gettime;; - esac - else - case X$erl_xcomp_linux_clock_gettime_correction in - X) - erl_cv_time_correction=cross;; - Xyes|Xno) - if test $erl_xcomp_linux_clock_gettime_correction = yes; then - erl_cv_time_correction=clock_gettime - else - erl_cv_time_correction=times - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; - esac - fi - else - erl_cv_time_correction=times - fi - ;; - *) - erl_cv_time_correction=times ;; - esac - ;; - *) - erl_cv_time_correction=none ;; - esac - ;; - esac - ;; -esac -]) - -xrtlib="" -case $erl_cv_time_correction in - times) - AC_DEFINE(CORRECT_USING_TIMES,[], - [Define if you do not have a high-res. timer & want to use times() instead]) - ;; - clock_gettime|cross) - if test $erl_cv_time_correction = cross; then - erl_cv_time_correction=clock_gettime - AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) - fi - xrtlib="-lrt" - AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], - [Define if you want to use clock_gettime to simulate gethrtime]) - ;; -esac -dnl -dnl Check if gethrvtime is working, and if to use procfs ioctl -dnl or (yet to be written) write to the procfs ctl file. -dnl - -AC_MSG_CHECKING([if gethrvtime works and how to use it]) -AC_TRY_RUN([ -/* gethrvtime procfs ioctl test */ -/* These need to be undef:ed to not break activation of - * micro level process accounting on /proc/self - */ -#ifdef _LARGEFILE_SOURCE -# undef _LARGEFILE_SOURCE -#endif -#ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -#endif -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/signal.h> -#include <sys/fault.h> -#include <sys/syscall.h> -#include <sys/procfs.h> -#include <fcntl.h> - -int main() { - long msacct = PR_MSACCT; - int fd; - long long start, stop; - int i; - pid_t pid = getpid(); - char proc_self[30] = "/proc/"; - - sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); - if ( (fd = open(proc_self, O_WRONLY)) == -1) - exit(1); - if (ioctl(fd, PIOCSET, &msacct) < 0) - exit(2); - if (close(fd) < 0) - exit(3); - start = gethrvtime(); - for (i = 0; i < 100; i++) - stop = gethrvtime(); - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; -} -], -erl_gethrvtime=procfs_ioctl, -erl_gethrvtime=false, -[ -case X$erl_xcomp_gethrvtime_procfs_ioctl in - X) - erl_gethrvtime=cross;; - Xyes|Xno) - if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then - erl_gethrvtime=procfs_ioctl - else - erl_gethrvtime=false - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; -esac -]) - -case $erl_gethrvtime in - procfs_ioctl) - AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], - [define if gethrvtime() works and uses ioctl() to /proc/self]) - AC_MSG_RESULT(uses ioctl to procfs) - ;; - *) - if test $erl_gethrvtime = cross; then - erl_gethrvtime=false - AC_MSG_RESULT(cross) - AC_MSG_WARN([result 'not working' guessed because of cross compilation]) - else - AC_MSG_RESULT(not working) - fi - - dnl - dnl Check if clock_gettime (linux) is working - dnl - - AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) - save_libs=$LIBS - LIBS="-lrt" - AC_TRY_RUN([ - #include <stdlib.h> - #include <unistd.h> - #include <string.h> - #include <stdio.h> - #include <time.h> - int main() { - long long start, stop; - int i; - struct timespec tp; - - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) - exit(1); - start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - for (i = 0; i < 100; i++) - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); - stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; - } - ], - erl_clock_gettime=yes, - erl_clock_gettime=no, - [ - case X$erl_xcomp_clock_gettime_cpu_time in - X) erl_clock_gettime=cross;; - Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; - *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; - esac - ]) - LIBS=$save_libs - case $host_os in - linux*) - AC_MSG_RESULT([no; not stable]) - LIBRT=$xrtlib - ;; - *) - AC_MSG_RESULT($erl_clock_gettime) - case $erl_clock_gettime in - yes) - AC_DEFINE(HAVE_CLOCK_GETTIME,[], - [define if clock_gettime() works for getting process time]) - LIBRT=-lrt - ;; - cross) - erl_clock_gettime=no - AC_MSG_WARN([result no guessed because of cross compilation]) - LIBRT=$xrtlib - ;; - *) - LIBRT=$xrtlib - ;; - esac - ;; - esac - AC_SUBST(LIBRT) - ;; -esac -])dnl - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_TRY_ENABLE_CFLAG -dnl -dnl -dnl Tries a CFLAG and sees if it can be enabled without compiler errors -dnl $1: textual cflag to add -dnl $2: variable to store the modified CFLAG in -dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS]) -dnl -dnl -AC_DEFUN([LM_TRY_ENABLE_CFLAG], [ - AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)]) - saved_CFLAGS=$CFLAGS; - CFLAGS="$1 $$2"; - AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false) - CFLAGS=$saved_CFLAGS; - if test "X$can_enable_flag" = "Xtrue"; then - AC_MSG_RESULT([yes]) - AS_VAR_SET($2, "$1 $$2") - else - AC_MSG_RESULT([no]) - fi -]) - -dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY -dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a -dnl AC_LANG_JAVA instead...) -AC_DEFUN(ERL_TRY_LINK_JAVA, -[java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(, )dnl -cat > conftest.java <<EOF -$1 -class conftest { public static void main(String[] args) { - $2 - ; return; }} -EOF -changequote([, ])dnl -if AC_TRY_EVAL(java_link) && test -s conftest.class; then - ifelse([$3], , :, [rm -rf conftest* - $3]) -else - echo "configure: failed program was:" 1>&AC_FD_CC - cat conftest.java 1>&AC_FD_CC - echo "configure: PATH was $PATH" 1>&AC_FD_CC -ifelse([$4], , , [ rm -rf conftest* - $4 -])dnl -fi -rm -f conftest*]) -#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ - - diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot Binary files differindex c497fe37fc..6cc4fa1f43 100644 --- a/bootstrap/bin/start.boot +++ b/bootstrap/bin/start.boot diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot Binary files differindex c497fe37fc..6cc4fa1f43 100644 --- a/bootstrap/bin/start_clean.boot +++ b/bootstrap/bin/start_clean.boot diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam Binary files differindex f58fdd7171..e6c5cc9028 100644 --- a/bootstrap/lib/compiler/ebin/beam_asm.beam +++ b/bootstrap/lib/compiler/ebin/beam_asm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam Binary files differindex f339e76fce..6454719448 100644 --- a/bootstrap/lib/compiler/ebin/beam_bool.beam +++ b/bootstrap/lib/compiler/ebin/beam_bool.beam diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app index f12713417f..ea1be86c83 100644 --- a/bootstrap/lib/compiler/ebin/compiler.app +++ b/bootstrap/lib/compiler/ebin/compiler.app @@ -18,7 +18,7 @@ {application, compiler, [{description, "ERTS CXC 138 10"}, - {vsn, "5.0.1"}, + {vsn, "5.0.3"}, {modules, [ beam_a, beam_asm, diff --git a/bootstrap/lib/compiler/ebin/core_lib.beam b/bootstrap/lib/compiler/ebin/core_lib.beam Binary files differindex bb38837049..54f43c6c10 100644 --- a/bootstrap/lib/compiler/ebin/core_lib.beam +++ b/bootstrap/lib/compiler/ebin/core_lib.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex cce0ac7832..64477ec574 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 5da654686a..851b5512c3 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam Binary files differindex 25f2506078..5305c3854c 100644 --- a/bootstrap/lib/kernel/ebin/file.beam +++ b/bootstrap/lib/kernel/ebin/file.beam diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam Binary files differindex b24c850af3..6df9ac9564 100644 --- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam +++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam Binary files differindex 4d156b726c..4fff1c069d 100644 --- a/bootstrap/lib/kernel/ebin/inet.beam +++ b/bootstrap/lib/kernel/ebin/inet.beam diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app index e60b36e1e7..3388f28e91 100644 --- a/bootstrap/lib/kernel/ebin/kernel.app +++ b/bootstrap/lib/kernel/ebin/kernel.app @@ -21,7 +21,7 @@ {application, kernel, [ {description, "ERTS CXC 138 10"}, - {vsn, "3.0.2"}, + {vsn, "3.1"}, {modules, [application, application_controller, application_master, diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup index fda418ae8a..b6fade4222 100644 --- a/bootstrap/lib/kernel/ebin/kernel.appup +++ b/bootstrap/lib/kernel/ebin/kernel.appup @@ -15,7 +15,7 @@ %% under the License. %% %% %CopyrightEnd% -{"3.0", +{"3.1", %% Up from - max one major revision back [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17 {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16 diff --git a/bootstrap/lib/kernel/ebin/standard_error.beam b/bootstrap/lib/kernel/ebin/standard_error.beam Binary files differindex 21b5722bb2..be4f9292e7 100644 --- a/bootstrap/lib/kernel/ebin/standard_error.beam +++ b/bootstrap/lib/kernel/ebin/standard_error.beam diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam Binary files differindex 6f430b8c6c..46adf4ee3a 100644 --- a/bootstrap/lib/stdlib/ebin/dets.beam +++ b/bootstrap/lib/stdlib/ebin/dets.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_server.beam b/bootstrap/lib/stdlib/ebin/dets_server.beam Binary files differindex 6bbefbbf1e..7ce673e23c 100644 --- a/bootstrap/lib/stdlib/ebin/dets_server.beam +++ b/bootstrap/lib/stdlib/ebin/dets_server.beam diff --git a/bootstrap/lib/stdlib/ebin/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam Binary files differindex 12aa74c4ac..f006e86851 100644 --- a/bootstrap/lib/stdlib/ebin/edlin.beam +++ b/bootstrap/lib/stdlib/ebin/edlin.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam Binary files differindex ff84000ac0..b2104b1d3f 100644 --- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam +++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam Binary files differindex 998bb0b209..4c27146a81 100644 --- a/bootstrap/lib/stdlib/ebin/erl_parse.beam +++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam Binary files differindex ff196f3a45..4549b309ca 100644 --- a/bootstrap/lib/stdlib/ebin/erl_pp.beam +++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_tar.beam b/bootstrap/lib/stdlib/ebin/erl_tar.beam Binary files differindex 76f5f95270..24c65996b3 100644 --- a/bootstrap/lib/stdlib/ebin/erl_tar.beam +++ b/bootstrap/lib/stdlib/ebin/erl_tar.beam diff --git a/bootstrap/lib/stdlib/ebin/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam Binary files differindex 9fc7dd79cb..ab3600c2f2 100644 --- a/bootstrap/lib/stdlib/ebin/filelib.beam +++ b/bootstrap/lib/stdlib/ebin/filelib.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam Binary files differindex d45e508d22..e7aaf99eb0 100644 --- a/bootstrap/lib/stdlib/ebin/gen_event.beam +++ b/bootstrap/lib/stdlib/ebin/gen_event.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam Binary files differindex cb9421b7c5..833287bbe2 100644 --- a/bootstrap/lib/stdlib/ebin/gen_server.beam +++ b/bootstrap/lib/stdlib/ebin/gen_server.beam diff --git a/bootstrap/lib/stdlib/ebin/io.beam b/bootstrap/lib/stdlib/ebin/io.beam Binary files differindex 6c80bfe78b..fd64aedde1 100644 --- a/bootstrap/lib/stdlib/ebin/io.beam +++ b/bootstrap/lib/stdlib/ebin/io.beam diff --git a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam Binary files differindex fa7e6fcbc3..9504baab1b 100644 --- a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam +++ b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam Binary files differindex 9a55c521f8..55eec2691c 100644 --- a/bootstrap/lib/stdlib/ebin/ms_transform.beam +++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam Binary files differindex 23b140aeb5..7c2d60d845 100644 --- a/bootstrap/lib/stdlib/ebin/otp_internal.beam +++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app index 8cbf23e958..e92798b83d 100644 --- a/bootstrap/lib/stdlib/ebin/stdlib.app +++ b/bootstrap/lib/stdlib/ebin/stdlib.app @@ -19,7 +19,7 @@ %% {application, stdlib, [{description, "ERTS CXC 138 10"}, - {vsn, "2.1.1"}, + {vsn, "2.3"}, {modules, [array, base64, beam_lib, diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup index d4db0c865e..fb2e12f03c 100644 --- a/bootstrap/lib/stdlib/ebin/stdlib.appup +++ b/bootstrap/lib/stdlib/ebin/stdlib.appup @@ -15,11 +15,13 @@ %% under the License. %% %% %CopyrightEnd% -{"2.0", +{"2.3", %% Up from - max one major revision back - [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17 + [{<<"2\\.[1-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3 + {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0 {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16 %% Down to - max one major revision back - [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17 + [{<<"2\\.[1-2](\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1-17.3 + {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0 {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16 }. diff --git a/configure.in b/configure.in index be169b8428..0e09af4eff 100644 --- a/configure.in +++ b/configure.in @@ -266,6 +266,13 @@ AC_ARG_WITH(ssl-incl, AS_HELP_STRING([--with-ssl-incl=PATH], [location of OpenSSL include dir, if different than specified by --with-ssl=PATH])) +AC_ARG_WITH(ssl-rpath, +AS_HELP_STRING([--with-ssl-rpath=yes|no|PATHS], + [runtime library path for OpenSSL. Default is 'yes', which equates to a + number of standard locations. If 'no', then no runtime + library paths wil be used. Anything else should be a + comma separated list of paths.])) + AC_ARG_ENABLE(dynamic-ssl-lib, AS_HELP_STRING([--disable-dynamic-ssl-lib], [disable using dynamic openssl libraries])) @@ -416,7 +423,7 @@ AC_SUBST(NATIVE_LIBS_ENABLED) rm -f $ERL_TOP/lib/SKIP-APPLICATIONS for app in `cd lib && ls -d *`; do var=`eval echo \\$with_$app` - if test X${var} == Xno; then + if test X${var} = Xno; then echo "$app" >> $ERL_TOP/lib/SKIP-APPLICATIONS fi done diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index ed492d55ff..d78025b0be 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -1421,9 +1421,31 @@ case "$THR_LIB_NAME" in int z; AO_nop_full(); +#if defined(AO_HAVE_store) AO_store(&x, (AO_t) 0); +#elif defined(AO_HAVE_store_release) + AO_store_release(&x, (AO_t) 0); +#else +#error No store +#endif +#if defined(AO_HAVE_load) z = AO_load(&x); +#elif defined(AO_HAVE_load_acquire) + z = AO_load_acquire(&x); +#else +#error No load +#endif +#if defined(AO_HAVE_compare_and_swap_full) z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); +#elif defined(AO_HAVE_compare_and_swap_release) + z = AO_compare_and_swap_release(&x, (AO_t) 0, (AO_t) 1); +#elif defined(AO_HAVE_compare_and_swap_acquire) + z = AO_compare_and_swap_acquire(&x, (AO_t) 0, (AO_t) 1); +#elif defined(AO_HAVE_compare_and_swap) + z = AO_compare_and_swap(&x, (AO_t) 0, (AO_t) 1); +#else +#error No compare_and_swap +#endif ], [ethr_have_native_atomics=yes ethr_have_libatomic_ops=yes]) diff --git a/erts/configure.in b/erts/configure.in index 766e35fb2b..b3fe48d62c 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1691,10 +1691,13 @@ systemd_daemon_save_LIBS=$LIBS LIBS= AC_SEARCH_LIBS(sd_listen_fds,[systemd systemd-daemon], [have_sd_listen_fds=yes],[have_sd_listen_fds=no],$systemd_daemon_save_LIBS) +AC_SEARCH_LIBS(sd_notify,[systemd systemd-daemon], + [have_sd_notify=yes],[have_sd_notify=no],$systemd_daemon_save_LIBS) AC_CHECK_HEADERS(systemd/sd-daemon.h, [have_systemd_sd_daemon_h=yes],[have_systemd_sd_daemon_h=no]) if test x"$have_sd_listen_fds" = x"yes" && \ + test x"$have_sd_notify" = x"yes" && \ test x"$have_systemd_sd_daemon_h" = x"yes"; then AC_DEFINE([HAVE_SYSTEMD_DAEMON],[1],[Define if you have systemd daemon]) SYSTEMD_DAEMON_LIBS=$LIBS @@ -1781,7 +1784,7 @@ if test x"$ac_cv_header_netinet_sctp_h" = x"yes"; then AC_CHECK_DECLS([SCTP_UNORDERED, SCTP_ADDR_OVER, SCTP_ABORT, SCTP_EOF, SCTP_SENDALL, SCTP_ADDR_CONFIRMED, SCTP_DELAYED_ACK_TIME, - SCTP_EMPTY, + SCTP_EMPTY, SCTP_UNCONFIRMED, SCTP_CLOSED, SCTPS_IDLE, SCTP_BOUND, SCTPS_BOUND, SCTP_LISTEN, SCTPS_LISTEN, @@ -2109,6 +2112,17 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop flockfile fstat strlcpy strlcat setsid posix2time time2posix \ setlocale nl_langinfo poll mlockall]) +AC_MSG_CHECKING([for isfinite]) +AC_TRY_LINK([#include <math.h>], + [isfinite(0);], have_isfinite=yes, have_isfinite=no), + +if test $have_isfinite = yes; then + AC_DEFINE(HAVE_ISFINITE,[1], + [Define to 1 if you have the `isfinite' function.]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi case X$erl_xcomp_posix_memalign in Xno) ;; @@ -3956,6 +3970,7 @@ if test "$enable_dtrace_test" = "yes" ; then DTRACE_ENABLED_2STEP=yes fi], []) + $RM -f foo-dtrace.h AS_IF([test "x$DTRACE_ENABLED_2STEP" = "xyes"], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) @@ -4091,6 +4106,20 @@ esac ], [with_ssl_incl=$with_ssl]) #default +AC_ARG_WITH(ssl-rpath, +AS_HELP_STRING([--with-ssl-rpath=yes|no|PATHS], + [runtime library path for OpenSSL. Default is "yes", which equates to a + number of standard locations. If "no", then no runtime + library paths wil be used. Anything else should be a + comma separated list of paths.]), +[ +case X$with_ssl in + Xno) AC_MSG_ERROR([--with-ssl-rpath set without --with-ssl]);; +esac +], +[with_ssl_rpath=yes]) #default + + AC_ARG_ENABLE(dynamic-ssl-lib, AS_HELP_STRING([--disable-dynamic-ssl-lib], [disable using dynamic openssl libraries]), @@ -4556,7 +4585,12 @@ cc_rflg="$CFLAG_RUNTIME_LIBRARY_PATH" ld_rflg="$LDFLAG_RUNTIME_LIBRARY_PATH" ded_ld_rflg="$DED_LD_FLAG_RUNTIME_LIBRARY_PATH" -if test "$SSL_APP" != "" && test "$SSL_DYNAMIC_ONLY" = "yes" && \ + +case "$with_ssl_rpath" in + +yes) # Use standard lib locations for ssl runtime library path + + if test "$SSL_APP" != "" && test "$SSL_DYNAMIC_ONLY" = "yes" && \ { test "$cc_rflg" != "" || test "$ld_rflg" != "" || test "$ded_ld_rflg" != ""; } ; then AC_MSG_CHECKING(for ssl runtime library path to use) @@ -4640,7 +4674,25 @@ if test "$SSL_APP" != "" && test "$SSL_DYNAMIC_ONLY" = "yes" && \ AC_MSG_RESULT([$rpath]) test "$rpath" != "" || AC_MSG_WARN([Cannot set run path during linking]) -fi + fi + ;; + +no) # Use no ssl runtime library path + SSL_DED_LD_RUNTIME_LIBRARY_PATH= + ;; + +*) # Use ssl runtime library paths set by --with-ssl-rpath (without any check) + ded_ld_rpath= + delimit= + for dir in `echo $with_ssl_rpath | sed "s/,/ /g"`; do + ded_ld_rpath="$ded_ld_rpath$delimit$ded_ld_rflg$dir" + delimit=" " + done + SSL_DED_LD_RUNTIME_LIBRARY_PATH="$ded_ld_rpath" + ;; + +esac + #-------------------------------------------------------------------- # Os mon stuff. @@ -4817,7 +4869,7 @@ AH_BOTTOM([ #define HAVE_GETHRVTIME #endif -#ifndef HAVE_FINITE +#if !defined(HAVE_ISFINITE) && !defined(HAVE_FINITE) # if defined(HAVE_ISINF) && defined(HAVE_ISNAN) # define USE_ISINF_ISNAN # endif diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml index d3de29b876..2b5fc877c3 100644 --- a/erts/doc/src/crash_dump.xml +++ b/erts/doc/src/crash_dump.xml @@ -115,8 +115,9 @@ sockets/pipes can be used simultaneously by Erlang (due to limitations in the Unix <c><![CDATA[select]]></c> call). The number of open regular files is not affected by this.</item> - <item>"Received SIGUSR1" - The SIGUSR1 signal was sent to the - Erlang machine (Unix only).</item> + <item>"Received SIGUSR1" - Sending the SIGUSR1 signal to a + Erlang machine (Unix only) forces a crash dump. This slogan reflects + that the Erlang machine crash-dumped due to receiving that signal.</item> <item>"Kernel pid terminated (<em>Who</em>) (<em>Exit-reason</em>)" - The kernel supervisor has detected a failure, usually that the <c><![CDATA[application_controller]]></c> diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index f856b9ab86..d11f6b0c6d 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -525,7 +525,8 @@ core dump and no crash dump if an internal error is detected.</p> <p>Calling <c>erlang:halt/1</c> with a string argument will still - produce a crash dump.</p> + produce a crash dump. On Unix systems, sending an emulator process + a SIGUSR1 signal will also force a crash dump.</p> </item> <tag><marker id="+e"><c><![CDATA[+e Number]]></c></marker></tag> <item> @@ -1141,6 +1142,23 @@ <p>For more information, see <seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p> </item> + <tag><marker id="+secio"><c>+secio true|false</c></marker></tag> + <item> + <p>Enable or disable eager check I/O scheduling. The default + is currently <c>false</c>, but will most likely be changed + to <c>true</c> in OTP 18. The behaviour before this flag + was introduced corresponds to <c>+secio false</c>.</p> + <p>The flag effects when schedulers will check for I/O + operations possible to execute, and when such I/O operations + will execute. As the name of the parameter implies, + schedulers will be more eager to check for I/O when + <c>true</c> is passed. This however also implies that + execution of outstanding I/O operation will not be + prioritized to the same extent as when <c>false</c> is + passed.</p> + <p><seealso marker="erlang#system_info_eager_check_io"><c>erlang:system_info(eager_check_io)</c></seealso> + returns the value of this parameter used when starting the VM.</p> + </item> <tag><marker id="+sfwi"><c>+sfwi Interval</c></marker></tag> <item> <p>Set scheduler forced wakeup interval. All run queues will diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 4a1aab75c7..77fc906aca 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -2033,7 +2033,8 @@ ERL_DRV_MAP int sz entry function is called. If <c>ready_async</c> is null in the driver entry, the <c>async_free</c> function is called instead.</p> - <p>The return value is a handle to the asynchronous task.</p> + <p>The return value is -1 if the <c>driver_async</c> call + fails.</p> <note> <p>As of erts version 5.5.4.3 the default stack size for threads in the async-thread pool is 16 kilowords, diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml index fa083db4c7..a6e7dddbed 100644 --- a/erts/doc/src/erl_ext_dist.xml +++ b/erts/doc/src/erl_ext_dist.xml @@ -126,9 +126,8 @@ However, only characters that can be encoded using Latin1 (ISO-8859-1) are currently supported in atoms. The support for UTF-8 encoded atoms in the external format has been implemented in order to be able to support - all Unicode characters in atoms in <em>some future release</em>. Full - support for Unicode atoms will not happen before OTP-R18, and might - be introduced even later than that. Until full Unicode support for + all Unicode characters in atoms in <em>some future release</em>. + Until full Unicode support for atoms has been introduced, it is an <em>error</em> to pass atoms containing characters that cannot be encoded in Latin1, and <em>the behavior is undefined</em>.</p> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 84168397f6..cba2c07959 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2840,7 +2840,7 @@ os_prompt% </pre> raised. The error reason may differ between operating systems. Typically the error <c>enoent</c> is raised when one tries to run a program that is not found and - <c>eaccess</c> is raised when the given file is not + <c>eacces</c> is raised when the given file is not executable.</p> </item> <tag><c>{fd, <anno>In</anno>, <anno>Out</anno>}</c></tag> @@ -5775,6 +5775,7 @@ ok <name name="system_info" arity="1" clause_i="52"/> <name name="system_info" arity="1" clause_i="53"/> <name name="system_info" arity="1" clause_i="54"/> + <name name="system_info" arity="1" clause_i="55"/> <fsummary>Information about the system</fsummary> <desc> <p>Returns various information about the current system @@ -5970,6 +5971,16 @@ ok The return value will always be <c>false</c> since the elib_malloc allocator has been removed.</p> </item> + <tag><marker id="system_info_eager_check_io"><c>eager_check_io</c></marker></tag> + <item> + <p> + Returns the value of the <c>erl</c> + <seealso marker="erl#+secio">+secio</seealso> command line + flag which is either <c>true</c> or <c>false</c>. See the + documentation of the command line flag for information about + the different values. + </p> + </item> <tag><c>ets_limit</c></tag> <item> <p>Returns the maximum number of ETS tables allowed. This limit @@ -6133,6 +6144,11 @@ ok <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p> </item> + <tag><c>nif_version</c></tag> + <item> + <p>Returns a string containing the erlang NIF version + used by the runtime system. It will be on the form "<major ver>.<minor ver>".</p> + </item> <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag> <item> <p>Returns a string containing the OTP release number of the diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 743369951f..af0d4d7377 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,6 +30,342 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 6.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix getifaddrs realloc pointer error</p> + <p> + When a buffer was exhausted and subsequently reallocated, + we could get an unsafe pointer pointing to faulty memory.</p> + <p> + For this to occur we would need to have a large number of + interfaces and a reallocation of memory to a lower + addresses.</p> + <p> + The symptom would be garbage returned from + erlang:port_control(Port, 25, []) + (prim_inet:getifaddrs(Port) resulting in a badarg) or a + segmentation fault.</p> + <p> + Own Id: OTP-12445</p> + </item> + <item> + <p> + Don't close all file descriptors twice in child_setup</p> + <p> + The commit c2b4eab25c907f453a394d382c04cd04e6c06b49 + introduced an error in which child_setup erroneously + tried to close all file descriptors twice.</p> + <p> + Use closefrom() if available when closing all file + descriptors.</p> + <p> + The function closefrom() was only used in the vfork() + case before but is now also used in the fork() case if + available.</p> + <p> + Own Id: OTP-12446</p> + </item> + <item> + <p> + During a crashdump all file descriptors are closed to + ensure the closing of the epmd port and to reserve a file + descriptor for the crashdump file.</p> + <p> + If a driver (third party library) cannot handle closing + of sockets this could result in a segmentation fault in + which case a crashdump would not be produced. This is now + fixed by only closing inets sockets via an emergency + close callback to the driver and thus closing the epmd + socket.</p> + <p> + Own Id: OTP-12447</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 6.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix HiPE debug lock checking on OS X 64bit</p> + <p> + Position-independent code is mandatory on OS X. We use + r11 as an intermediate register to fill + BIF_P->hipe.bif_callee. This fixes the following error + when doing `make debug FLAVOR=smp`:</p> + <p> + clang -cc1as: fatal error: error in backend: 32-bit + absolute addressing is not supported in 64-bit mode</p> + <p> + Own Id: OTP-12188</p> + </item> + <item> + <p> + Fix race bug that could cause VM crash in + <c>erlang:port_get_data/1</c> if the port was closed by a + concurrent process. Also fix fatal bug if + <c>port_set_data/2</c> is called with a non-immediate + data term. Both bugs exist since R16B01.</p> + <p> + Own Id: OTP-12208</p> + </item> + <item> + <p> + Correct make variable SSL_DED_LD_RUNTIME_LIBRARY_PATH + when erl_xcomp_sysroot ends with a slash.</p> + <p> + Own Id: OTP-12216 Aux Id: seq12700 </p> + </item> + <item> + <p> + Fix two cases of unreachable code caused by false use of + assigment operators.</p> + <p> + Own Id: OTP-12222</p> + </item> + <item> + <p> + Fix bug when hipe compiled code makes tail call to a BIF + that disables GC while trapping (sush as binary_to_list, + list_to_binary, binary_to_term, term_to_binary).</p> + <p> + Own Id: OTP-12231</p> + </item> + <item> + <p> + Fix bug when a migrated empty memory carrier is reused + just before it should be destroyed by the thread that + created it.</p> + <p> + Own Id: OTP-12249</p> + </item> + <item> + <p> + Prevents compile-time errors in NIFs, when the compiler + is instructed to treat missing field initializers as + errors, by adding an initializer for the new options + field which was added to ErlNifEntry for 17.3.</p> + <p> + Own Id: OTP-12266</p> + </item> + <item> + <p> + Fixed CPU topology detection on FreeBSD systems where + Erlang/OTP is compiled by new C compilers (including, but + possibly not limited to, gcc 4.9 and clang).</p> + <p> + Own Id: OTP-12267</p> + </item> + <item> + <p> + Use C99 function isfinite() instead of finite() when + available on non GCC compilers.</p> + <p> + Own Id: OTP-12268</p> + </item> + <item> + <p> + Fix bug on windows where an incorrect number of links + could be returned when doing file:read_file_info on a + directory.</p> + <p> + Own Id: OTP-12269</p> + </item> + <item> + <p> + Fix rare bug when purging module on VM started with + +Meamin.</p> + <p> + Own Id: OTP-12273</p> + </item> + <item> + <p> + Repair run_erl terminal window size adjustment sent from + to_erl. This was broken in OTP 17.0 which could lead to + strange cursor behaviour in the to_erl shell.</p> + <p> + Own Id: OTP-12275 Aux Id: seq12739 </p> + </item> + <item> + <p> + Fixed bug on windows causing gen_tcp/udp to return an + error when given an fd to work with.</p> + <p> + Own Id: OTP-12289</p> + </item> + <item> + <p> + Fix various internal erts issues where negating a signed + integer in C would trigger undefined behavior. This fixes + issues when dividing with bignums and list_to_integer.</p> + <p> + Own Id: OTP-12290</p> + </item> + <item> + <p> + When flushing output to stdout on windows, the emulator + could sometimes hang indefinitely waiting for the flush + to complete. This has been fixed.</p> + <p> + Own Id: OTP-12291</p> + </item> + <item> + <p> + Fix so that non-smp emulators with dirty scheduler + support shows the correct number of dirty schedulers when + calling erlang:system_info(system_version).</p> + <p> + Own Id: OTP-12295</p> + </item> + <item> + <p> + Add <c>nif_version</c> to <c>erlang:system_info/1</c> in + order to get the NIF API version of the runtime system in + a way similar to <c>driver_version</c>.</p> + <p> + Own Id: OTP-12298</p> + </item> + <item> + <p> + Fix bug that could cause the return value from dirty NIF + with zero arity to be treated as garbage, leading to VM + crash.</p> + <p> + Own Id: OTP-12300</p> + </item> + <item> + <p> + Improve allocation carrier migration search logic. This + will reduce the risk of failed migrations that could lead + to excess memory consumption. It will also improve smp + performance due to reduced memory contention on the + migration pool.</p> + <p> + Own Id: OTP-12323</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Introduced support for eager check I/O.</p> + <p>By default eager check I/O will be disabled, but this + will most likely be changed in OTP 18. When eager check + I/O is enabled, schedulers will more frequently check for + I/O work. Outstanding I/O operations will however not be + prioritized to the same extent as when eager check I/O is + disabled.</p> + <p>Eager check I/O can be enabled using the <c>erl</c> + command line argument: <seealso + marker="erl#+secio"><c>+secio true</c></seealso></p> + <p>Characteristics impact when enabled:</p> <list> + <item>Lower latency and smoother management of externally + triggered I/O operations.</item> <item>A slightly reduced + priority of externally triggered I/O operations.</item> + </list> + <p> + Own Id: OTP-12117</p> + </item> + <item> + <p> + Fix erts .app-file</p> + <p> + Own Id: OTP-12189</p> + </item> + <item> + <p> + Add configure option --with-ssl-incl=PATH to support + OpenSSL installations with headers and libraries at + different places.</p> + <p> + Own Id: OTP-12215 Aux Id: seq12700 </p> + </item> + <item> + <p> + Optimization of atomic memory operations with release + barrier semantics on 32-bit PowerPC when using the + implementation included in OTP.</p> + <p> + Own Id: OTP-12250</p> + </item> + <item> + <p> + Minor adjustment of scheduler activation code making sure + that an activation of a scheduler is not prevented by its + run-queue being non-empty. (Thanks to Songlu Cai)</p> + <p> + Own Id: OTP-12287</p> + </item> + <item> + <p> + Improved support for atomic memory operations provided by + the <url + href="https://github.com/ivmai/libatomic_ops/"><c>libatomic_ops</c></url> + library. Most importantly support for use of native + double word atomics when implemented by + <c>libatomic_ops</c> (for example, implemented for ARM).</p> + <p> + The <seealso + marker="doc/installation_guide:INSTALL#Advanced-configuration-and-build-of-ErlangOTP_Configuring_Atomic-Memory-Operations-and-the-VM"><c>$ERL_TOP/HOWTO/INSTALL.md</c></seealso> + document now also more clearly describes when you want to + build together with a <c>libatomic_ops</c> installation.</p> + <p> + Own Id: OTP-12302</p> + </item> + <item> + <p> + Add configure option --with-ssl-rpath to control which + runtime library path to use for dynamic linkage toward + OpenSSL.</p> + <p> + Own Id: OTP-12316 Aux Id: seq12753 </p> + </item> + <item> + <p> + Added systemd notify support to epmd</p> + <p> + Own Id: OTP-12321</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 6.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bug when an migrated empty memory carrier is reused + just before it should be destroyed by the thread that + created it.</p> + <p> + Own Id: OTP-12249</p> + </item> + <item> + <p> + Repair run_erl terminal window size adjustment sent from + to_erl. This was broken in OTP 17.0 which could lead to + strange cursor behaviour in the to_erl shell.</p> + <p> + Own Id: OTP-12275 Aux Id: seq12739 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 6.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml index 11a7437f5a..da8ccdecdf 100644 --- a/erts/doc/src/zlib.xml +++ b/erts/doc/src/zlib.xml @@ -302,7 +302,7 @@ list_to_binary([B1,B2])</pre> <fsummary>Decompress data</fsummary> <desc> <p><c>inflate/2</c> decompresses as much data as possible. - It may some introduce some output latency (reading + It may introduce some output latency (reading input without producing any output).</p> <p>If a preset dictionary is needed at this point (see <c>inflateSetDictionary</c> below), <c>inflate/2</c> throws a diff --git a/erts/emulator/beam/beam_ranges.c b/erts/emulator/beam/beam_ranges.c index 0f2d5d0c2a..cb6470638f 100644 --- a/erts/emulator/beam/beam_ranges.c +++ b/erts/emulator/beam/beam_ranges.c @@ -282,7 +282,7 @@ find_range(BeamInstr* pc) while (low < high) { if (pc < mid->start) { high = mid; - } else if (pc > RANGE_END(mid)) { + } else if (pc >= RANGE_END(mid)) { low = mid + 1; } else { erts_smp_atomic_set_nob(&r[active].mid, (erts_aint_t) mid); diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index a5be8e1529..42dd160e38 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2772,6 +2772,7 @@ static int do_list_to_integer(Process *p, Eterm orig_list, Eterm *integer, Eterm *rest) { Sint i = 0; + Uint ui = 0; int skip = 0; int neg = 0; int n = 0; @@ -2825,8 +2826,8 @@ static int do_list_to_integer(Process *p, Eterm orig_list, unsigned_val(CAR(list_val(lst))) > '9') { break; } - i = i * 10; - i = i + unsigned_val(CAR(list_val(lst))) - '0'; + ui = ui * 10; + ui = ui + unsigned_val(CAR(list_val(lst))) - '0'; n++; lst = CDR(list_val(lst)); if (is_nil(lst)) { @@ -2850,7 +2851,8 @@ static int do_list_to_integer(Process *p, Eterm orig_list, */ if (n <= SMALL_DIGITS) { /* It must be small */ - if (neg) i = -i; + if (neg) i = -(Sint)ui; + else i = (Sint)ui; res = make_small(i); } else { lg2 = (n+1)*230/69+1; diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index a8710dd910..de7d370938 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -274,10 +274,9 @@ _b = _b << _s; \ _vn1 = _b >> H_EXP; \ _vn0 = _b & LO_MASK; \ - /* Sometimes _s is 0 which triggers undefined behaviour for the \ - (_a0>>(D_EXP-_s)) shift, but this is ok because the \ - & -s will make it all to 0 later anyways. */ \ - _un32 = (_a1 << _s) | ((_a0>>(D_EXP-_s)) & (-_s >> (D_EXP-1))); \ + /* If needed to avoid undefined behaviour */ \ + if (_s) _un32 = (_a1 << _s) | ((_a0>>(D_EXP-_s)) & (-_s >> (D_EXP-1))); \ + else _un32 = _a1; \ _un10 = _a0 << _s; \ _un1 = _un10 >> H_EXP; \ _un0 = _un10 & LO_MASK; \ diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index 08265b590d..2cddfe2800 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -181,7 +181,6 @@ static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext) ASSERT(is_node_name_atom(mon->pid)); erts_print(to, to_arg, "%s{to,{%T,%T},%T}", prefix, mon->name, mon->pid, mon->ref); - erts_print(to, to_arg,"}"); } else if (is_atom(mon->name)){ /* local by name */ erts_print(to, to_arg, "%s{to,{%T,%T},%T}", prefix, mon->name, erts_this_dist_entry->sysname, mon->ref); diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index df33bbc2f7..21434eb117 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -398,6 +398,7 @@ type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state type DRV_EV_D_STATE FIXED_SIZE SYSTEM driver_event_data_state type DRV_SEL_D_STATE FIXED_SIZE SYSTEM driver_select_data_state type FD_LIST SHORT_LIVED SYSTEM fd_list +type ACTIVE_FD_ARR SHORT_LIVED SYSTEM active_fd_array type POLLSET LONG_LIVED SYSTEM pollset type POLLSET_UPDREQ SHORT_LIVED SYSTEM pollset_update_req type POLL_FDS LONG_LIVED SYSTEM poll_fds diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index a4e164bf51..e3172dc4fb 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -205,7 +205,7 @@ MBC after deallocating first block: ASSERT(((UWord)(F) & (~FLG_MASK|THIS_FREE_BLK_HDR_FLG|PREV_FREE_BLK_HDR_FLG)) == THIS_FREE_BLK_HDR_FLG), \ (B)->bhdr = ((Sz) | (F)), \ (B)->u.carrier = (C)) - + # define IS_MBC_FIRST_ABLK(AP,B) \ ((((UWord)(B) & ~ERTS_SACRR_UNIT_MASK) == MBC_HEADER_SIZE(AP)) \ && ((B)->bhdr & MBC_ABLK_OFFSET_MASK) == 0) @@ -378,9 +378,8 @@ do { \ #ifdef ERTS_SMP #define SBC_HEADER_SIZE \ - (UNIT_CEILING(sizeof(Carrier_t) \ - - sizeof(ErtsAlcCPoolData_t) \ - + ABLK_HDR_SZ) \ + (UNIT_CEILING(offsetof(Carrier_t, cpool) \ + + ABLK_HDR_SZ) \ - ABLK_HDR_SZ) #else #define SBC_HEADER_SIZE \ @@ -929,6 +928,88 @@ unlink_carrier(CarrierList_t *cl, Carrier_t *crr) #ifdef ERTS_SMP +#ifdef DEBUG +static int is_in_list(ErtsDoubleLink_t* sentinel, ErtsDoubleLink_t* node) +{ + ErtsDoubleLink_t* p; + + ASSERT(node != sentinel); + for (p = sentinel->next; p != sentinel; p = p->next) { + if (p == node) + return 1; + } + return 0; +} +#endif /* DEBUG */ + +static ERTS_INLINE void +link_edl_after(ErtsDoubleLink_t* after_me, ErtsDoubleLink_t* node) +{ + ErtsDoubleLink_t* before_me = after_me->next; + ASSERT(node != after_me && node != before_me); + node->next = before_me; + node->prev = after_me; + before_me->prev = node; + after_me->next = node; +} + +static ERTS_INLINE void +link_edl_before(ErtsDoubleLink_t* before_me, ErtsDoubleLink_t* node) +{ + ErtsDoubleLink_t* after_me = before_me->prev; + ASSERT(node != before_me && node != after_me); + node->next = before_me; + node->prev = after_me; + before_me->prev = node; + after_me->next = node; +} + +static ERTS_INLINE void +unlink_edl(ErtsDoubleLink_t* node) +{ + node->next->prev = node->prev; + node->prev->next = node->next; +} + +static ERTS_INLINE void +relink_edl_before(ErtsDoubleLink_t* before_me, ErtsDoubleLink_t* node) +{ + if (node != before_me && node != before_me->prev) { + unlink_edl(node); + link_edl_before(before_me, node); + } +} + +static ERTS_INLINE int is_abandoned(Carrier_t *crr) +{ + return crr->cpool.abandoned.next != NULL; +} + +static ERTS_INLINE void +link_abandoned_carrier(ErtsDoubleLink_t* list, Carrier_t *crr) +{ + ASSERT(!is_abandoned(crr)); + + link_edl_after(list, &crr->cpool.abandoned); + + ASSERT(crr->cpool.abandoned.next != &crr->cpool.abandoned); + ASSERT(crr->cpool.abandoned.prev != &crr->cpool.abandoned); +} + +static ERTS_INLINE void +unlink_abandoned_carrier(Carrier_t *crr) +{ + ASSERT(is_in_list(&crr->cpool.orig_allctr->cpool.pooled_list, + &crr->cpool.abandoned) || + is_in_list(&crr->cpool.orig_allctr->cpool.traitor_list, + &crr->cpool.abandoned)); + + unlink_edl(&crr->cpool.abandoned); + + crr->cpool.abandoned.next = NULL; + crr->cpool.abandoned.prev = NULL; +} + static ERTS_INLINE void clear_busy_pool_carrier(Allctr_t *allctr, Carrier_t *crr) { @@ -955,7 +1036,7 @@ clear_busy_pool_carrier(Allctr_t *allctr, Carrier_t *crr) } } -#endif +#endif /* ERTS_SMP */ #if 0 #define ERTS_DBG_CHK_FIX_LIST(A, FIX, IX, B) \ @@ -1775,6 +1856,18 @@ handle_delayed_dealloc(Allctr_t *allctr, * data has been overwritten by the queue. */ Carrier_t *crr = FIRST_BLK_TO_MBC(allctr, blk); + + /* Restore word overwritten by the dd-queue as it will be read + * if this carrier is pulled from dc_list by cpool_fetch() + */ + ERTS_ALC_CPOOL_ASSERT(FBLK_TO_MBC(blk) != crr); + ERTS_ALC_CPOOL_ASSERT(sizeof(ErtsAllctrDDBlock_t) == sizeof(void*)); +#ifdef MBC_ABLK_OFFSET_BITS + blk->u.carrier = crr; +#else + blk->carrier = crr; +#endif + ERTS_ALC_CPOOL_ASSERT(ERTS_ALC_IS_CPOOL_ENABLED(allctr)); ERTS_ALC_CPOOL_ASSERT(allctr == crr->cpool.orig_allctr); ERTS_ALC_CPOOL_ASSERT(((erts_aint_t) allctr) @@ -2563,10 +2656,9 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint32 alcu_flgs, #ifdef ERTS_SMP #define ERTS_ALC_MAX_DEALLOC_CARRIER 10 -#define ERTS_ALC_CPOOL_MAX_FETCH_INSPECT 10 +#define ERTS_ALC_CPOOL_MAX_FETCH_INSPECT 20 +#define ERTS_ALC_CPOOL_MAX_TRAITOR_INSPECT 10 #define ERTS_ALC_CPOOL_CHECK_LIMIT_COUNT 100 -#define ERTS_ALC_CPOOL_MAX_NO_CARRIERS 5 -#define ERTS_ALC_CPOOL_INSERT_ALLOWED_OFFSET 100 #define ERTS_ALC_CPOOL_MAX_FAILED_STAT_READS 3 #define ERTS_ALC_CPOOL_PTR_MOD_MRK (((erts_aint_t) 1) << 0) @@ -2743,9 +2835,6 @@ cpool_insert(Allctr_t *allctr, Carrier_t *crr) (erts_aint_t) CARRIER_SZ(crr)); erts_atomic_inc_nob(&allctr->cpool.stat.no_carriers); - erts_smp_atomic_set_nob(&crr->allctr, - ((erts_aint_t) allctr)|ERTS_CRR_ALCTR_FLG_IN_POOL); - /* * We search in 'next' direction and begin by passing * one element before trying to insert. This in order to @@ -2804,6 +2893,9 @@ cpool_insert(Allctr_t *allctr, Carrier_t *crr) cpool_set_mod_marked(&cpd2p->prev, (erts_aint_t) &crr->cpool, (erts_aint_t) cpd1p); + + erts_smp_atomic_set_wb(&crr->allctr, + ((erts_aint_t) allctr)|ERTS_CRR_ALCTR_FLG_IN_POOL); } static void @@ -2904,59 +2996,163 @@ cpool_delete(Allctr_t *allctr, Allctr_t *prev_allctr, Carrier_t *crr) static Carrier_t * cpool_fetch(Allctr_t *allctr, UWord size) { - int i; + int i, i_stop, has_passed_sentinel; Carrier_t *crr; ErtsAlcCPoolData_t *cpdp; - ErtsAlcCPoolData_t *sentinel = &carrier_pool[allctr->alloc_no].sentinel; + ErtsAlcCPoolData_t *cpool_entrance; + ErtsAlcCPoolData_t *sentinel; + ErtsDoubleLink_t* dl; + ErtsDoubleLink_t* first_old_traitor; ERTS_ALC_CPOOL_ASSERT(allctr->alloc_no == ERTS_ALC_A_INVALID /* testcase */ || erts_thr_progress_is_managed_thread()); - i = 0; + i = ERTS_ALC_CPOOL_MAX_FETCH_INSPECT; + first_old_traitor = allctr->cpool.traitor_list.next; + cpool_entrance = NULL; - /* First; check our own pending dealloc carrier list... */ - crr = allctr->cpool.dc_list.last; - while (crr && i < ERTS_ALC_CPOOL_MAX_FETCH_INSPECT) { - if (erts_atomic_read_nob(&crr->cpool.max_size) >= size) { - unlink_carrier(&allctr->cpool.dc_list, crr); -#ifdef ERTS_ALC_CPOOL_DEBUG - ERTS_ALC_CPOOL_ASSERT(erts_smp_atomic_xchg_nob(&crr->allctr, - ((erts_aint_t) allctr)) - == (((erts_aint_t) allctr) & ~ERTS_CRR_ALCTR_FLG_MASK)); -#else - erts_smp_atomic_set_nob(&crr->allctr, ((erts_aint_t) allctr)); -#endif - return crr; + /* + * Search my own pooled_list, + * i.e my abandoned carriers that were in the pool last time I checked. + */ + + dl = allctr->cpool.pooled_list.next; + while(dl != &allctr->cpool.pooled_list) { + erts_aint_t exp, act; + crr = (Carrier_t *) (((char *) dl) - offsetof(Carrier_t, cpool.abandoned)); + + ASSERT(!is_in_list(&allctr->cpool.traitor_list, dl)); + ASSERT(crr->cpool.orig_allctr == allctr); + dl = dl->next; + exp = erts_smp_atomic_read_rb(&crr->allctr); + if ((exp & ERTS_CRR_ALCTR_FLG_MASK) == ERTS_CRR_ALCTR_FLG_IN_POOL + && erts_atomic_read_nob(&crr->cpool.max_size) >= size) { + /* Try to fetch it... */ + act = erts_smp_atomic_cmpxchg_mb(&crr->allctr, + (erts_aint_t) allctr, + exp); + if (act == exp) { + cpool_delete(allctr, ((Allctr_t *) (act & ~ERTS_CRR_ALCTR_FLG_MASK)), crr); + unlink_abandoned_carrier(crr); + + /* Move sentinel to continue next search from here */ + relink_edl_before(dl, &allctr->cpool.pooled_list); + return crr; + } + exp = act; + } + if (exp & ERTS_CRR_ALCTR_FLG_IN_POOL) { + if (!cpool_entrance) + cpool_entrance = &crr->cpool; + } + else { /* Not in pool, move to traitor_list */ + unlink_abandoned_carrier(crr); + link_abandoned_carrier(&allctr->cpool.traitor_list, crr); + } + if (--i <= 0) { + /* Move sentinel to continue next search from here */ + relink_edl_before(dl, &allctr->cpool.pooled_list); + return NULL; } - crr = crr->prev; - i++; } - /* ... then the pool ... */ + /* Now search traitor_list. + * i.e carriers employed by other allocators last time I checked. + * They might have been abandoned since then. + */ + + i_stop = (i < ERTS_ALC_CPOOL_MAX_TRAITOR_INSPECT ? + 0 : i - ERTS_ALC_CPOOL_MAX_TRAITOR_INSPECT); + dl = first_old_traitor; + while(dl != &allctr->cpool.traitor_list) { + erts_aint_t exp, act; + crr = (Carrier_t *) (((char *) dl) - offsetof(Carrier_t, cpool.abandoned)); + ASSERT(dl != &allctr->cpool.pooled_list); + ASSERT(crr->cpool.orig_allctr == allctr); + dl = dl->next; + exp = erts_smp_atomic_read_rb(&crr->allctr); + if (exp & ERTS_CRR_ALCTR_FLG_IN_POOL) { + if (!(exp & ERTS_CRR_ALCTR_FLG_BUSY) + && erts_atomic_read_nob(&crr->cpool.max_size) >= size) { + /* Try to fetch it... */ + act = erts_smp_atomic_cmpxchg_mb(&crr->allctr, + (erts_aint_t) allctr, + exp); + if (act == exp) { + cpool_delete(allctr, ((Allctr_t *) (act & ~ERTS_CRR_ALCTR_FLG_MASK)), crr); + unlink_abandoned_carrier(crr); + + /* Move sentinel to continue next search from here */ + relink_edl_before(dl, &allctr->cpool.traitor_list); + return crr; + } + exp = act; + } + if (exp & ERTS_CRR_ALCTR_FLG_IN_POOL) { + if (!cpool_entrance) + cpool_entrance = &crr->cpool; + + /* Move to pooled_list */ + unlink_abandoned_carrier(crr); + link_abandoned_carrier(&allctr->cpool.pooled_list, crr); + } + } + if (--i <= i_stop) { + /* Move sentinel to continue next search from here */ + relink_edl_before(dl, &allctr->cpool.traitor_list); + if (i > 0) + break; + else + return NULL; + } + } /* - * We search in 'prev' direction and begin by passing - * one element before trying to fetch. This in order to - * avoid contention with threads inserting elements. + * Finally search the shared pool and try employ foreign carriers */ - cpdp = cpool_aint2cpd(cpool_read(&sentinel->prev)); - if (cpdp == sentinel) - return NULL; + sentinel = &carrier_pool[allctr->alloc_no].sentinel; + if (cpool_entrance) { + /* We saw a pooled carried above, use it as entrance into the pool + */ + cpdp = cpool_entrance; + } + else { + /* No pooled carried seen above. Start search at cpool sentinel, + * but begin by passing one element before trying to fetch. + * This in order to avoid contention with threads inserting elements. + */ + cpool_entrance = sentinel; + cpdp = cpool_aint2cpd(cpool_read(&cpool_entrance->prev)); + if (cpdp == sentinel) + return NULL; + } - while (i < ERTS_ALC_CPOOL_MAX_FETCH_INSPECT) { + has_passed_sentinel = 0; + while (1) { erts_aint_t exp; cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev)); - if (cpdp == sentinel) { + if (cpdp == cpool_entrance) { + if (cpool_entrance == sentinel) { + cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev)); + if (cpdp == sentinel) + return NULL; + } + i = 0; /* Last one to inspect */ + } + else if (cpdp == sentinel) { + if (has_passed_sentinel) { + /* We been here before. cpool_entrance must have been removed */ + return NULL; + } cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev)); if (cpdp == sentinel) return NULL; - i = ERTS_ALC_CPOOL_MAX_FETCH_INSPECT; /* Last one to inspect */ + has_passed_sentinel = 1; } - crr = (Carrier_t *) (((char *) cpdp) - offsetof(Carrier_t, cpool)); + crr = (Carrier_t *)(((char *)cpdp) - offsetof(Carrier_t, cpool)); exp = erts_smp_atomic_read_rb(&crr->allctr); - if (((exp & (ERTS_CRR_ALCTR_FLG_IN_POOL|ERTS_CRR_ALCTR_FLG_BUSY)) - == ERTS_CRR_ALCTR_FLG_IN_POOL) + if (((exp & (ERTS_CRR_ALCTR_FLG_MASK)) == ERTS_CRR_ALCTR_FLG_IN_POOL) && (erts_atomic_read_nob(&cpdp->max_size) >= size)) { erts_aint_t act; /* Try to fetch it... */ @@ -2965,11 +3161,35 @@ cpool_fetch(Allctr_t *allctr, UWord size) exp); if (act == exp) { cpool_delete(allctr, ((Allctr_t *) (act & ~ERTS_CRR_ALCTR_FLG_MASK)), crr); + if (crr->cpool.orig_allctr == allctr) { + unlink_abandoned_carrier(crr); + } return crr; } } - i++; + if (--i <= 0) + return NULL; + } + + /* Last; check our own pending dealloc carrier list... */ + crr = allctr->cpool.dc_list.last; + while (crr) { + if (erts_atomic_read_nob(&crr->cpool.max_size) >= size) { + unlink_carrier(&allctr->cpool.dc_list, crr); +#ifdef ERTS_ALC_CPOOL_DEBUG + ERTS_ALC_CPOOL_ASSERT(erts_smp_atomic_xchg_nob(&crr->allctr, + ((erts_aint_t) allctr)) + == (((erts_aint_t) allctr) & ~ERTS_CRR_ALCTR_FLG_MASK)); +#else + erts_smp_atomic_set_nob(&crr->allctr, ((erts_aint_t) allctr)); +#endif + return crr; + } + crr = crr->prev; + if (--i <= 0) + return NULL; } + return NULL; } @@ -3066,6 +3286,9 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr) return; } + if (is_abandoned(crr)) + unlink_abandoned_carrier(crr); + if (crr->cpool.thr_prgr == ERTS_THR_PRGR_INVALID || erts_thr_progress_has_reached(crr->cpool.thr_prgr)) { dealloc_carrier(allctr, crr, 1); @@ -3112,6 +3335,8 @@ cpool_init_carrier_data(Allctr_t *allctr, Carrier_t *crr) limit = (csz/100)*allctr->cpool.util_limit; crr->cpool.abandon_limit = limit; } + crr->cpool.abandoned.next = NULL; + crr->cpool.abandoned.prev = NULL; } static void @@ -3142,6 +3367,9 @@ abandon_carrier(Allctr_t *allctr, Carrier_t *crr) STAT_MBC_CPOOL_INSERT(allctr, crr); unlink_carrier(&allctr->mbc_list, crr); + if (crr->cpool.orig_allctr == allctr) { + link_abandoned_carrier(&allctr->cpool.pooled_list, crr); + } allctr->remove_mbc(allctr, crr); @@ -3649,6 +3877,11 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp) if (busy_pcrr_pp && *busy_pcrr_pp) { ERTS_ALC_CPOOL_ASSERT(*busy_pcrr_pp == crr); *busy_pcrr_pp = NULL; + ERTS_ALC_CPOOL_ASSERT(erts_smp_atomic_read_nob(&crr->allctr) + == (((erts_aint_t) allctr) + | ERTS_CRR_ALCTR_FLG_IN_POOL + | ERTS_CRR_ALCTR_FLG_BUSY)); + erts_smp_atomic_set_nob(&crr->allctr, ((erts_aint_t) allctr)); cpool_delete(allctr, allctr, crr); } else @@ -5528,6 +5761,10 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) allctr->min_block_size = sz; } + allctr->cpool.pooled_list.next = &allctr->cpool.pooled_list; + allctr->cpool.pooled_list.prev = &allctr->cpool.pooled_list; + allctr->cpool.traitor_list.next = &allctr->cpool.traitor_list; + allctr->cpool.traitor_list.prev = &allctr->cpool.traitor_list; allctr->cpool.dc_list.first = NULL; allctr->cpool.dc_list.last = NULL; allctr->cpool.abandon_limit = 0; diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index 7be6b1ed9d..eee920e66c 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -268,6 +268,11 @@ typedef union {char c[ERTS_ALLOC_ALIGN_BYTES]; long l; double d;} Unit_t; #ifdef ERTS_SMP +typedef struct ErtsDoubleLink_t_ { + struct ErtsDoubleLink_t_ *next; + struct ErtsDoubleLink_t_ *prev; +}ErtsDoubleLink_t; + typedef struct { erts_atomic_t next; erts_atomic_t prev; @@ -277,6 +282,7 @@ typedef struct { UWord abandon_limit; UWord blocks; UWord blocks_size; + ErtsDoubleLink_t abandoned; /* node in pooled_list or traitor_list */ } ErtsAlcCPoolData_t; #endif @@ -500,7 +506,12 @@ struct Allctr_t_ { CarrierList_t sbc_list; #ifdef ERTS_SMP struct { - CarrierList_t dc_list; + /* pooled_list, traitor list and dc_list contain only + carriers _created_ by this allocator */ + ErtsDoubleLink_t pooled_list; + ErtsDoubleLink_t traitor_list; + CarrierList_t dc_list; + UWord abandon_limit; int disable_abandon; int check_limit_count; diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 6efe9d9550..b90362d82c 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -27,6 +27,7 @@ #include "erl_process.h" #include "error.h" #include "erl_driver.h" +#include "erl_nif.h" #include "bif.h" #include "big.h" #include "erl_version.h" @@ -90,7 +91,7 @@ static char erts_system_version[] = ("Erlang/OTP " ERLANG_OTP_RELEASE " [smp:%beu:%beu]" #endif #ifdef USE_THREADS -#ifdef ERTS_DIRTY_SCHEDULERS +#if defined(ERTS_DIRTY_SCHEDULERS) && defined(ERTS_SMP) " [ds:%beu:%beu:%beu]" #endif " [async-threads:%d]" @@ -2459,6 +2460,13 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) ERL_DRV_EXTENDED_MINOR_VERSION); hp = HAlloc(BIF_P, 2*n); BIF_RET(buf_to_intlist(&hp, buf, n, NIL)); + } else if (ERTS_IS_ATOM_STR("nif_version", BIF_ARG_1)) { + char buf[42]; + int n = erts_snprintf(buf, 42, "%d.%d", + ERL_NIF_MAJOR_VERSION, + ERL_NIF_MINOR_VERSION); + hp = HAlloc(BIF_P, 2*n); + BIF_RET(buf_to_intlist(&hp, buf, n, NIL)); } else if (ERTS_IS_ATOM_STR("smp_support", BIF_ARG_1)) { #ifdef ERTS_SMP BIF_RET(am_true); @@ -2696,6 +2704,9 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) ? am_disabled : am_enabled); } + else if (ERTS_IS_ATOM_STR("eager_check_io",BIF_ARG_1)) { + BIF_RET(erts_eager_check_io ? am_true : am_false); + } BIF_ERROR(BIF_P, BADARG); } @@ -3304,17 +3315,38 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1) BIF_RET(make_small((Uint) words)); } else if (ERTS_IS_ATOM_STR("check_io_debug", BIF_ARG_1)) { - /* Used by (emulator) */ - int res; + /* Used by driver_SUITE (emulator) */ + Uint sz, *szp; + Eterm res, *hp, **hpp; + int no_errors; + ErtsCheckIoDebugInfo ciodi = {0}; #ifdef HAVE_ERTS_CHECK_IO_DEBUG erts_smp_proc_unlock(BIF_P,ERTS_PROC_LOCK_MAIN); - res = erts_check_io_debug(); + no_errors = erts_check_io_debug(&ciodi); erts_smp_proc_lock(BIF_P,ERTS_PROC_LOCK_MAIN); #else - res = 0; + no_errors = 0; #endif - ASSERT(res >= 0); - BIF_RET(erts_make_integer((Uint) res, BIF_P)); + sz = 0; + szp = &sz; + hpp = NULL; + while (1) { + res = erts_bld_tuple(hpp, szp, 4, + erts_bld_uint(hpp, szp, + (Uint) no_errors), + erts_bld_uint(hpp, szp, + (Uint) ciodi.no_used_fds), + erts_bld_uint(hpp, szp, + (Uint) ciodi.no_driver_select_structs), + erts_bld_uint(hpp, szp, + (Uint) ciodi.no_driver_event_structs)); + if (hpp) + break; + hp = HAlloc(BIF_P, sz); + szp = NULL; + hpp = &hp; + } + BIF_RET(res); } else if (ERTS_IS_ATOM_STR("process_info_args", BIF_ARG_1)) { /* Used by process_SUITE (emulator) */ diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c index 64bd598ba6..7ce950e090 100644 --- a/erts/emulator/beam/erl_bif_port.c +++ b/erts/emulator/beam/erl_bif_port.c @@ -472,7 +472,7 @@ cleanup_old_port_data(erts_aint_t data) ErtsPortDataHeap *pdhp = (ErtsPortDataHeap *) data; size_t size; ERTS_SMP_DATA_DEPENDENCY_READ_MEMORY_BARRIER; - size = sizeof(ErtsPortDataHeap) + pdhp->hsize*(sizeof(Eterm) - 1); + size = sizeof(ErtsPortDataHeap) + (pdhp->hsize-1)*sizeof(Eterm); erts_schedule_thr_prgr_later_cleanup_op(free_port_data_heap, (void *) pdhp, &pdhp->later_op, @@ -508,7 +508,7 @@ erts_port_data_size(Port *prt) } else { ErtsPortDataHeap *pdhp = (ErtsPortDataHeap *) data; - return (Uint) sizeof(ErtsPortDataHeap) + pdhp->hsize*(sizeof(Eterm)-1); + return (Uint) sizeof(ErtsPortDataHeap) + (pdhp->hsize-1)*sizeof(Eterm); } } @@ -550,7 +550,7 @@ BIF_RETTYPE port_set_data_2(BIF_ALIST_2) hsize = size_object(BIF_ARG_2); pdhp = erts_alloc(ERTS_ALC_T_PORT_DATA_HEAP, - sizeof(ErtsPortDataHeap) + hsize*(sizeof(Eterm)-1)); + sizeof(ErtsPortDataHeap) + (hsize-1)*sizeof(Eterm)); hp = &pdhp->heap[0]; pdhp->off_heap.first = NULL; pdhp->off_heap.overhead = 0; diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index f9938fc66c..e498ac70ec 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -133,7 +133,7 @@ typedef struct { #define ERL_DRV_EXTENDED_MARKER (0xfeeeeeed) #define ERL_DRV_EXTENDED_MAJOR_VERSION 3 -#define ERL_DRV_EXTENDED_MINOR_VERSION 1 +#define ERL_DRV_EXTENDED_MINOR_VERSION 2 /* * The emulator will refuse to load a driver with a major version @@ -361,6 +361,9 @@ typedef struct erl_drv_entry { /* Called on behalf of driver_select when it is safe to release 'event'. A typical unix driver would call close(event) */ + void (*emergency_close)(ErlDrvData drv_data); + /* called when the port is closed abruptly. + specifically when erl_crash_dump is called. */ /* When adding entries here, dont forget to pad in obsolete/driver.h */ } ErlDrvEntry; diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 88c4006934..61f8385efc 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -548,6 +548,8 @@ void erts_usage(void) erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); erts_fprintf(stderr, "-sct cput set cpu topology,\n"); erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); + erts_fprintf(stderr, "-secio bool enable/disable eager check I/O scheduling,\n"); + erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); #if ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT_OPT erts_fprintf(stderr, "-sub bool enable/disable scheduler utilization balancing,\n"); #else @@ -1674,6 +1676,22 @@ erl_start(int argc, char **argv) erts_usage(); } } + else if (has_prefix("ecio", sub_param)) { + arg = get_arg(sub_param+4, argv[i+1], &i); +#ifndef __OSE__ + if (sys_strcmp("true", arg) == 0) + erts_eager_check_io = 1; + else +#endif + if (sys_strcmp("false", arg) == 0) + erts_eager_check_io = 0; + else { + erts_fprintf(stderr, + "bad schedule eager check I/O value '%s'\n", + arg); + erts_usage(); + } + } else if (has_prefix("pp", sub_param)) { arg = get_arg(sub_param+2, argv[i+1], &i); if (sys_strcmp(arg, "true") == 0) diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ede5f335dc..adc3520ebb 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1646,6 +1646,7 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec ep->m = env->mod_nif; ep->fp = indirect_fp; proc->freason = TRAP; + proc->arity = argc; return THE_NON_VALUE; } diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index 226fc199a1..849024453c 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -241,21 +241,10 @@ extern TWinDynNifCallbacks WinDynNifCallbacks; # else # define ERL_NIF_INIT_DECL(MODNAME) __declspec(dllexport) ErlNifEntry* nif_init(TWinDynNifCallbacks* callbacks) # endif -# ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT -# define ERL_NIF_INIT_BODY do { \ - memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks)); \ - entry.options = ERL_NIF_DIRTY_NIF_OPTION; \ - } while(0) -# else -# define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks)) -# endif +# define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks)) #else # define ERL_NIF_INIT_GLOB -# ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT -# define ERL_NIF_INIT_BODY entry.options = ERL_NIF_DIRTY_NIF_OPTION -# else -# define ERL_NIF_INIT_BODY -# endif +# define ERL_NIF_INIT_BODY # ifdef STATIC_ERLANG_NIF # define ERL_NIF_INIT_DECL(MODNAME) ErlNifEntry* MODNAME ## _nif_init(void) # else @@ -263,6 +252,11 @@ extern TWinDynNifCallbacks WinDynNifCallbacks; # endif #endif +#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT +# define ERL_NIF_ENTRY_OPTIONS ERL_NIF_DIRTY_NIF_OPTION +#else +# define ERL_NIF_ENTRY_OPTIONS 0 +#endif #ifdef __cplusplus } @@ -288,7 +282,8 @@ ERL_NIF_INIT_DECL(NAME) \ sizeof(FUNCS) / sizeof(*FUNCS), \ FUNCS, \ LOAD, RELOAD, UPGRADE, UNLOAD, \ - ERL_NIF_VM_VARIANT \ + ERL_NIF_VM_VARIANT, \ + ERL_NIF_ENTRY_OPTIONS \ }; \ ERL_NIF_INIT_BODY; \ return &entry; \ diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 682f6f8f4b..2aa0a27197 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -32,6 +32,7 @@ #include "global.h" #include "erl_port_task.h" #include "dist.h" +#include "erl_check_io.h" #include "dtrace-wrapper.h" #include <stdarg.h> @@ -550,6 +551,16 @@ reset_handle(ErtsPortTask *ptp) } static ERTS_INLINE void +reset_executed_io_task_handle(ErtsPortTask *ptp) +{ + if (ptp->u.alive.handle) { + ASSERT(ptp == handle2task(ptp->u.alive.handle)); + erts_io_notify_port_task_executed(ptp->u.alive.handle); + reset_port_task_handle(ptp->u.alive.handle); + } +} + +static ERTS_INLINE void set_handle(ErtsPortTask *ptp, ErtsPortTaskHandle *pthp) { ptp->u.alive.handle = pthp; @@ -1396,10 +1407,7 @@ erts_port_task_schedule(Eterm id, erts_aint32_t act, add_flags; unsigned int prof_runnable_ports; - if (pthp && erts_port_task_is_scheduled(pthp)) { - ASSERT(0); - erts_port_task_abort(pthp); - } + ERTS_LC_ASSERT(!pthp || !erts_port_task_is_scheduled(pthp)); ASSERT(is_internal_port(id)); @@ -1699,8 +1707,6 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) goto aborted_port_task; } - reset_handle(ptp); - if (erts_system_monitor_long_schedule != 0) { start_time = erts_timestamp_millis(); } @@ -1711,6 +1717,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) switch (ptp->type) { case ERTS_PORT_TASK_TIMEOUT: + reset_handle(ptp); reds = ERTS_PORT_REDS_TIMEOUT; if (!(state & ERTS_PORT_SFLGS_DEAD)) { DTRACE_DRIVER(driver_timeout, pp); @@ -1725,6 +1732,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) for input and output */ (*pp->drv_ptr->ready_input)((ErlDrvData) pp->drv_data, ptp->u.alive.td.io.event); + reset_executed_io_task_handle(ptp); io_tasks_executed++; break; case ERTS_PORT_TASK_OUTPUT: @@ -1733,6 +1741,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) DTRACE_DRIVER(driver_ready_output, pp); (*pp->drv_ptr->ready_output)((ErlDrvData) pp->drv_data, ptp->u.alive.td.io.event); + reset_executed_io_task_handle(ptp); io_tasks_executed++; break; case ERTS_PORT_TASK_EVENT: @@ -1742,10 +1751,12 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) (*pp->drv_ptr->event)((ErlDrvData) pp->drv_data, ptp->u.alive.td.io.event, ptp->u.alive.td.io.event_data); + reset_executed_io_task_handle(ptp); io_tasks_executed++; break; case ERTS_PORT_TASK_PROC_SIG: { ErtsProc2PortSigData *sigdp = &ptp->u.alive.td.psig.data; + reset_handle(ptp); ASSERT((state & ERTS_PORT_SFLGS_DEAD) == 0); if (!pp->sched.taskq.bpq) reds = ptp->u.alive.td.psig.callback(pp, @@ -1763,6 +1774,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) break; } case ERTS_PORT_TASK_DIST_CMD: + reset_handle(ptp); reds = erts_dist_command(pp, CONTEXT_REDS - pp->reds); break; default: diff --git a/erts/emulator/beam/erl_port_task.h b/erts/emulator/beam/erl_port_task.h index 9ef0cfcedc..406cd3c492 100644 --- a/erts/emulator/beam/erl_port_task.h +++ b/erts/emulator/beam/erl_port_task.h @@ -156,7 +156,7 @@ erts_port_task_handle_init(ErtsPortTaskHandle *pthp) ERTS_GLB_INLINE int erts_port_task_is_scheduled(ErtsPortTaskHandle *pthp) { - return ((void *) erts_smp_atomic_read_nob(pthp)) != NULL; + return ((void *) erts_smp_atomic_read_acqb(pthp)) != NULL; } ERTS_GLB_INLINE void erts_port_task_pre_init_sched(ErtsPortTaskSched *ptsp, diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 20a88ec581..ea63d20dfa 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -148,6 +148,12 @@ extern BeamInstr beam_apply[]; extern BeamInstr beam_exit[]; extern BeamInstr beam_continue_exit[]; +#ifdef __OSE__ +/* Eager check I/O not supported on OSE yet. */ +int erts_eager_check_io = 0; +#else +int erts_eager_check_io = 0; +#endif int erts_sched_compact_load; int erts_sched_balance_util = 0; Uint erts_no_schedulers; @@ -710,72 +716,24 @@ sched_wall_time_ts(void) #if ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT -#ifdef ARCH_64 - static ERTS_INLINE Uint64 aschedtime_read(ErtsAtomicSchedTime *var) { - return (Uint64) erts_atomic_read_nob((erts_atomic_t *) var); + return (Uint64) erts_atomic64_read_nob((erts_atomic64_t *) var); } static ERTS_INLINE void aschedtime_set(ErtsAtomicSchedTime *var, Uint64 val) { - erts_atomic_set_nob((erts_atomic_t *) var, (erts_aint_t) val); + erts_atomic64_set_nob((erts_atomic64_t *) var, (erts_aint64_t) val); } static ERTS_INLINE void aschedtime_init(ErtsAtomicSchedTime *var) { - erts_atomic_init_nob((erts_atomic_t *) var, (erts_aint_t) 0); -} - -#elif defined(ARCH_32) - -static ERTS_INLINE Uint64 -aschedtime_read(ErtsAtomicSchedTime *var) -{ - erts_dw_aint_t dw; - erts_dw_atomic_read_nob((erts_dw_atomic_t *) var, &dw); -#ifdef ETHR_SU_DW_NAINT_T__ - return (Uint64) dw.dw_sint; -#else - { - Uint64 res; - res = (Uint64) ((Uint32) dw.sint[ERTS_DW_AINT_HIGH_WORD]); - res <<= 32; - res |= (Uint64) ((Uint32) dw.sint[ERTS_DW_AINT_LOW_WORD]); - return res; - } -#endif + erts_atomic64_init_nob((erts_atomic64_t *) var, (erts_aint64_t) 0); } -static ERTS_INLINE void -aschedtime_set(ErtsAtomicSchedTime *var, Uint64 val) -{ - erts_dw_aint_t dw; -#ifdef ETHR_SU_DW_NAINT_T__ - dw.dw_sint = (ETHR_SU_DW_NAINT_T__) val; -#else - dw.sint[ERTS_DW_AINT_LOW_WORD] = (erts_aint_t) (val & 0xffffffff); - dw.sint[ERTS_DW_AINT_HIGH_WORD] = (erts_aint_t) ((val >> 32) & 0xffffffff); -#endif - erts_dw_atomic_set_nob((erts_dw_atomic_t *) var, &dw); -} - -static ERTS_INLINE void -aschedtime_init(ErtsAtomicSchedTime *var) -{ - erts_dw_aint_t dw; - dw.sint[ERTS_DW_AINT_LOW_WORD] = (erts_aint_t) 0; - dw.sint[ERTS_DW_AINT_HIGH_WORD] = (erts_aint_t) 0; - erts_dw_atomic_init_nob((erts_dw_atomic_t *) var, &dw); -} - -#else -# error :-/ -#endif - #define ERTS_GET_AVG_MAX_UNLOCKED_TRY 50 #define ERTS_SCHED_AVG_UTIL_WRITE_MARKER (~((Uint64) 0)) @@ -2381,29 +2339,47 @@ try_set_sys_scheduling(void) #endif static ERTS_INLINE int -prepare_for_sys_schedule(ErtsSchedulerData *esdp) +prepare_for_sys_schedule(ErtsSchedulerData *esdp, int non_blocking) { + if (non_blocking && erts_eager_check_io) { #ifdef ERTS_SMP - while (!erts_port_task_have_outstanding_io_tasks() - && try_set_sys_scheduling()) { #ifdef ERTS_SCHED_ONLY_POLL_SCHED_1 - if (esdp->no != 1) { - /* If we are not scheduler 1 and ERTS_SCHED_ONLY_POLL_SCHED_1 is used - then we make sure to wake scheduler 1 */ - ErtsRunQueue *rq = ERTS_RUNQ_IX(0); - clear_sys_scheduling(); - wake_scheduler(rq); - return 0; - } + if (esdp->no != 1) { + /* If we are not scheduler 1 and ERTS_SCHED_ONLY_POLL_SCHED_1 is used + then we make sure to wake scheduler 1 */ + ErtsRunQueue *rq = ERTS_RUNQ_IX(0); + wake_scheduler(rq); + return 0; + } #endif - if (!erts_port_task_have_outstanding_io_tasks()) + return try_set_sys_scheduling(); +#else return 1; - clear_sys_scheduling(); +#endif } - return 0; + else { +#ifdef ERTS_SMP + while (!erts_port_task_have_outstanding_io_tasks() + && try_set_sys_scheduling()) { +#ifdef ERTS_SCHED_ONLY_POLL_SCHED_1 + if (esdp->no != 1) { + /* If we are not scheduler 1 and ERTS_SCHED_ONLY_POLL_SCHED_1 is used + then we make sure to wake scheduler 1 */ + ErtsRunQueue *rq = ERTS_RUNQ_IX(0); + clear_sys_scheduling(); + wake_scheduler(rq); + return 0; + } +#endif + if (!erts_port_task_have_outstanding_io_tasks()) + return 1; + clear_sys_scheduling(); + } + return 0; #else - return !erts_port_task_have_outstanding_io_tasks(); + return !erts_port_task_have_outstanding_io_tasks(); #endif + } } #ifdef ERTS_SMP @@ -2780,7 +2756,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * be waiting in erl_sys_schedule() */ - if (ERTS_SCHEDULER_IS_DIRTY(esdp) || !prepare_for_sys_schedule(esdp)) { + if (ERTS_SCHEDULER_IS_DIRTY(esdp) || !prepare_for_sys_schedule(esdp, 0)) { sched_waiting(esdp->no, rq); @@ -2944,7 +2920,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * Got to check that we still got I/O tasks; otherwise * we have to continue checking for I/O... */ - if (!prepare_for_sys_schedule(esdp)) { + if (!prepare_for_sys_schedule(esdp, 0)) { spincount *= ERTS_SCHED_TSE_SLEEP_SPINCOUNT_FACT; goto tse_wait; } @@ -2966,7 +2942,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * Got to check that we still got I/O tasks; otherwise * we have to wait in erl_sys_schedule() after all... */ - if (!prepare_for_sys_schedule(esdp)) { + if (!prepare_for_sys_schedule(esdp, 0)) { /* * Not allowed to wait in erl_sys_schedule; * do tse wait instead... @@ -3220,11 +3196,11 @@ chk_wake_sched(ErtsRunQueue *crq, int ix, int activate) return 0; wrq = ERTS_RUNQ_IX(ix); flags = ERTS_RUNQ_FLGS_GET(wrq); + if (activate && !(flags & ERTS_RUNQ_FLG_SUSPENDED)) { + if (try_inc_no_active_runqs(ix+1)) + (void) ERTS_RUNQ_FLGS_UNSET(wrq, ERTS_RUNQ_FLG_INACTIVE); + } if (!(flags & (ERTS_RUNQ_FLG_SUSPENDED|ERTS_RUNQ_FLG_NONEMPTY))) { - if (activate) { - if (try_inc_no_active_runqs(ix+1)) - (void) ERTS_RUNQ_FLGS_UNSET(wrq, ERTS_RUNQ_FLG_INACTIVE); - } wake_scheduler(wrq); return 1; } @@ -9200,7 +9176,7 @@ Process *schedule(Process *p, int calls) } else if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && (fcalls > input_reductions && - prepare_for_sys_schedule(esdp))) { + prepare_for_sys_schedule(esdp, !0))) { /* * Schedule system-level activities. */ @@ -9208,8 +9184,6 @@ Process *schedule(Process *p, int calls) erts_smp_atomic32_set_relb(&function_calls, 0); fcalls = 0; - ASSERT(!erts_port_task_have_outstanding_io_tasks()); - #if 0 /* Not needed since we wont wait in sys schedule */ erts_sys_schedule_interrupt(0); #endif @@ -9241,7 +9215,9 @@ Process *schedule(Process *p, int calls) if (RUNQ_READ_LEN(&rq->ports.info.len)) { int have_outstanding_io; have_outstanding_io = erts_port_task_execute(rq, &esdp->current_port); - if ((have_outstanding_io && fcalls > 2*input_reductions) + if ((!erts_eager_check_io + && have_outstanding_io + && fcalls > 2*input_reductions) || rq->halt_in_progress) { /* * If we have performed more than 2*INPUT_REDUCTIONS since diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 3b0798207e..f50b217d4a 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -104,6 +104,7 @@ struct saved_calls { }; extern Export exp_send, exp_receive, exp_timeout; +extern int erts_eager_check_io; extern int erts_sched_compact_load; extern int erts_sched_balance_util; extern Uint erts_no_schedulers; @@ -350,13 +351,7 @@ typedef struct { #undef ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT #define ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT_OPT -#ifdef ARCH_64 -typedef erts_atomic_t ErtsAtomicSchedTime; -#elif defined(ARCH_32) -typedef erts_dw_atomic_t ErtsAtomicSchedTime; -#else -# error :-/ -#endif +typedef erts_atomic64_t ErtsAtomicSchedTime; #if ERTS_HAVE_SCHED_UTIL_BALANCING_SUPPORT typedef struct { diff --git a/erts/emulator/beam/erl_ptab.c b/erts/emulator/beam/erl_ptab.c index eabf016081..02943ee683 100644 --- a/erts/emulator/beam/erl_ptab.c +++ b/erts/emulator/beam/erl_ptab.c @@ -280,124 +280,38 @@ struct ErtsPTabListBifData_ { }; -#ifdef ARCH_32 - -static ERTS_INLINE Uint64 -dw_aint_to_uint64(erts_dw_aint_t *dw) -{ -#ifdef ETHR_SU_DW_NAINT_T__ - return (Uint64) dw->dw_sint; -#else - Uint64 res; - res = (Uint64) ((Uint32) dw->sint[ERTS_DW_AINT_HIGH_WORD]); - res <<= 32; - res |= (Uint64) ((Uint32) dw->sint[ERTS_DW_AINT_LOW_WORD]); - return res; -#endif -} - -static void -unint64_to_dw_aint(erts_dw_aint_t *dw, Uint64 val) -{ -#ifdef ETHR_SU_DW_NAINT_T__ - dw->dw_sint = (ETHR_SU_DW_NAINT_T__) val; -#else - dw->sint[ERTS_DW_AINT_LOW_WORD] = (erts_aint_t) (val & 0xffffffff); - dw->sint[ERTS_DW_AINT_HIGH_WORD] = (erts_aint_t) ((val >> 32) & 0xffffffff); -#endif -} - static ERTS_INLINE void last_data_init_nob(ErtsPTab *ptab, Uint64 val) { - erts_dw_aint_t dw; - unint64_to_dw_aint(&dw, val); - erts_smp_dw_atomic_init_nob(&ptab->vola.tile.last_data, &dw); + erts_smp_atomic64_init_nob(&ptab->vola.tile.last_data, (erts_aint64_t) val); } static ERTS_INLINE void last_data_set_relb(ErtsPTab *ptab, Uint64 val) { - erts_dw_aint_t dw; - unint64_to_dw_aint(&dw, val); - erts_smp_dw_atomic_set_relb(&ptab->vola.tile.last_data, &dw); + erts_smp_atomic64_set_relb(&ptab->vola.tile.last_data, (erts_aint64_t) val); } static ERTS_INLINE Uint64 last_data_read_nob(ErtsPTab *ptab) { - erts_dw_aint_t dw; - erts_smp_dw_atomic_read_nob(&ptab->vola.tile.last_data, &dw); - return dw_aint_to_uint64(&dw); + return (Uint64) erts_smp_atomic64_read_nob(&ptab->vola.tile.last_data); } static ERTS_INLINE Uint64 last_data_read_acqb(ErtsPTab *ptab) { - erts_dw_aint_t dw; - erts_smp_dw_atomic_read_acqb(&ptab->vola.tile.last_data, &dw); - return dw_aint_to_uint64(&dw); + return (Uint64) erts_smp_atomic64_read_acqb(&ptab->vola.tile.last_data); } static ERTS_INLINE Uint64 last_data_cmpxchg_relb(ErtsPTab *ptab, Uint64 new, Uint64 exp) { - erts_dw_aint_t dw_new, dw_xchg; - - unint64_to_dw_aint(&dw_new, new); - unint64_to_dw_aint(&dw_xchg, exp); - - if (erts_smp_dw_atomic_cmpxchg_relb(&ptab->vola.tile.last_data, - &dw_new, - &dw_xchg)) - return exp; - else - return dw_aint_to_uint64(&dw_xchg); -} - -#elif defined(ARCH_64) - -union { - erts_smp_atomic_t pid_data; - char align[ERTS_CACHE_LINE_SIZE]; -} last erts_align_attribute(ERTS_CACHE_LINE_SIZE); - -static ERTS_INLINE void -last_data_init_nob(ErtsPTab *ptab, Uint64 val) -{ - erts_smp_atomic_init_nob(&ptab->vola.tile.last_data, (erts_aint_t) val); + return (Uint64) erts_smp_atomic64_cmpxchg_relb(&ptab->vola.tile.last_data, + (erts_aint64_t) new, + (erts_aint64_t) exp); } -static ERTS_INLINE void -last_data_set_relb(ErtsPTab *ptab, Uint64 val) -{ - erts_smp_atomic_set_relb(&ptab->vola.tile.last_data, (erts_aint_t) val); -} - -static ERTS_INLINE Uint64 -last_data_read_nob(ErtsPTab *ptab) -{ - return (Uint64) erts_smp_atomic_read_nob(&ptab->vola.tile.last_data); -} - -static ERTS_INLINE Uint64 -last_data_read_acqb(ErtsPTab *ptab) -{ - return (Uint64) erts_smp_atomic_read_acqb(&ptab->vola.tile.last_data); -} - -static ERTS_INLINE Uint64 -last_data_cmpxchg_relb(ErtsPTab *ptab, Uint64 new, Uint64 exp) -{ - return (Uint64) erts_smp_atomic_cmpxchg_relb(&ptab->vola.tile.last_data, - (erts_aint_t) new, - (erts_aint_t) exp); -} - -#else -# error "Not 64-bit, nor 32-bit architecture..." -#endif - static ERTS_INLINE int last_data_cmp(Uint64 ld1, Uint64 ld2) { diff --git a/erts/emulator/beam/erl_ptab.h b/erts/emulator/beam/erl_ptab.h index e3e05f14af..876241159b 100644 --- a/erts/emulator/beam/erl_ptab.h +++ b/erts/emulator/beam/erl_ptab.h @@ -88,11 +88,7 @@ typedef struct { } ErtsPTabListData; typedef struct { -#ifdef ARCH_32 - erts_smp_dw_atomic_t last_data; -#else - erts_smp_atomic_t last_data; -#endif + erts_smp_atomic64_t last_data; erts_smp_atomic32_t count; erts_smp_atomic32_t aid_ix; erts_smp_atomic32_t fid_ix; diff --git a/erts/emulator/beam/erl_smp.h b/erts/emulator/beam/erl_smp.h index c38ef47d87..6c40edeb3e 100644 --- a/erts/emulator/beam/erl_smp.h +++ b/erts/emulator/beam/erl_smp.h @@ -60,6 +60,7 @@ typedef erts_tsd_key_t erts_smp_tsd_key_t; #define erts_smp_dw_atomic_t erts_dw_atomic_t #define erts_smp_atomic_t erts_atomic_t #define erts_smp_atomic32_t erts_atomic32_t +#define erts_smp_atomic64_t erts_atomic64_t typedef erts_spinlock_t erts_smp_spinlock_t; typedef erts_rwlock_t erts_smp_rwlock_t; void erts_thr_fatal_error(int, char *); /* implemented in erl_init.c */ @@ -95,6 +96,7 @@ typedef int erts_smp_tsd_key_t; #define erts_smp_dw_atomic_t erts_no_dw_atomic_t #define erts_smp_atomic_t erts_no_atomic_t #define erts_smp_atomic32_t erts_no_atomic32_t +#define erts_smp_atomic64_t erts_no_atomic64_t #if __GNUC__ > 2 typedef struct { } erts_smp_spinlock_t; typedef struct { } erts_smp_rwlock_t; @@ -489,6 +491,116 @@ ERTS_GLB_INLINE void erts_smp_thr_sigwait(const sigset_t *set, int *sig); #define erts_smp_atomic32_set_dirty erts_atomic32_set_dirty #define erts_smp_atomic32_read_dirty erts_atomic32_read_dirty +/* 64-bit atomics */ + +#define erts_smp_atomic64_init_nob erts_atomic64_init_nob +#define erts_smp_atomic64_set_nob erts_atomic64_set_nob +#define erts_smp_atomic64_read_nob erts_atomic64_read_nob +#define erts_smp_atomic64_inc_read_nob erts_atomic64_inc_read_nob +#define erts_smp_atomic64_dec_read_nob erts_atomic64_dec_read_nob +#define erts_smp_atomic64_inc_nob erts_atomic64_inc_nob +#define erts_smp_atomic64_dec_nob erts_atomic64_dec_nob +#define erts_smp_atomic64_add_read_nob erts_atomic64_add_read_nob +#define erts_smp_atomic64_add_nob erts_atomic64_add_nob +#define erts_smp_atomic64_read_bor_nob erts_atomic64_read_bor_nob +#define erts_smp_atomic64_read_band_nob erts_atomic64_read_band_nob +#define erts_smp_atomic64_xchg_nob erts_atomic64_xchg_nob +#define erts_smp_atomic64_cmpxchg_nob erts_atomic64_cmpxchg_nob +#define erts_smp_atomic64_read_bset_nob erts_atomic64_read_bset_nob + +#define erts_smp_atomic64_init_mb erts_atomic64_init_mb +#define erts_smp_atomic64_set_mb erts_atomic64_set_mb +#define erts_smp_atomic64_read_mb erts_atomic64_read_mb +#define erts_smp_atomic64_inc_read_mb erts_atomic64_inc_read_mb +#define erts_smp_atomic64_dec_read_mb erts_atomic64_dec_read_mb +#define erts_smp_atomic64_inc_mb erts_atomic64_inc_mb +#define erts_smp_atomic64_dec_mb erts_atomic64_dec_mb +#define erts_smp_atomic64_add_read_mb erts_atomic64_add_read_mb +#define erts_smp_atomic64_add_mb erts_atomic64_add_mb +#define erts_smp_atomic64_read_bor_mb erts_atomic64_read_bor_mb +#define erts_smp_atomic64_read_band_mb erts_atomic64_read_band_mb +#define erts_smp_atomic64_xchg_mb erts_atomic64_xchg_mb +#define erts_smp_atomic64_cmpxchg_mb erts_atomic64_cmpxchg_mb +#define erts_smp_atomic64_read_bset_mb erts_atomic64_read_bset_mb + +#define erts_smp_atomic64_init_acqb erts_atomic64_init_acqb +#define erts_smp_atomic64_set_acqb erts_atomic64_set_acqb +#define erts_smp_atomic64_read_acqb erts_atomic64_read_acqb +#define erts_smp_atomic64_inc_read_acqb erts_atomic64_inc_read_acqb +#define erts_smp_atomic64_dec_read_acqb erts_atomic64_dec_read_acqb +#define erts_smp_atomic64_inc_acqb erts_atomic64_inc_acqb +#define erts_smp_atomic64_dec_acqb erts_atomic64_dec_acqb +#define erts_smp_atomic64_add_read_acqb erts_atomic64_add_read_acqb +#define erts_smp_atomic64_add_acqb erts_atomic64_add_acqb +#define erts_smp_atomic64_read_bor_acqb erts_atomic64_read_bor_acqb +#define erts_smp_atomic64_read_band_acqb erts_atomic64_read_band_acqb +#define erts_smp_atomic64_xchg_acqb erts_atomic64_xchg_acqb +#define erts_smp_atomic64_cmpxchg_acqb erts_atomic64_cmpxchg_acqb +#define erts_smp_atomic64_read_bset_acqb erts_atomic64_read_bset_acqb + +#define erts_smp_atomic64_init_relb erts_atomic64_init_relb +#define erts_smp_atomic64_set_relb erts_atomic64_set_relb +#define erts_smp_atomic64_read_relb erts_atomic64_read_relb +#define erts_smp_atomic64_inc_read_relb erts_atomic64_inc_read_relb +#define erts_smp_atomic64_dec_read_relb erts_atomic64_dec_read_relb +#define erts_smp_atomic64_inc_relb erts_atomic64_inc_relb +#define erts_smp_atomic64_dec_relb erts_atomic64_dec_relb +#define erts_smp_atomic64_add_read_relb erts_atomic64_add_read_relb +#define erts_smp_atomic64_add_relb erts_atomic64_add_relb +#define erts_smp_atomic64_read_bor_relb erts_atomic64_read_bor_relb +#define erts_smp_atomic64_read_band_relb erts_atomic64_read_band_relb +#define erts_smp_atomic64_xchg_relb erts_atomic64_xchg_relb +#define erts_smp_atomic64_cmpxchg_relb erts_atomic64_cmpxchg_relb +#define erts_smp_atomic64_read_bset_relb erts_atomic64_read_bset_relb + +#define erts_smp_atomic64_init_ddrb erts_atomic64_init_ddrb +#define erts_smp_atomic64_set_ddrb erts_atomic64_set_ddrb +#define erts_smp_atomic64_read_ddrb erts_atomic64_read_ddrb +#define erts_smp_atomic64_inc_read_ddrb erts_atomic64_inc_read_ddrb +#define erts_smp_atomic64_dec_read_ddrb erts_atomic64_dec_read_ddrb +#define erts_smp_atomic64_inc_ddrb erts_atomic64_inc_ddrb +#define erts_smp_atomic64_dec_ddrb erts_atomic64_dec_ddrb +#define erts_smp_atomic64_add_read_ddrb erts_atomic64_add_read_ddrb +#define erts_smp_atomic64_add_ddrb erts_atomic64_add_ddrb +#define erts_smp_atomic64_read_bor_ddrb erts_atomic64_read_bor_ddrb +#define erts_smp_atomic64_read_band_ddrb erts_atomic64_read_band_ddrb +#define erts_smp_atomic64_xchg_ddrb erts_atomic64_xchg_ddrb +#define erts_smp_atomic64_cmpxchg_ddrb erts_atomic64_cmpxchg_ddrb +#define erts_smp_atomic64_read_bset_ddrb erts_atomic64_read_bset_ddrb + +#define erts_smp_atomic64_init_rb erts_atomic64_init_rb +#define erts_smp_atomic64_set_rb erts_atomic64_set_rb +#define erts_smp_atomic64_read_rb erts_atomic64_read_rb +#define erts_smp_atomic64_inc_read_rb erts_atomic64_inc_read_rb +#define erts_smp_atomic64_dec_read_rb erts_atomic64_dec_read_rb +#define erts_smp_atomic64_inc_rb erts_atomic64_inc_rb +#define erts_smp_atomic64_dec_rb erts_atomic64_dec_rb +#define erts_smp_atomic64_add_read_rb erts_atomic64_add_read_rb +#define erts_smp_atomic64_add_rb erts_atomic64_add_rb +#define erts_smp_atomic64_read_bor_rb erts_atomic64_read_bor_rb +#define erts_smp_atomic64_read_band_rb erts_atomic64_read_band_rb +#define erts_smp_atomic64_xchg_rb erts_atomic64_xchg_rb +#define erts_smp_atomic64_cmpxchg_rb erts_atomic64_cmpxchg_rb +#define erts_smp_atomic64_read_bset_rb erts_atomic64_read_bset_rb + +#define erts_smp_atomic64_init_wb erts_atomic64_init_wb +#define erts_smp_atomic64_set_wb erts_atomic64_set_wb +#define erts_smp_atomic64_read_wb erts_atomic64_read_wb +#define erts_smp_atomic64_inc_read_wb erts_atomic64_inc_read_wb +#define erts_smp_atomic64_dec_read_wb erts_atomic64_dec_read_wb +#define erts_smp_atomic64_inc_wb erts_atomic64_inc_wb +#define erts_smp_atomic64_dec_wb erts_atomic64_dec_wb +#define erts_smp_atomic64_add_read_wb erts_atomic64_add_read_wb +#define erts_smp_atomic64_add_wb erts_atomic64_add_wb +#define erts_smp_atomic64_read_bor_wb erts_atomic64_read_bor_wb +#define erts_smp_atomic64_read_band_wb erts_atomic64_read_band_wb +#define erts_smp_atomic64_xchg_wb erts_atomic64_xchg_wb +#define erts_smp_atomic64_cmpxchg_wb erts_atomic64_cmpxchg_wb +#define erts_smp_atomic64_read_bset_wb erts_atomic64_read_bset_wb + +#define erts_smp_atomic64_set_dirty erts_atomic64_set_dirty +#define erts_smp_atomic64_read_dirty erts_atomic64_read_dirty + #else /* !ERTS_SMP */ /* Double word size atomics */ @@ -751,6 +863,116 @@ ERTS_GLB_INLINE void erts_smp_thr_sigwait(const sigset_t *set, int *sig); #define erts_smp_atomic32_set_dirty erts_no_atomic32_set #define erts_smp_atomic32_read_dirty erts_no_atomic32_read +/* 64-bit atomics */ + +#define erts_smp_atomic64_init_nob erts_no_atomic64_set +#define erts_smp_atomic64_set_nob erts_no_atomic64_set +#define erts_smp_atomic64_read_nob erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_nob erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_nob erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_nob erts_no_atomic64_inc +#define erts_smp_atomic64_dec_nob erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_nob erts_no_atomic64_add_read +#define erts_smp_atomic64_add_nob erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_nob erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_nob erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_nob erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_nob erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_nob erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_mb erts_no_atomic64_set +#define erts_smp_atomic64_set_mb erts_no_atomic64_set +#define erts_smp_atomic64_read_mb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_mb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_mb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_mb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_mb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_mb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_mb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_mb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_mb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_mb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_mb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_mb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_acqb erts_no_atomic64_set +#define erts_smp_atomic64_set_acqb erts_no_atomic64_set +#define erts_smp_atomic64_read_acqb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_acqb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_acqb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_acqb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_acqb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_acqb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_acqb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_acqb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_acqb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_acqb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_acqb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_acqb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_relb erts_no_atomic64_set +#define erts_smp_atomic64_set_relb erts_no_atomic64_set +#define erts_smp_atomic64_read_relb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_relb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_relb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_relb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_relb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_relb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_relb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_relb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_relb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_relb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_relb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_relb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_ddrb erts_no_atomic64_set +#define erts_smp_atomic64_set_ddrb erts_no_atomic64_set +#define erts_smp_atomic64_read_ddrb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_ddrb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_ddrb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_ddrb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_ddrb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_ddrb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_ddrb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_ddrb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_ddrb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_ddrb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_ddrb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_ddrb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_rb erts_no_atomic64_set +#define erts_smp_atomic64_set_rb erts_no_atomic64_set +#define erts_smp_atomic64_read_rb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_rb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_rb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_rb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_rb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_rb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_rb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_rb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_rb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_rb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_rb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_rb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_init_wb erts_no_atomic64_set +#define erts_smp_atomic64_set_wb erts_no_atomic64_set +#define erts_smp_atomic64_read_wb erts_no_atomic64_read +#define erts_smp_atomic64_inc_read_wb erts_no_atomic64_inc_read +#define erts_smp_atomic64_dec_read_wb erts_no_atomic64_dec_read +#define erts_smp_atomic64_inc_wb erts_no_atomic64_inc +#define erts_smp_atomic64_dec_wb erts_no_atomic64_dec +#define erts_smp_atomic64_add_read_wb erts_no_atomic64_add_read +#define erts_smp_atomic64_add_wb erts_no_atomic64_add +#define erts_smp_atomic64_read_bor_wb erts_no_atomic64_read_bor +#define erts_smp_atomic64_read_band_wb erts_no_atomic64_read_band +#define erts_smp_atomic64_xchg_wb erts_no_atomic64_xchg +#define erts_smp_atomic64_cmpxchg_wb erts_no_atomic64_cmpxchg +#define erts_smp_atomic64_read_bset_wb erts_no_atomic64_read_bset + +#define erts_smp_atomic64_set_dirty erts_no_atomic64_set +#define erts_smp_atomic64_read_dirty erts_no_atomic64_read + #endif /* !ERTS_SMP */ #if ERTS_GLB_INLINE_INCL_FUNC_DEF diff --git a/erts/emulator/beam/erl_thr_progress.c b/erts/emulator/beam/erl_thr_progress.c index 545a0343d0..664c479eb6 100644 --- a/erts/emulator/beam/erl_thr_progress.c +++ b/erts/emulator/beam/erl_thr_progress.c @@ -115,70 +115,24 @@ #undef read_nob #define read_nob erts_thr_prgr_read_nob__ -#ifdef ARCH_64 - static ERTS_INLINE void set_mb(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) { - erts_atomic_set_mb(atmc, val); + erts_atomic64_set_mb(atmc, (erts_aint64_t) val); } static ERTS_INLINE void set_nob(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) { - erts_atomic_set_nob(atmc, val); + erts_atomic64_set_nob(atmc, (erts_aint64_t) val); } static ERTS_INLINE void init_nob(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) { - erts_atomic_init_nob(atmc, val); -} - -#else - -#undef dw_aint_to_val -#define dw_aint_to_val erts_thr_prgr_dw_aint_to_val__ - -static void -val_to_dw_aint(erts_dw_aint_t *dw_aint, ErtsThrPrgrVal val) -{ -#ifdef ETHR_SU_DW_NAINT_T__ - dw_aint->dw_sint = (ETHR_SU_DW_NAINT_T__) val; -#else - dw_aint->sint[ERTS_DW_AINT_LOW_WORD] - = (erts_aint_t) (val & 0xffffffff); - dw_aint->sint[ERTS_DW_AINT_HIGH_WORD] - = (erts_aint_t) ((val >> 32) & 0xffffffff); -#endif + erts_atomic64_init_nob(atmc, (erts_aint64_t) val); } -static ERTS_INLINE void -set_mb(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) -{ - erts_dw_aint_t dw_aint; - val_to_dw_aint(&dw_aint, val); - erts_dw_atomic_set_mb(atmc, &dw_aint); -} - -static ERTS_INLINE void -set_nob(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) -{ - erts_dw_aint_t dw_aint; - val_to_dw_aint(&dw_aint, val); - erts_dw_atomic_set_nob(atmc, &dw_aint); -} - -static ERTS_INLINE void -init_nob(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) -{ - erts_dw_aint_t dw_aint; - val_to_dw_aint(&dw_aint, val); - erts_dw_atomic_init_nob(atmc, &dw_aint); -} - -#endif - /* #define ERTS_THR_PROGRESS_STATE_DEBUG */ #ifdef ERTS_THR_PROGRESS_STATE_DEBUG diff --git a/erts/emulator/beam/erl_thr_progress.h b/erts/emulator/beam/erl_thr_progress.h index 5f392944c2..03ddbd467c 100644 --- a/erts/emulator/beam/erl_thr_progress.h +++ b/erts/emulator/beam/erl_thr_progress.h @@ -115,11 +115,7 @@ struct ErtsThrPrgrLaterOp_ { extern erts_tsd_key_t erts_thr_prgr_data_key__; -#ifdef ARCH_64 -# define ERTS_THR_PRGR_ATOMIC erts_atomic_t -#else /* ARCH_32 */ -# define ERTS_THR_PRGR_ATOMIC erts_dw_atomic_t -#endif +#define ERTS_THR_PRGR_ATOMIC erts_atomic64_t typedef struct { void *arg; @@ -158,10 +154,6 @@ void erts_thr_progress_unmanaged_continue__(int umrefc_ix); void erts_thr_progress_dbg_print_state(void); -#ifdef ARCH_32 -#define ERTS_THR_PRGR_ATOMIC erts_dw_atomic_t -ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_dw_aint_to_val__(erts_dw_aint_t *dw_aint); -#endif ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_nob__(ERTS_THR_PRGR_ATOMIC *atmc); ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_acqb__(ERTS_THR_PRGR_ATOMIC *atmc); ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_mb__(ERTS_THR_PRGR_ATOMIC *atmc); @@ -184,68 +176,24 @@ ERTS_GLB_INLINE int erts_thr_progress_has_reached(ErtsThrPrgrVal val); #if ERTS_GLB_INLINE_INCL_FUNC_DEF -#ifdef ARCH_64 - -ERTS_GLB_INLINE ErtsThrPrgrVal -erts_thr_prgr_read_nob__(ERTS_THR_PRGR_ATOMIC *atmc) -{ - return (ErtsThrPrgrVal) erts_atomic_read_nob(atmc); -} - -ERTS_GLB_INLINE ErtsThrPrgrVal -erts_thr_prgr_read_acqb__(ERTS_THR_PRGR_ATOMIC *atmc) -{ - return (ErtsThrPrgrVal) erts_atomic_read_acqb(atmc); -} - -ERTS_GLB_INLINE ErtsThrPrgrVal -erts_thr_prgr_read_mb__(ERTS_THR_PRGR_ATOMIC *atmc) -{ - return (ErtsThrPrgrVal) erts_atomic_read_mb(atmc); -} - -#else /* ARCH_32 */ - -ERTS_GLB_INLINE ErtsThrPrgrVal -erts_thr_prgr_dw_aint_to_val__(erts_dw_aint_t *dw_aint) -{ -#ifdef ETHR_SU_DW_NAINT_T__ - return (ErtsThrPrgrVal) dw_aint->dw_sint; -#else - ErtsThrPrgrVal res; - res = (ErtsThrPrgrVal) ((Uint32) dw_aint->sint[ERTS_DW_AINT_HIGH_WORD]); - res <<= 32; - res |= (ErtsThrPrgrVal) ((Uint32) dw_aint->sint[ERTS_DW_AINT_LOW_WORD]); - return res; -#endif -} - ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_nob__(ERTS_THR_PRGR_ATOMIC *atmc) { - erts_dw_aint_t dw_aint; - erts_dw_atomic_read_nob(atmc, &dw_aint); - return erts_thr_prgr_dw_aint_to_val__(&dw_aint); + return (ErtsThrPrgrVal) erts_atomic64_read_nob(atmc); } ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_acqb__(ERTS_THR_PRGR_ATOMIC *atmc) { - erts_dw_aint_t dw_aint; - erts_dw_atomic_read_acqb(atmc, &dw_aint); - return erts_thr_prgr_dw_aint_to_val__(&dw_aint); + return (ErtsThrPrgrVal) erts_atomic64_read_acqb(atmc); } ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_mb__(ERTS_THR_PRGR_ATOMIC *atmc) { - erts_dw_aint_t dw_aint; - erts_dw_atomic_read_mb(atmc, &dw_aint); - return erts_thr_prgr_dw_aint_to_val__(&dw_aint); + return (ErtsThrPrgrVal) erts_atomic64_read_mb(atmc); } -#endif - ERTS_GLB_INLINE int erts_thr_progress_is_managed_thread(void) { diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 80026104db..7214f3ea33 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -344,6 +344,16 @@ typedef ethr_ts_event erts_tse_t; #define erts_aint32_t ethr_sint32_t #define erts_atomic32_t ethr_atomic32_t +#if defined(ARCH_32) +# define erts_atomic64_t ethr_dw_atomic_t +# define erts_aint64_t ethr_sint64_t +#elif defined(ARCH_64) +# define erts_atomic64_t ethr_atomic_t +# define erts_aint64_t ethr_sint_t +#else +# error "Not supported architecture" +#endif + #define ERTS_DW_AINT_HIGH_WORD ETHR_DW_SINT_HIGH_WORD #define ERTS_DW_AINT_LOW_WORD ETHR_DW_SINT_LOW_WORD @@ -414,10 +424,12 @@ typedef int erts_tse_t; typedef struct { SWord sint[2]; } erts_dw_aint_t; typedef SWord erts_aint_t; typedef Sint32 erts_aint32_t; +typedef Sint64 erts_aint64_t; #define erts_dw_atomic_t erts_dw_aint_t #define erts_atomic_t erts_aint_t #define erts_atomic32_t erts_aint32_t +#define erts_atomic64_t erts_aint64_t #if __GNUC__ > 2 typedef struct { } erts_spinlock_t; @@ -446,6 +458,7 @@ typedef struct { int gcc_is_buggy; } erts_rwlock_t; #define erts_no_dw_atomic_t erts_dw_aint_t #define erts_no_atomic_t erts_aint_t #define erts_no_atomic32_t erts_aint32_t +#define erts_no_atomic64_t erts_aint64_t #define ERTS_AINT_NULL ((erts_aint_t) NULL) @@ -570,6 +583,29 @@ ERTS_GLB_INLINE erts_aint32_t erts_no_atomic32_cmpxchg(erts_no_atomic32_t *xchgp ERTS_GLB_INLINE erts_aint32_t erts_no_atomic32_read_bset(erts_no_atomic32_t *var, erts_aint32_t mask, erts_aint32_t set); +ERTS_GLB_INLINE void erts_no_atomic64_set(erts_no_atomic64_t *var, + erts_aint64_t i); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_read(erts_no_atomic64_t *var); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_inc_read(erts_no_atomic64_t *incp); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_dec_read(erts_no_atomic64_t *decp); +ERTS_GLB_INLINE void erts_no_atomic64_inc(erts_no_atomic64_t *incp); +ERTS_GLB_INLINE void erts_no_atomic64_dec(erts_no_atomic64_t *decp); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_add_read(erts_no_atomic64_t *addp, + erts_aint64_t i); +ERTS_GLB_INLINE void erts_no_atomic64_add(erts_no_atomic64_t *addp, + erts_aint64_t i); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_read_bor(erts_no_atomic64_t *var, + erts_aint64_t mask); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_read_band(erts_no_atomic64_t *var, + erts_aint64_t mask); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_xchg(erts_no_atomic64_t *xchgp, + erts_aint64_t new); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_cmpxchg(erts_no_atomic64_t *xchgp, + erts_aint64_t new, + erts_aint64_t expected); +ERTS_GLB_INLINE erts_aint64_t erts_no_atomic64_read_bset(erts_no_atomic64_t *var, + erts_aint64_t mask, + erts_aint64_t set); ERTS_GLB_INLINE void erts_spinlock_init_x_opt(erts_spinlock_t *lock, char *name, @@ -1200,6 +1236,441 @@ erts_atomic32_read_dirty(erts_atomic32_t *var) #endif +/* 64-bit atomics */ + +#if defined(ARCH_64) + +#define erts_atomic64_init_nob ethr_atomic_init +#define erts_atomic64_set_nob ethr_atomic_set +#define erts_atomic64_read_nob ethr_atomic_read +#define erts_atomic64_inc_read_nob ethr_atomic_inc_read +#define erts_atomic64_dec_read_nob ethr_atomic_dec_read +#define erts_atomic64_inc_nob ethr_atomic_inc +#define erts_atomic64_dec_nob ethr_atomic_dec +#define erts_atomic64_add_read_nob ethr_atomic_add_read +#define erts_atomic64_add_nob ethr_atomic_add +#define erts_atomic64_read_bor_nob ethr_atomic_read_bor +#define erts_atomic64_read_band_nob ethr_atomic_read_band +#define erts_atomic64_xchg_nob ethr_atomic_xchg +#define erts_atomic64_cmpxchg_nob ethr_atomic_cmpxchg +#define erts_atomic64_read_bset_nob erts_atomic_read_bset_nob + +#define erts_atomic64_init_mb ethr_atomic_init_mb +#define erts_atomic64_set_mb ethr_atomic_set_mb +#define erts_atomic64_read_mb ethr_atomic_read_mb +#define erts_atomic64_inc_read_mb ethr_atomic_inc_read_mb +#define erts_atomic64_dec_read_mb ethr_atomic_dec_read_mb +#define erts_atomic64_inc_mb ethr_atomic_inc_mb +#define erts_atomic64_dec_mb ethr_atomic_dec_mb +#define erts_atomic64_add_read_mb ethr_atomic_add_read_mb +#define erts_atomic64_add_mb ethr_atomic_add_mb +#define erts_atomic64_read_bor_mb ethr_atomic_read_bor_mb +#define erts_atomic64_read_band_mb ethr_atomic_read_band_mb +#define erts_atomic64_xchg_mb ethr_atomic_xchg_mb +#define erts_atomic64_cmpxchg_mb ethr_atomic_cmpxchg_mb +#define erts_atomic64_read_bset_mb erts_atomic_read_bset_mb + +#define erts_atomic64_init_acqb ethr_atomic_init_acqb +#define erts_atomic64_set_acqb ethr_atomic_set_acqb +#define erts_atomic64_read_acqb ethr_atomic_read_acqb +#define erts_atomic64_inc_read_acqb ethr_atomic_inc_read_acqb +#define erts_atomic64_dec_read_acqb ethr_atomic_dec_read_acqb +#define erts_atomic64_inc_acqb ethr_atomic_inc_acqb +#define erts_atomic64_dec_acqb ethr_atomic_dec_acqb +#define erts_atomic64_add_read_acqb ethr_atomic_add_read_acqb +#define erts_atomic64_add_acqb ethr_atomic_add_acqb +#define erts_atomic64_read_bor_acqb ethr_atomic_read_bor_acqb +#define erts_atomic64_read_band_acqb ethr_atomic_read_band_acqb +#define erts_atomic64_xchg_acqb ethr_atomic_xchg_acqb +#define erts_atomic64_cmpxchg_acqb ethr_atomic_cmpxchg_acqb +#define erts_atomic64_read_bset_acqb erts_atomic_read_bset_acqb + +#define erts_atomic64_init_relb ethr_atomic_init_relb +#define erts_atomic64_set_relb ethr_atomic_set_relb +#define erts_atomic64_read_relb ethr_atomic_read_relb +#define erts_atomic64_inc_read_relb ethr_atomic_inc_read_relb +#define erts_atomic64_dec_read_relb ethr_atomic_dec_read_relb +#define erts_atomic64_inc_relb ethr_atomic_inc_relb +#define erts_atomic64_dec_relb ethr_atomic_dec_relb +#define erts_atomic64_add_read_relb ethr_atomic_add_read_relb +#define erts_atomic64_add_relb ethr_atomic_add_relb +#define erts_atomic64_read_bor_relb ethr_atomic_read_bor_relb +#define erts_atomic64_read_band_relb ethr_atomic_read_band_relb +#define erts_atomic64_xchg_relb ethr_atomic_xchg_relb +#define erts_atomic64_cmpxchg_relb ethr_atomic_cmpxchg_relb +#define erts_atomic64_read_bset_relb erts_atomic_read_bset_relb + +#define erts_atomic64_init_ddrb ethr_atomic_init_ddrb +#define erts_atomic64_set_ddrb ethr_atomic_set_ddrb +#define erts_atomic64_read_ddrb ethr_atomic_read_ddrb +#define erts_atomic64_inc_read_ddrb ethr_atomic_inc_read_ddrb +#define erts_atomic64_dec_read_ddrb ethr_atomic_dec_read_ddrb +#define erts_atomic64_inc_ddrb ethr_atomic_inc_ddrb +#define erts_atomic64_dec_ddrb ethr_atomic_dec_ddrb +#define erts_atomic64_add_read_ddrb ethr_atomic_add_read_ddrb +#define erts_atomic64_add_ddrb ethr_atomic_add_ddrb +#define erts_atomic64_read_bor_ddrb ethr_atomic_read_bor_ddrb +#define erts_atomic64_read_band_ddrb ethr_atomic_read_band_ddrb +#define erts_atomic64_xchg_ddrb ethr_atomic_xchg_ddrb +#define erts_atomic64_cmpxchg_ddrb ethr_atomic_cmpxchg_ddrb +#define erts_atomic64_read_bset_ddrb erts_atomic_read_bset_ddrb + +#define erts_atomic64_init_rb ethr_atomic_init_rb +#define erts_atomic64_set_rb ethr_atomic_set_rb +#define erts_atomic64_read_rb ethr_atomic_read_rb +#define erts_atomic64_inc_read_rb ethr_atomic_inc_read_rb +#define erts_atomic64_dec_read_rb ethr_atomic_dec_read_rb +#define erts_atomic64_inc_rb ethr_atomic_inc_rb +#define erts_atomic64_dec_rb ethr_atomic_dec_rb +#define erts_atomic64_add_read_rb ethr_atomic_add_read_rb +#define erts_atomic64_add_rb ethr_atomic_add_rb +#define erts_atomic64_read_bor_rb ethr_atomic_read_bor_rb +#define erts_atomic64_read_band_rb ethr_atomic_read_band_rb +#define erts_atomic64_xchg_rb ethr_atomic_xchg_rb +#define erts_atomic64_cmpxchg_rb ethr_atomic_cmpxchg_rb +#define erts_atomic64_read_bset_rb erts_atomic_read_bset_rb + +#define erts_atomic64_init_wb ethr_atomic_init_wb +#define erts_atomic64_set_wb ethr_atomic_set_wb +#define erts_atomic64_read_wb ethr_atomic_read_wb +#define erts_atomic64_inc_read_wb ethr_atomic_inc_read_wb +#define erts_atomic64_dec_read_wb ethr_atomic_dec_read_wb +#define erts_atomic64_inc_wb ethr_atomic_inc_wb +#define erts_atomic64_dec_wb ethr_atomic_dec_wb +#define erts_atomic64_add_read_wb ethr_atomic_add_read_wb +#define erts_atomic64_add_wb ethr_atomic_add_wb +#define erts_atomic64_read_bor_wb ethr_atomic_read_bor_wb +#define erts_atomic64_read_band_wb ethr_atomic_read_band_wb +#define erts_atomic64_xchg_wb ethr_atomic_xchg_wb +#define erts_atomic64_cmpxchg_wb ethr_atomic_cmpxchg_wb +#define erts_atomic64_read_bset_wb erts_atomic_read_bset_wb + +#define erts_atomic64_set_dirty erts_atomic_set_dirty +#define erts_atomic64_read_dirty erts_atomic_read_dirty + +#elif defined(ARCH_32) + +#undef ERTS_ATOMIC64_OPS_DECL__ + +#define ERTS_ATOMIC64_OPS_DECL__(BARRIER) \ +ERTS_GLB_INLINE void \ +erts_atomic64_init_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE void \ +erts_atomic64_set_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_ ## BARRIER(erts_atomic64_t *var); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_inc_read_ ## BARRIER(erts_atomic64_t *var); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_dec_read_ ## BARRIER(erts_atomic64_t *var); \ +ERTS_GLB_INLINE void \ +erts_atomic64_inc_ ## BARRIER(erts_atomic64_t *var); \ +ERTS_GLB_INLINE void \ +erts_atomic64_dec_ ## BARRIER(erts_atomic64_t *var); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_add_read_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE void \ +erts_atomic64_add_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_bor_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_band_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_xchg_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_cmpxchg_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t new, \ + erts_aint64_t exp); \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_bset_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t mask, \ + erts_aint64_t set) + +ERTS_ATOMIC64_OPS_DECL__(nob); +ERTS_ATOMIC64_OPS_DECL__(mb); +ERTS_ATOMIC64_OPS_DECL__(acqb); +ERTS_ATOMIC64_OPS_DECL__(relb); +ERTS_ATOMIC64_OPS_DECL__(ddrb); +ERTS_ATOMIC64_OPS_DECL__(rb); +ERTS_ATOMIC64_OPS_DECL__(wb); + +#undef ERTS_ATOMIC64_OPS_DECL__ + +ERTS_GLB_INLINE void +erts_atomic64_set_dirty(erts_atomic64_t *var, erts_aint64_t val); +ERTS_GLB_INLINE erts_aint64_t +erts_atomic64_read_dirty(erts_atomic64_t *var); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +/* + * The ethr_dw_atomic_*_nob() functions below + * are here to make it possible for the + * ERTS_ATOMIC64_OPS_IMPL__() to map erts + * barriers to ethread barriers... + */ +static ERTS_INLINE void +ethr_dw_atomic_init_nob(ethr_dw_atomic_t *var, + ethr_dw_sint_t *val) +{ + ethr_dw_atomic_init(var, val); +} + +static ERTS_INLINE void +ethr_dw_atomic_set_nob(ethr_dw_atomic_t *var, + ethr_dw_sint_t *val) +{ + ethr_dw_atomic_set(var, val); +} + +static ERTS_INLINE void +ethr_dw_atomic_read_nob(ethr_dw_atomic_t *var, + ethr_dw_sint_t *val) +{ + ethr_dw_atomic_read(var, val); +} + +static ERTS_INLINE int +ethr_dw_atomic_cmpxchg_nob(ethr_dw_atomic_t *var, + ethr_dw_sint_t *new, + ethr_dw_sint_t *xchg) +{ + return ethr_dw_atomic_cmpxchg(var, new, xchg); +} + +#undef ERTS_ATOMIC64_OPS_IMPL__ +#undef ERTS_ATOMIC64_DW_CMPXCHG_IMPL__ +#undef ERTS_DW_SINT_TO_AINT64__ +#undef ERTS_AINT64_TO_DW_SINT__ + +#ifdef ETHR_SU_DW_NAINT_T__ +#define ERTS_DW_SINT_TO_AINT64__(DW) \ + ((erts_aint64_t) DW.dw_sint) +#define ERTS_AINT64_TO_DW_SINT__(DW, AINT64) \ + (DW.dw_sint = (ETHR_SU_DW_NAINT_T__) AINT64) +#else /* !ETHR_SU_DW_NAINT_T__ */ +#define ERTS_DW_SINT_TO_AINT64__(DW) \ + ((((erts_aint64_t) DW.sint[ETHR_DW_SINT_HIGH_WORD]) << 32) \ + | (((erts_aint64_t) DW.sint[ETHR_DW_SINT_LOW_WORD]) \ + & ((erts_aint64_t) 0xffffffff))) +#define ERTS_AINT64_TO_DW_SINT__(DW, AINT64) \ + do { \ + DW.sint[ETHR_DW_SINT_LOW_WORD] = \ + (ethr_sint_t) (AINT64 & 0xffffffff); \ + DW.sint[ETHR_DW_SINT_HIGH_WORD] = \ + (ethr_sint_t) ((AINT64 >> 32) & 0xffffffff); \ + } while (0) +#endif /* !ETHR_SU_DW_NAINT_T__ */ + +#define ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(CmpXchgOp, \ + AVarP, XchgVar, NewVar, \ + ModificationCode) \ +do { \ + ethr_dw_sint_t dw_xchg__, dw_new__; \ + ethr_dw_atomic_read(AVarP, &dw_xchg__); \ + do { \ + XchgVar = ERTS_DW_SINT_TO_AINT64__(dw_xchg__); \ + { \ + ModificationCode; \ + } \ + ERTS_AINT64_TO_DW_SINT__(dw_new__, NewVar); \ + } while (!CmpXchgOp((AVarP), &dw_new__, &dw_xchg__)); \ +} while (0) + +#define ERTS_ATOMIC64_OPS_IMPL__(BARRIER) \ + \ +ERTS_GLB_INLINE void \ +erts_atomic64_init_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + ethr_dw_sint_t dw; \ + ERTS_AINT64_TO_DW_SINT__(dw, val); \ + ethr_dw_atomic_init_ ## BARRIER(var, &dw); \ +} \ + \ +ERTS_GLB_INLINE void \ +erts_atomic64_set_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + ethr_dw_sint_t dw; \ + ERTS_AINT64_TO_DW_SINT__(dw, val); \ + ethr_dw_atomic_set_ ## BARRIER(var, &dw); \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_ ## BARRIER(erts_atomic64_t *var) \ +{ \ + ethr_dw_sint_t dw; \ + ethr_dw_atomic_read_ ## BARRIER(var, &dw); \ + return ERTS_DW_SINT_TO_AINT64__(dw); \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_inc_read_ ## BARRIER(erts_atomic64_t *var) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg + 1); \ + return new; \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_dec_read_ ## BARRIER(erts_atomic64_t *var) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg - 1); \ + return new; \ +} \ + \ +ERTS_GLB_INLINE void \ +erts_atomic64_inc_ ## BARRIER(erts_atomic64_t *var) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg + 1); \ +} \ + \ +ERTS_GLB_INLINE void \ +erts_atomic64_dec_ ## BARRIER(erts_atomic64_t *var) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg - 1); \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_add_read_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg + val); \ + return new; \ +} \ + \ +ERTS_GLB_INLINE void \ +erts_atomic64_add_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg + val); \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_bor_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg | val); \ + return xchg; \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_band_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = xchg & val); \ + return xchg; \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_xchg_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t val) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + new = val); \ + return xchg; \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_cmpxchg_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t new, \ + erts_aint64_t exp) \ +{ \ + ethr_dw_sint_t dw_xchg, dw_new; \ + ERTS_AINT64_TO_DW_SINT__(dw_xchg, exp); \ + ERTS_AINT64_TO_DW_SINT__(dw_new, new); \ + if (ethr_dw_atomic_cmpxchg_ ## BARRIER(var, &dw_new, &dw_xchg)) \ + return exp; \ + return ERTS_DW_SINT_TO_AINT64__(dw_xchg); \ +} \ + \ +ERTS_GLB_INLINE erts_aint64_t \ +erts_atomic64_read_bset_ ## BARRIER(erts_atomic64_t *var, \ + erts_aint64_t mask, \ + erts_aint64_t set) \ +{ \ + erts_aint64_t xchg, new; \ + ERTS_ATOMIC64_DW_CMPXCHG_IMPL__(ethr_dw_atomic_cmpxchg_ ## BARRIER, \ + var, xchg, new, \ + { \ + new = xchg & ~mask; \ + new |= mask & set; \ + }); \ + return xchg; \ +} + +ERTS_ATOMIC64_OPS_IMPL__(nob) +ERTS_ATOMIC64_OPS_IMPL__(mb) +ERTS_ATOMIC64_OPS_IMPL__(acqb) +ERTS_ATOMIC64_OPS_IMPL__(relb) +ERTS_ATOMIC64_OPS_IMPL__(ddrb) +ERTS_ATOMIC64_OPS_IMPL__(rb) +ERTS_ATOMIC64_OPS_IMPL__(wb) + +#undef ERTS_ATOMIC64_OPS_IMPL__ +#undef ERTS_ATOMIC64_DW_CMPXCHG_IMPL__ + +ERTS_GLB_INLINE void +erts_atomic64_set_dirty(erts_atomic64_t *var, erts_aint64_t val) +{ + ethr_sint_t *sint = ethr_dw_atomic_addr(var); + ethr_dw_sint_t dw; + ERTS_AINT64_TO_DW_SINT__(dw, val); + sint[0] = dw.sint[0]; + sint[1] = dw.sint[1]; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_atomic64_read_dirty(erts_atomic64_t *var) +{ + ethr_sint_t *sint; + ethr_dw_sint_t dw; + sint = ethr_dw_atomic_addr(var); + dw.sint[0] = sint[0]; + dw.sint[1] = sint[1]; + return ERTS_DW_SINT_TO_AINT64__(dw); +} + +#undef ERTS_DW_SINT_TO_AINT64__ +#undef ERTS_AINT64_TO_DW_SINT__ + +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ + +#endif /* ARCH_32 */ + #else /* !USE_THREADS */ /* Double word size atomics */ @@ -1462,6 +1933,116 @@ erts_atomic32_read_dirty(erts_atomic32_t *var) #define erts_atomic32_set_dirty erts_no_atomic32_set #define erts_atomic32_read_dirty erts_no_atomic32_read +/* 64-bit atomics */ + +#define erts_atomic64_init_nob erts_no_atomic64_set +#define erts_atomic64_set_nob erts_no_atomic64_set +#define erts_atomic64_read_nob erts_no_atomic64_read +#define erts_atomic64_inc_read_nob erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_nob erts_no_atomic64_dec_read +#define erts_atomic64_inc_nob erts_no_atomic64_inc +#define erts_atomic64_dec_nob erts_no_atomic64_dec +#define erts_atomic64_add_read_nob erts_no_atomic64_add_read +#define erts_atomic64_add_nob erts_no_atomic64_add +#define erts_atomic64_read_bor_nob erts_no_atomic64_read_bor +#define erts_atomic64_read_band_nob erts_no_atomic64_read_band +#define erts_atomic64_xchg_nob erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_nob erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_nob erts_no_atomic64_read_bset + +#define erts_atomic64_init_mb erts_no_atomic64_set +#define erts_atomic64_set_mb erts_no_atomic64_set +#define erts_atomic64_read_mb erts_no_atomic64_read +#define erts_atomic64_inc_read_mb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_mb erts_no_atomic64_dec_read +#define erts_atomic64_inc_mb erts_no_atomic64_inc +#define erts_atomic64_dec_mb erts_no_atomic64_dec +#define erts_atomic64_add_read_mb erts_no_atomic64_add_read +#define erts_atomic64_add_mb erts_no_atomic64_add +#define erts_atomic64_read_bor_mb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_mb erts_no_atomic64_read_band +#define erts_atomic64_xchg_mb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_mb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_mb erts_no_atomic64_read_bset + +#define erts_atomic64_init_acqb erts_no_atomic64_set +#define erts_atomic64_set_acqb erts_no_atomic64_set +#define erts_atomic64_read_acqb erts_no_atomic64_read +#define erts_atomic64_inc_read_acqb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_acqb erts_no_atomic64_dec_read +#define erts_atomic64_inc_acqb erts_no_atomic64_inc +#define erts_atomic64_dec_acqb erts_no_atomic64_dec +#define erts_atomic64_add_read_acqb erts_no_atomic64_add_read +#define erts_atomic64_add_acqb erts_no_atomic64_add +#define erts_atomic64_read_bor_acqb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_acqb erts_no_atomic64_read_band +#define erts_atomic64_xchg_acqb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_acqb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_acqb erts_no_atomic64_read_bset + +#define erts_atomic64_init_relb erts_no_atomic64_set +#define erts_atomic64_set_relb erts_no_atomic64_set +#define erts_atomic64_read_relb erts_no_atomic64_read +#define erts_atomic64_inc_read_relb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_relb erts_no_atomic64_dec_read +#define erts_atomic64_inc_relb erts_no_atomic64_inc +#define erts_atomic64_dec_relb erts_no_atomic64_dec +#define erts_atomic64_add_read_relb erts_no_atomic64_add_read +#define erts_atomic64_add_relb erts_no_atomic64_add +#define erts_atomic64_read_bor_relb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_relb erts_no_atomic64_read_band +#define erts_atomic64_xchg_relb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_relb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_relb erts_no_atomic64_read_bset + +#define erts_atomic64_init_ddrb erts_no_atomic64_set +#define erts_atomic64_set_ddrb erts_no_atomic64_set +#define erts_atomic64_read_ddrb erts_no_atomic64_read +#define erts_atomic64_inc_read_ddrb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_ddrb erts_no_atomic64_dec_read +#define erts_atomic64_inc_ddrb erts_no_atomic64_inc +#define erts_atomic64_dec_ddrb erts_no_atomic64_dec +#define erts_atomic64_add_read_ddrb erts_no_atomic64_add_read +#define erts_atomic64_add_ddrb erts_no_atomic64_add +#define erts_atomic64_read_bor_ddrb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_ddrb erts_no_atomic64_read_band +#define erts_atomic64_xchg_ddrb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_ddrb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_ddrb erts_no_atomic64_read_bset + +#define erts_atomic64_init_rb erts_no_atomic64_set +#define erts_atomic64_set_rb erts_no_atomic64_set +#define erts_atomic64_read_rb erts_no_atomic64_read +#define erts_atomic64_inc_read_rb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_rb erts_no_atomic64_dec_read +#define erts_atomic64_inc_rb erts_no_atomic64_inc +#define erts_atomic64_dec_rb erts_no_atomic64_dec +#define erts_atomic64_add_read_rb erts_no_atomic64_add_read +#define erts_atomic64_add_rb erts_no_atomic64_add +#define erts_atomic64_read_bor_rb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_rb erts_no_atomic64_read_band +#define erts_atomic64_xchg_rb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_rb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_rb erts_no_atomic64_read_bset + +#define erts_atomic64_init_wb erts_no_atomic64_set +#define erts_atomic64_set_wb erts_no_atomic64_set +#define erts_atomic64_read_wb erts_no_atomic64_read +#define erts_atomic64_inc_read_wb erts_no_atomic64_inc_read +#define erts_atomic64_dec_read_wb erts_no_atomic64_dec_read +#define erts_atomic64_inc_wb erts_no_atomic64_inc +#define erts_atomic64_dec_wb erts_no_atomic64_dec +#define erts_atomic64_add_read_wb erts_no_atomic64_add_read +#define erts_atomic64_add_wb erts_no_atomic64_add +#define erts_atomic64_read_bor_wb erts_no_atomic64_read_bor +#define erts_atomic64_read_band_wb erts_no_atomic64_read_band +#define erts_atomic64_xchg_wb erts_no_atomic64_xchg +#define erts_atomic64_cmpxchg_wb erts_no_atomic64_cmpxchg +#define erts_atomic64_read_bset_wb erts_no_atomic64_read_bset + +#define erts_atomic64_set_dirty erts_no_atomic64_set +#define erts_atomic64_read_dirty erts_no_atomic64_read + #endif /* !USE_THREADS */ #if ERTS_GLB_INLINE_INCL_FUNC_DEF @@ -2383,6 +2964,104 @@ erts_no_atomic32_read_bset(erts_no_atomic32_t *var, return old; } +/* atomic64 */ + +ERTS_GLB_INLINE void +erts_no_atomic64_set(erts_no_atomic64_t *var, erts_aint64_t i) +{ + *var = i; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_read(erts_no_atomic64_t *var) +{ + return *var; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_inc_read(erts_no_atomic64_t *incp) +{ + return ++(*incp); +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_dec_read(erts_no_atomic64_t *decp) +{ + return --(*decp); +} + +ERTS_GLB_INLINE void +erts_no_atomic64_inc(erts_no_atomic64_t *incp) +{ + ++(*incp); +} + +ERTS_GLB_INLINE void +erts_no_atomic64_dec(erts_no_atomic64_t *decp) +{ + --(*decp); +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_add_read(erts_no_atomic64_t *addp, erts_aint64_t i) +{ + return *addp += i; +} + +ERTS_GLB_INLINE void +erts_no_atomic64_add(erts_no_atomic64_t *addp, erts_aint64_t i) +{ + *addp += i; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_read_bor(erts_no_atomic64_t *var, erts_aint64_t mask) +{ + erts_aint64_t old; + old = *var; + *var |= mask; + return old; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_read_band(erts_no_atomic64_t *var, erts_aint64_t mask) +{ + erts_aint64_t old; + old = *var; + *var &= mask; + return old; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_xchg(erts_no_atomic64_t *xchgp, erts_aint64_t new) +{ + erts_aint64_t old = *xchgp; + *xchgp = new; + return old; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_cmpxchg(erts_no_atomic64_t *xchgp, + erts_aint64_t new, + erts_aint64_t expected) +{ + erts_aint64_t old = *xchgp; + if (old == expected) + *xchgp = new; + return old; +} + +ERTS_GLB_INLINE erts_aint64_t +erts_no_atomic64_read_bset(erts_no_atomic64_t *var, + erts_aint64_t mask, + erts_aint64_t set) +{ + erts_aint64_t old = *var; + *var &= ~mask; + *var |= (mask & set); + return old; +} + /* spinlock */ ERTS_GLB_INLINE void diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h index 0807649ea1..c32f8fd61c 100644 --- a/erts/emulator/beam/erl_utils.h +++ b/erts/emulator/beam/erl_utils.h @@ -32,11 +32,7 @@ typedef struct { #endif union { Uint64 not_atomic; -#ifdef ARCH_64 - erts_atomic_t atomic; -#else - erts_dw_atomic_t atomic; -#endif + erts_atomic64_t atomic; } counter; } erts_interval_t; @@ -50,9 +46,6 @@ Uint64 erts_ensure_later_interval_nob(erts_interval_t *, Uint64); Uint64 erts_ensure_later_interval_acqb(erts_interval_t *, Uint64); Uint64 erts_smp_ensure_later_interval_nob(erts_interval_t *, Uint64); Uint64 erts_smp_ensure_later_interval_acqb(erts_interval_t *, Uint64); -#ifdef ARCH_32 -ERTS_GLB_INLINE Uint64 erts_interval_dw_aint_to_val__(erts_dw_aint_t *); -#endif ERTS_GLB_INLINE Uint64 erts_current_interval_nob__(erts_interval_t *); ERTS_GLB_INLINE Uint64 erts_current_interval_acqb__(erts_interval_t *); ERTS_GLB_INLINE Uint64 erts_current_interval_nob(erts_interval_t *); @@ -62,46 +55,16 @@ ERTS_GLB_INLINE Uint64 erts_smp_current_interval_acqb(erts_interval_t *); #if ERTS_GLB_INLINE_INCL_FUNC_DEF -#ifdef ARCH_32 - -ERTS_GLB_INLINE Uint64 -erts_interval_dw_aint_to_val__(erts_dw_aint_t *dw) -{ -#ifdef ETHR_SU_DW_NAINT_T__ - return (Uint64) dw->dw_sint; -#else - Uint64 res; - res = (Uint64) ((Uint32) dw->sint[ERTS_DW_AINT_HIGH_WORD]); - res <<= 32; - res |= (Uint64) ((Uint32) dw->sint[ERTS_DW_AINT_LOW_WORD]); - return res; -#endif -} - -#endif - ERTS_GLB_INLINE Uint64 erts_current_interval_nob__(erts_interval_t *icp) { -#ifdef ARCH_64 - return (Uint64) erts_atomic_read_nob(&icp->counter.atomic); -#else - erts_dw_aint_t dw; - erts_dw_atomic_read_nob(&icp->counter.atomic, &dw); - return erts_interval_dw_aint_to_val__(&dw); -#endif + return (Uint64) erts_atomic64_read_nob(&icp->counter.atomic); } ERTS_GLB_INLINE Uint64 erts_current_interval_acqb__(erts_interval_t *icp) { -#ifdef ARCH_64 - return (Uint64) erts_atomic_read_acqb(&icp->counter.atomic); -#else - erts_dw_aint_t dw; - erts_dw_atomic_read_acqb(&icp->counter.atomic, &dw); - return erts_interval_dw_aint_to_val__(&dw); -#endif + return (Uint64) erts_atomic64_read_acqb(&icp->counter.atomic); } ERTS_GLB_INLINE Uint64 diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index bf00958eb1..10565f67e5 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -156,7 +156,6 @@ void erts_init_atom_cache_map(ErtsAtomCacheMap *); void erts_reset_atom_cache_map(ErtsAtomCacheMap *); void erts_destroy_atom_cache_map(ErtsAtomCacheMap *); void erts_finalize_atom_cache_map(ErtsAtomCacheMap *, Uint32); -Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *); Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *); byte *erts_encode_ext_dist_header_setup(byte *, ErtsAtomCacheMap *); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 891046a8b5..32a2dc43e8 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -160,6 +160,7 @@ struct erts_driver_t_ { void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data); /* Might be NULL */ void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor); void (*stop_select)(ErlDrvEvent event, void*); /* Might be NULL */ + void (*emergency_close)(ErlDrvData drv_data); /* Might be NULL */ }; extern erts_driver_t *driver_list; @@ -852,6 +853,7 @@ Uint erts_port_ioq_size(Port *pp); void erts_stale_drv_select(Eterm, ErlDrvPort, ErlDrvEvent, int, int); Port *erts_get_heart_port(void); +void erts_emergency_close_ports(void); #if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_COUNT) void erts_lcnt_enable_io_lock_count(int enable); diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 9ae973e108..012a7d1a4b 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -7349,6 +7349,8 @@ no_stop_select_callback(ErlDrvEvent event, void* private) erts_send_error_to_logger_nogl(dsbufp); } +#define IS_DRIVER_VERSION_GE(DE,MAJOR,MINOR) \ + ((DE)->major_version >= (MAJOR) && (DE)->minor_version >= (MINOR)) static int init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) @@ -7396,6 +7398,7 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) drv->timeout = de->timeout ? de->timeout : no_timeout_callback; drv->ready_async = de->ready_async; drv->process_exit = de->process_exit; + drv->emergency_close = IS_DRIVER_VERSION_GE(de,3,2) ? de->emergency_close : NULL; if (de->stop_select) drv->stop_select = de->stop_select; else @@ -7414,6 +7417,8 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) } } +#undef IS_DRIVER_VERSION_GE + void erts_destroy_driver(erts_driver_t *drv) { @@ -7557,7 +7562,7 @@ Port *erts_get_heart_port(void) if (!port) continue; /* only examine undead or alive ports */ - if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_DEAD) + if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) continue; /* immediate atom compare */ reg = port->common.u.alive.reg; @@ -7568,3 +7573,23 @@ Port *erts_get_heart_port(void) return NULL; } + +void erts_emergency_close_ports(void) +{ + int ix, max = erts_ptab_max(&erts_port); + + for (ix = 0; ix < max; ix++) { + Port *port = erts_pix2port(ix); + + if (!port) + continue; + /* only examine undead or alive ports */ + if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) + continue; + + /* emergency close socket */ + if (port->drv_ptr->emergency_close) { + port->drv_ptr->emergency_close((ErlDrvData) port->drv_data); + } + } +} diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 3d8dd9c6d0..c29d4b3777 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -66,8 +66,12 @@ */ #ifndef ERTS_SYS_FD_TYPE +#define ERTS_SYS_FD_INVALID ((ErtsSysFdType) -1) typedef int ErtsSysFdType; #else +#ifndef ERTS_SYS_FD_INVALID +# error missing ERTS_SYS_FD_INVALID +#endif typedef ERTS_SYS_FD_TYPE ErtsSysFdType; #endif @@ -501,7 +505,7 @@ extern volatile int erts_writing_erl_crash_dump; # define NO_ERF # define NO_ERFC /* This definition doesn't take NaN into account, but matherr() gets those */ -# define finite(x) (fabs(x) != HUGE_VAL) +# define isfinite(x) (fabs(x) != HUGE_VAL) # define USE_MATHERR # define HAVE_FINITE #endif @@ -744,6 +748,14 @@ void init_getenv_state(GETENV_STATE *); char * getenv_string(GETENV_STATE *); void fini_getenv_state(GETENV_STATE *); +#define HAVE_ERTS_CHECK_IO_DEBUG +typedef struct { + int no_used_fds; + int no_driver_select_structs; + int no_driver_event_structs; +} ErtsCheckIoDebugInfo; +int erts_check_io_debug(ErtsCheckIoDebugInfo *ip); + /* xxxP */ #define SYS_DEFAULT_FLOAT_DECIMALS 20 void init_sys_float(void); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 55f9e68e78..c505c44905 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -48,6 +48,7 @@ #include "erl_sched_spec_pre_alloc.h" #include "beam_bp.h" #include "erl_ptab.h" +#include "erl_check_io.h" #undef M_TRIM_THRESHOLD #undef M_TOP_PAD @@ -4215,19 +4216,7 @@ void erts_silence_warn_unused_result(long unused) void erts_interval_init(erts_interval_t *icp) { -#ifdef ARCH_64 - erts_atomic_init_nob(&icp->counter.atomic, 0); -#else - erts_dw_aint_t dw; -#ifdef ETHR_SU_DW_NAINT_T__ - dw.dw_sint = 0; -#else - dw.sint[ERTS_DW_AINT_HIGH_WORD] = 0; - dw.sint[ERTS_DW_AINT_LOW_WORD] = 0; -#endif - erts_dw_atomic_init_nob(&icp->counter.atomic, &dw); - -#endif + erts_atomic64_init_nob(&icp->counter.atomic, 0); #ifdef DEBUG icp->smp_api = 0; #endif @@ -4249,55 +4238,13 @@ erts_smp_interval_init(erts_interval_t *icp) static ERTS_INLINE Uint64 step_interval_nob(erts_interval_t *icp) { -#ifdef ARCH_64 - return (Uint64) erts_atomic_inc_read_nob(&icp->counter.atomic); -#else - erts_dw_aint_t exp; - - erts_dw_atomic_read_nob(&icp->counter.atomic, &exp); - while (1) { - erts_dw_aint_t new = exp; - -#ifdef ETHR_SU_DW_NAINT_T__ - new.dw_sint++; -#else - new.sint[ERTS_DW_AINT_LOW_WORD]++; - if (new.sint[ERTS_DW_AINT_LOW_WORD] == 0) - new.sint[ERTS_DW_AINT_HIGH_WORD]++; -#endif - - if (erts_dw_atomic_cmpxchg_nob(&icp->counter.atomic, &new, &exp)) - return erts_interval_dw_aint_to_val__(&new); - - } -#endif + return (Uint64) erts_atomic64_inc_read_nob(&icp->counter.atomic); } static ERTS_INLINE Uint64 step_interval_relb(erts_interval_t *icp) { -#ifdef ARCH_64 - return (Uint64) erts_atomic_inc_read_relb(&icp->counter.atomic); -#else - erts_dw_aint_t exp; - - erts_dw_atomic_read_nob(&icp->counter.atomic, &exp); - while (1) { - erts_dw_aint_t new = exp; - -#ifdef ETHR_SU_DW_NAINT_T__ - new.dw_sint++; -#else - new.sint[ERTS_DW_AINT_LOW_WORD]++; - if (new.sint[ERTS_DW_AINT_LOW_WORD] == 0) - new.sint[ERTS_DW_AINT_HIGH_WORD]++; -#endif - - if (erts_dw_atomic_cmpxchg_relb(&icp->counter.atomic, &new, &exp)) - return erts_interval_dw_aint_to_val__(&new); - - } -#endif + return (Uint64) erts_atomic64_inc_read_relb(&icp->counter.atomic); } @@ -4305,38 +4252,10 @@ static ERTS_INLINE Uint64 ensure_later_interval_nob(erts_interval_t *icp, Uint64 ic) { Uint64 curr_ic; -#ifdef ARCH_64 - curr_ic = (Uint64) erts_atomic_read_nob(&icp->counter.atomic); + curr_ic = (Uint64) erts_atomic64_read_nob(&icp->counter.atomic); if (curr_ic > ic) return curr_ic; - return (Uint64) erts_atomic_inc_read_nob(&icp->counter.atomic); -#else - erts_dw_aint_t exp; - - erts_dw_atomic_read_nob(&icp->counter.atomic, &exp); - curr_ic = erts_interval_dw_aint_to_val__(&exp); - if (curr_ic > ic) - return curr_ic; - - while (1) { - erts_dw_aint_t new = exp; - -#ifdef ETHR_SU_DW_NAINT_T__ - new.dw_sint++; -#else - new.sint[ERTS_DW_AINT_LOW_WORD]++; - if (new.sint[ERTS_DW_AINT_LOW_WORD] == 0) - new.sint[ERTS_DW_AINT_HIGH_WORD]++; -#endif - - if (erts_dw_atomic_cmpxchg_nob(&icp->counter.atomic, &new, &exp)) - return erts_interval_dw_aint_to_val__(&new); - - curr_ic = erts_interval_dw_aint_to_val__(&exp); - if (curr_ic > ic) - return curr_ic; - } -#endif + return (Uint64) erts_atomic64_inc_read_nob(&icp->counter.atomic); } @@ -4344,38 +4263,10 @@ static ERTS_INLINE Uint64 ensure_later_interval_acqb(erts_interval_t *icp, Uint64 ic) { Uint64 curr_ic; -#ifdef ARCH_64 - curr_ic = (Uint64) erts_atomic_read_acqb(&icp->counter.atomic); + curr_ic = (Uint64) erts_atomic64_read_acqb(&icp->counter.atomic); if (curr_ic > ic) return curr_ic; - return (Uint64) erts_atomic_inc_read_acqb(&icp->counter.atomic); -#else - erts_dw_aint_t exp; - - erts_dw_atomic_read_acqb(&icp->counter.atomic, &exp); - curr_ic = erts_interval_dw_aint_to_val__(&exp); - if (curr_ic > ic) - return curr_ic; - - while (1) { - erts_dw_aint_t new = exp; - -#ifdef ETHR_SU_DW_NAINT_T__ - new.dw_sint++; -#else - new.sint[ERTS_DW_AINT_LOW_WORD]++; - if (new.sint[ERTS_DW_AINT_LOW_WORD] == 0) - new.sint[ERTS_DW_AINT_HIGH_WORD]++; -#endif - - if (erts_dw_atomic_cmpxchg_acqb(&icp->counter.atomic, &new, &exp)) - return erts_interval_dw_aint_to_val__(&new); - - curr_ic = erts_interval_dw_aint_to_val__(&exp); - if (curr_ic > ic) - return curr_ic; - } -#endif + return (Uint64) erts_atomic64_inc_read_acqb(&icp->counter.atomic); } Uint64 diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 891589d1c5..3c6922eb8e 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -268,14 +268,13 @@ static BOOL (WINAPI *fpSetHandleInformation)(HANDLE,DWORD,DWORD); #define sock_htonl(x) htonl((x)) #define sock_send(s,buf,len,flag) send((s),(buf),(len),(flag)) #define sock_sendv(s, vec, size, np, flag) \ - WSASend((s),(WSABUF*)(vec),\ - (size),(np),(flag),NULL,NULL) + WSASend((s),(WSABUF*)(vec),(size),(np),(flag),NULL,NULL) #define sock_recv(s,buf,len,flag) recv((s),(buf),(len),(flag)) #define sock_recvfrom(s,buf,blen,flag,addr,alen) \ - recvfrom((s),(buf),(blen),(flag),(addr),(alen)) + recvfrom((s),(buf),(blen),(flag),(addr),(alen)) #define sock_sendto(s,buf,blen,flag,addr,alen) \ - sendto((s),(buf),(blen),(flag),(addr),(alen)) + sendto((s),(buf),(blen),(flag),(addr),(alen)) #define sock_hostname(buf, len) gethostname((buf), (len)) #define sock_getservbyname(name,proto) getservbyname((name),(proto)) @@ -360,9 +359,9 @@ static ssize_t writev_fallback(int fd, const struct iovec *iov, int iovcnt, int #define sock_accept(s, addr, len) accept((s), (addr), (len)) #define sock_send(s,buf,len,flag) inet_send((s),(buf),(len),(flag)) #define sock_sendto(s,buf,blen,flag,addr,alen) \ - sendto((s),(buf),(blen),(flag),(addr),(alen)) + sendto((s),(buf),(blen),(flag),(addr),(alen)) #define sock_sendv(s, vec, size, np, flag) \ - (*(np) = writev_fallback((s), (struct iovec*)(vec), (size), (*(np)))) + (*(np) = writev_fallback((s), (struct iovec*)(vec), (size), (*(np)))) #define sock_sendmsg(s,msghdr,flag) sendmsg((s),(msghdr),(flag)) #define sock_open(af, type, proto) socket((af), (type), (proto)) @@ -1178,6 +1177,7 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData, unsigned int, static void tcp_inet_timeout(ErlDrvData); static void tcp_inet_process_exit(ErlDrvData, ErlDrvMonitor *); static void inet_stop_select(ErlDrvEvent, void*); +static void inet_emergency_close(ErlDrvData); #ifdef __WIN32__ static void tcp_inet_event(ErlDrvData, ErlDrvEvent); static void find_dynamic_functions(void); @@ -1288,7 +1288,8 @@ static struct erl_drv_entry tcp_inet_driver_entry = ERL_DRV_FLAG_USE_PORT_LOCKING|ERL_DRV_FLAG_SOFT_BUSY, NULL, tcp_inet_process_exit, - inet_stop_select + inet_stop_select, + inet_emergency_close }; @@ -1341,7 +1342,8 @@ static struct erl_drv_entry udp_inet_driver_entry = ERL_DRV_FLAG_USE_PORT_LOCKING, NULL, NULL, - inet_stop_select + inet_stop_select, + inet_emergency_close }; #endif @@ -1375,7 +1377,8 @@ static struct erl_drv_entry sctp_inet_driver_entry = ERL_DRV_FLAG_USE_PORT_LOCKING, NULL, NULL, /* process_exit */ - inet_stop_select + inet_stop_select, + inet_emergency_close }; #endif @@ -1421,7 +1424,7 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event); static int packet_inet_output(udp_descriptor* udesc, HANDLE event); #endif -/* convert descriptor poiner to inet_descriptor pointer */ +/* convert descriptor pointer to inet_descriptor pointer */ #define INETP(d) (&(d)->inet) #ifdef __OSE__ @@ -2890,6 +2893,9 @@ static ErlDrvTermData am_sctp_rtoinfo, /* Option names */ /* For #sctp_paddrinfo{}: */ am_active, am_inactive, +# if HAVE_DECL_SCTP_UNCONFIRMED + am_unconfirmed, +# endif /* For #sctp_status{}: */ # if HAVE_DECL_SCTP_EMPTY @@ -3919,7 +3925,10 @@ static void inet_init_sctp(void) { /* For #sctp_paddrinfo{}: */ INIT_ATOM(active); INIT_ATOM(inactive); - +# if HAVE_DECL_SCTP_UNCONFIRMED + INIT_ATOM(unconfirmed); +# endif + /* For #sctp_status{}: */ # if HAVE_DECL_SCTP_EMPTY INIT_ATOM(empty); @@ -4542,11 +4551,13 @@ static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type, inet_address name; unsigned int sz = sizeof(name); - /* check that it is a socket and that the socket is bound */ - if (IS_SOCKET_ERROR(sock_name(s, (struct sockaddr*) &name, &sz))) - return ctl_error(sock_errno(), rbuf, rsize); - if (name.sa.sa_family != domain) - return ctl_error(EINVAL, rbuf, rsize); + if (bound) { + /* check that it is a socket and that the socket is bound */ + if (IS_SOCKET_ERROR(sock_name(s, (struct sockaddr*) &name, &sz))) + return ctl_error(sock_errno(), rbuf, rsize); + if (name.sa.sa_family != domain) + return ctl_error(EINVAL, rbuf, rsize); + } #ifdef __OSE__ /* for fdopen duplicating the sd will allow to uniquely identify the signal from OSE with erlang port */ @@ -4719,6 +4730,36 @@ static char* sockaddr_to_buf(struct sockaddr* addr, char* ptr, char* end) return NULL; } +/* sockaddr_bufsz_need + * Returns the number of bytes needed to store the information + * through sockaddr_to_buf + */ + +static size_t sockaddr_bufsz_need(struct sockaddr* addr) +{ + if (addr->sa_family == AF_INET || addr->sa_family == 0) { + return 1 + sizeof(struct in_addr); + } +#if defined(HAVE_IN6) && defined(AF_INET6) + else if (addr->sa_family == AF_INET6) { + return 1 + sizeof(struct in6_addr); + } +#endif +#if defined(AF_LINK) + if (addr->sa_family == AF_LINK) { + struct sockaddr_dl *sdl_p = (struct sockaddr_dl*) addr; + return 2 + sdl_p->sdl_alen; + } +#endif +#if defined(AF_PACKET) && defined(HAVE_NETPACKET_PACKET_H) + else if(addr->sa_family == AF_PACKET) { + struct sockaddr_ll *sll_p = (struct sockaddr_ll*) addr; + return 2 + sll_p->sll_halen; + } +#endif + return 0; +} + static char* buf_to_sockaddr(char* ptr, char* end, struct sockaddr* addr) { buf_check(ptr,end,1); @@ -5797,6 +5838,11 @@ done: } #elif defined(HAVE_GETIFADDRS) +#ifdef DEBUG +#define GETIFADDRS_BUFSZ (1) +#else +#define GETIFADDRS_BUFSZ (512) +#endif static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, char **rbuf_pp, ErlDrvSizeT rsize) @@ -5807,15 +5853,15 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, char *buf_p; char *buf_alloc_p; - buf_size = 512; - buf_alloc_p = ALLOC(buf_size); + buf_size = GETIFADDRS_BUFSZ; + buf_alloc_p = ALLOC(GETIFADDRS_BUFSZ); buf_p = buf_alloc_p; # define BUF_ENSURE(Size) \ do { \ int NEED_, GOT_ = buf_p - buf_alloc_p; \ NEED_ = GOT_ + (Size); \ if (NEED_ > buf_size) { \ - buf_size = NEED_ + 512; \ + buf_size = NEED_ + GETIFADDRS_BUFSZ; \ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ buf_p = buf_alloc_p + GOT_; \ } \ @@ -5828,7 +5874,7 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, while (! (P_ = sockaddr_to_buf((sa), buf_p, \ buf_alloc_p+buf_size))) { \ int GOT_ = buf_p - buf_alloc_p; \ - buf_size += 512; \ + buf_size += GETIFADDRS_BUFSZ; \ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ buf_p = buf_alloc_p + GOT_; \ } \ @@ -5885,10 +5931,11 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, || ifa_p->ifa_addr->sa_family == AF_PACKET #endif ) { - char *bp = buf_p; - BUF_ENSURE(1); - SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr); - if (buf_p - bp < 4) buf_p = bp; /* Empty hwaddr */ + size_t need = sockaddr_bufsz_need(ifa_p->ifa_addr); + if (need > 3) { + BUF_ENSURE(1 + need); + SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr); + } } #endif } @@ -5903,6 +5950,7 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, return buf_size; # undef BUF_ENSURE } +#undef GETIFADDRS_BUFSZ #else @@ -7336,8 +7384,13 @@ static int load_paddrinfo (ErlDrvTermData * spec, int i, case SCTP_INACTIVE: i = LOAD_ATOM (spec, i, am_inactive); break; +# if HAVE_DECL_SCTP_UNCONFIRMED + case SCTP_UNCONFIRMED: + i = LOAD_ATOM (spec, i, am_unconfirmed); + break; +# endif default: - ASSERT(0); /* NB: SCTP_UNCONFIRMED modifier not yet supported */ + i = LOAD_ATOM (spec, i, am_undefined); } i = LOAD_INT (spec, i, pai->spinfo_cwnd); i = LOAD_INT (spec, i, pai->spinfo_srtt); @@ -8202,6 +8255,19 @@ static void inet_stop(inet_descriptor* desc) FREE(desc); } +static void inet_emergency_close(ErlDrvData data) +{ + /* valid for any (UDP, TCP or SCTP) descriptor */ + tcp_descriptor* tcp_desc = (tcp_descriptor*)data; + inet_descriptor* desc = INETP(tcp_desc); + DEBUGF(("inet_emergency_close(%ld) {s=%d\r\n", + (long)desc->port, desc->s)); + if (desc->s != INVALID_SOCKET) { + sock_close(desc->s); + } +} + + static void set_default_msgq_limits(ErlDrvPort port) { ErlDrvSizeT q_high = INET_HIGH_MSGQ_WATERMARK; diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index a321bb9641..7e4043fc1b 100644 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -1288,6 +1288,10 @@ do_fileinfo(Efile_call_state* state, Efile_info* pInfo, { HANDLE handle; /* Handle returned by CreateFile() */ BY_HANDLE_FILE_INFORMATION fileInfo; /* from CreateFile() */ + + /* We initialise nNumberOfLinks as GetFileInformationByHandle + does not always initialise this field */ + fileInfo.nNumberOfLinks = 1; if (handle = CreateFileW(name, GENERIC_READ, FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, 0, NULL)) { GetFileInformationByHandle(handle, &fileInfo); diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4 index bd8bc5ab6b..3ca9a1bcdb 100644 --- a/erts/emulator/hipe/hipe_arm_bifs.m4 +++ b/erts/emulator/hipe/hipe_arm_bifs.m4 @@ -25,6 +25,7 @@ include(`hipe/hipe_arm_asm.m4') .text .p2align 2 + .arm `#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) # define CALL_BIF(F) ldr r14, =F; str r14, [r0, #P_BIF_CALLEE]; bl hipe_debug_bif_wrapper @@ -391,7 +392,14 @@ $1: mov r0, P /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(0) +#else QUICK_CALL_RET($2,0) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -407,7 +415,14 @@ $1: NBIF_ARG(r1,1,0) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(1) +#else QUICK_CALL_RET($2,1) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -424,7 +439,14 @@ $1: NBIF_ARG(r2,2,1) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(2) +#else QUICK_CALL_RET($2,2) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -442,7 +464,14 @@ $1: NBIF_ARG(r3,3,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(3) +#else QUICK_CALL_RET($2,3) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -466,7 +495,14 @@ $1: NBIF_ARG(r3,5,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(5) +#else QUICK_CALL_RET($2,5) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -488,9 +524,16 @@ define(noproc_primop_interface_0, #`define' HAVE_$1 .global $1 $1: - /* XXX: this case is always trivial; how to suppress the branch? */ /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(0) +#else + /* XXX: this case is always trivial; how to suppress the branch? */ QUICK_CALL_RET($2,0) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -505,7 +548,14 @@ $1: NBIF_ARG(r0,1,0) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(1) +#else QUICK_CALL_RET($2,1) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -521,7 +571,14 @@ $1: NBIF_ARG(r1,2,1) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(2) +#else QUICK_CALL_RET($2,2) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -538,7 +595,14 @@ $1: NBIF_ARG(r2,3,2) /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(3) +#else QUICK_CALL_RET($2,3) +#endif .size $1, .-$1 .type $1, %function #endif') @@ -558,7 +622,14 @@ $1: str r4, [sp, #0] /* Perform a quick save;call;restore;ret sequence. */ +#ifdef __thumb__ + SAVE_CONTEXT_QUICK + bl $2 + RESTORE_CONTEXT_QUICK + NBIF_RET(5) +#else QUICK_CALL_RET($2,5) +#endif .size $1, .-$1 .type $1, %function #endif') diff --git a/erts/emulator/hipe/hipe_arm_glue.S b/erts/emulator/hipe/hipe_arm_glue.S index 2e2b8604a6..5723afac12 100644 --- a/erts/emulator/hipe/hipe_arm_glue.S +++ b/erts/emulator/hipe/hipe_arm_glue.S @@ -25,6 +25,7 @@ .text .p2align 2 + .arm /* * Enter Erlang from C. @@ -70,6 +71,7 @@ * Emulated code recursively calls native code. */ .global hipe_arm_call_to_native + .type hipe_arm_call_to_native, %function hipe_arm_call_to_native: ENTER_FROM_C /* get argument registers */ @@ -85,6 +87,7 @@ hipe_arm_call_to_native: * This is where native code returns to emulated code. */ .global nbif_return + .type nbif_return, %function nbif_return: str r0, [P, #P_ARG0] /* save retval */ mov r0, #HIPE_MODE_SWITCH_RES_RETURN @@ -95,6 +98,7 @@ nbif_return: * Emulated code returns to its native code caller. */ .global hipe_arm_return_to_native + .type hipe_arm_return_to_native, %function hipe_arm_return_to_native: ENTER_FROM_C /* get return value */ @@ -111,6 +115,7 @@ hipe_arm_return_to_native: * Emulated code tailcalls native code. */ .global hipe_arm_tailcall_to_native + .type hipe_arm_tailcall_to_native, %function hipe_arm_tailcall_to_native: ENTER_FROM_C /* get argument registers */ @@ -125,6 +130,7 @@ hipe_arm_tailcall_to_native: * Emulated code throws an exception to its native code caller. */ .global hipe_arm_throw_to_native + .type hipe_arm_throw_to_native, %function hipe_arm_throw_to_native: ENTER_FROM_C /* invoke the handler */ @@ -142,6 +148,7 @@ hipe_arm_throw_to_native: * XXX: Different stubs for different number of register parameters? */ .global nbif_callemu + .type nbif_callemu, %function nbif_callemu: str r8, [P, #P_BEAM_IP] str r0, [P, #P_ARITY] @@ -153,6 +160,7 @@ nbif_callemu: * nbif_apply */ .global nbif_apply + .type nbif_apply, %function nbif_apply: STORE_ARG_REGS mov r0, #HIPE_MODE_SWITCH_RES_APPLY @@ -169,6 +177,7 @@ nbif_apply: */ #if NR_ARG_REGS >= 6 .global nbif_ccallemu6 + .type nbif_ccallemu6, %function nbif_ccallemu6: str ARG5, [P, #P_ARG5] #if NR_ARG_REGS > 6 @@ -181,6 +190,7 @@ nbif_ccallemu6: #if NR_ARG_REGS >= 5 .global nbif_ccallemu5 + .type nbif_ccallemu5, %function nbif_ccallemu5: str ARG4, [P, #P_ARG4] #if NR_ARG_REGS > 5 @@ -193,6 +203,7 @@ nbif_ccallemu5: #if NR_ARG_REGS >= 4 .global nbif_ccallemu4 + .type nbif_ccallemu4, %function nbif_ccallemu4: str ARG3, [P, #P_ARG3] #if NR_ARG_REGS > 4 @@ -205,6 +216,7 @@ nbif_ccallemu4: #if NR_ARG_REGS >= 3 .global nbif_ccallemu3 + .type nbif_ccallemu3, %function nbif_ccallemu3: str ARG2, [P, #P_ARG2] #if NR_ARG_REGS > 3 @@ -217,6 +229,7 @@ nbif_ccallemu3: #if NR_ARG_REGS >= 2 .global nbif_ccallemu2 + .type nbif_ccallemu2, %function nbif_ccallemu2: str ARG1, [P, #P_ARG1] #if NR_ARG_REGS > 2 @@ -229,6 +242,7 @@ nbif_ccallemu2: #if NR_ARG_REGS >= 1 .global nbif_ccallemu1 + .type nbif_ccallemu1, %function nbif_ccallemu1: str ARG0, [P, #P_ARG0] #if NR_ARG_REGS > 1 @@ -240,6 +254,7 @@ nbif_ccallemu1: #endif .global nbif_ccallemu0 + .type nbif_ccallemu0, %function nbif_ccallemu0: /* We use r1 not ARG0 here because ARG0 is not defined when NR_ARG_REGS == 0. */ @@ -254,6 +269,7 @@ nbif_ccallemu0: * This is where native code suspends. */ .global nbif_suspend_0 + .type nbif_suspend_0, %function nbif_suspend_0: mov r0, #HIPE_MODE_SWITCH_RES_SUSPEND b .suspend_exit @@ -262,6 +278,7 @@ nbif_suspend_0: * Suspend from a receive (waiting for a message) */ .global nbif_suspend_msg + .type nbif_suspend_msg, %function nbif_suspend_msg: mov r0, #HIPE_MODE_SWITCH_RES_WAIT b .suspend_exit @@ -272,6 +289,7 @@ nbif_suspend_msg: * else { return 0; } */ .global nbif_suspend_msg_timeout + .type nbif_suspend_msg_timeout, %function nbif_suspend_msg_timeout: ldr r1, [P, #P_FLAGS] mov r0, #HIPE_MODE_SWITCH_RES_WAIT_TIMEOUT @@ -286,23 +304,31 @@ nbif_suspend_msg_timeout: * This is the default exception handler for native code. */ .global nbif_fail + .type nbif_fail, %function nbif_fail: mov r0, #HIPE_MODE_SWITCH_RES_THROW b .flush_exit /* no need to save RA */ .global nbif_0_gc_after_bif - .global nbif_1_gc_after_bif - .global nbif_2_gc_after_bif - .global nbif_3_gc_after_bif + .type nbif_0_gc_after_bif, %function nbif_0_gc_after_bif: mov r1, #0 b .gc_after_bif + + .global nbif_1_gc_after_bif + .type nbif_1_gc_after_bif, %function nbif_1_gc_after_bif: mov r1, #1 b .gc_after_bif + + .global nbif_2_gc_after_bif + .type nbif_2_gc_after_bif, %function nbif_2_gc_after_bif: mov r1, #2 b .gc_after_bif + + .global nbif_3_gc_after_bif + .type nbif_3_gc_after_bif, %function nbif_3_gc_after_bif: mov r1, #3 /*FALLTHROUGH*/ @@ -330,18 +356,25 @@ nbif_3_gc_after_bif: * TEMP_LR contains a copy of LR */ .global nbif_0_simple_exception + .type nbif_0_simple_exception, %function nbif_0_simple_exception: mov r1, #0 b .nbif_simple_exception + .global nbif_1_simple_exception + .type nbif_1_simple_exception, %function nbif_1_simple_exception: mov r1, #1 b .nbif_simple_exception + .global nbif_2_simple_exception + .type nbif_2_simple_exception, %function nbif_2_simple_exception: mov r1, #2 b .nbif_simple_exception + .global nbif_3_simple_exception + .type nbif_3_simple_exception, %function nbif_3_simple_exception: mov r1, #3 /*FALLTHROUGH*/ @@ -385,6 +418,7 @@ nbif_3_simple_exception: * the gray/white stack boundary */ .global nbif_stack_trap_ra + .type nbif_stack_trap_ra, %function nbif_stack_trap_ra: /* a return address, not a function */ # This only handles a single return value. # If we have more, we need to save them in the PCB. @@ -401,6 +435,7 @@ nbif_stack_trap_ra: /* a return address, not a function */ * Caller saved its LR in TEMP_LR (== TEMP1) before calling us. */ .global hipe_arm_inc_stack + .type hipe_arm_inc_stack, %function hipe_arm_inc_stack: STORE_ARG_REGS mov TEMP_ARG0, lr diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index 2497d51df1..c9eee2acf2 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -1022,7 +1022,7 @@ BIF_RETTYPE hipe_conv_big_to_float(BIF_ALIST_1) */ void hipe_emulate_fpe(Process* p) { - if (!finite(p->hipe.float_result)) { + if (!isfinite(p->hipe.float_result)) { p->fp_exception = 1; } } diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index 4ddc2790b1..1ae1d17b7f 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -2,7 +2,7 @@ * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2014. 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 @@ -187,6 +187,9 @@ void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure) void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) { + if (!hipe_bifcall_from_native_is_recursive(p)) + return; + /* ensure that at least 2 words are available on the BEAM stack */ if ((p->stop - 2) < p->htop) { DPRINTF("calling gc to reserve BEAM stack size"); @@ -195,25 +198,26 @@ void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) } p->stop -= 2; p->stop[0] = NIL; - p->stop[1] = NIL; + p->stop[1] = hipe_beam_catch_throw; } static __inline__ void hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) { - if (p->flags & F_DISABLE_GC) { + if (&p->stop[1] < p->hend && p->stop[1] == hipe_beam_catch_throw) { /* Trap frame already reserved */ - ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + ASSERT(p->stop[0] == NIL); } else { + ASSERT(!(p->flags & F_DISABLE_GC)); if ((p->stop - 2) < p->htop) { DPRINTF("calling gc to increase BEAM stack size"); p->fcalls -= erts_garbage_collect(p, 2, reg, arity); ASSERT(!((p->stop - 2) < p->htop)); } p->stop -= 2; + p->stop[1] = hipe_beam_catch_throw; } - p->stop[1] = hipe_beam_catch_throw; p->stop[0] = make_cp(p->cp); ++p->catches; p->cp = hipe_beam_pc_return; @@ -221,12 +225,16 @@ hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) void hipe_unreserve_beam_trap_frame(Process *p) { - ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + if (!hipe_bifcall_from_native_is_recursive(p)) + return; + + ASSERT(p->stop[0] == NIL && p->stop[1] == hipe_beam_catch_throw); p->stop += 2; } static __inline__ void hipe_pop_beam_trap_frame(Process *p) { + ASSERT(p->stop[1] == hipe_beam_catch_throw); p->cp = cp_val(p->stop[0]); --p->catches; p->stop += 2; diff --git a/erts/emulator/hipe/hipe_risc_glue.h b/erts/emulator/hipe/hipe_risc_glue.h index cc2671c016..dbb7086dae 100644 --- a/erts/emulator/hipe/hipe_risc_glue.h +++ b/erts/emulator/hipe/hipe_risc_glue.h @@ -214,6 +214,14 @@ hipe_trap_from_native_is_recursive(Process *p) return 0; } +/* Native called BIF. Is it a recursive call? + i.e should we return back to native when BIF is done? */ +static __inline__ int +hipe_bifcall_from_native_is_recursive(Process *p) +{ + return (p->hipe.nra != (void(*)(void))&nbif_return); +} + /* Native makes a call which needs to unload the parameters. This differs from hipe_call_from_native_is_recursive() in diff --git a/erts/emulator/hipe/hipe_x86_glue.h b/erts/emulator/hipe/hipe_x86_glue.h index 63ad250d60..4b6e495b9a 100644 --- a/erts/emulator/hipe/hipe_x86_glue.h +++ b/erts/emulator/hipe/hipe_x86_glue.h @@ -207,6 +207,14 @@ hipe_trap_from_native_is_recursive(Process *p) return 0; } +/* Native called BIF. Is it a recursive call? + i.e should we return back to native when BIF is done? */ +static __inline__ int +hipe_bifcall_from_native_is_recursive(Process *p) +{ + return (*p->hipe.nsp != (Eterm)nbif_return); +} + /* Native makes a call which needs to unload the parameters. This differs from hipe_call_from_native_is_recursive() in diff --git a/erts/emulator/internal_doc/CarrierMigration.md b/erts/emulator/internal_doc/CarrierMigration.md index b93c11c6ec..2a9594db25 100644 --- a/erts/emulator/internal_doc/CarrierMigration.md +++ b/erts/emulator/internal_doc/CarrierMigration.md @@ -16,12 +16,12 @@ When a carrier is empty, i.e. contains only one large free block, it is deallocated. Since multiblock carriers can contain both allocated blocks and free blocks at the same time, an allocator instance might be stuck with a large amount of poorly utilized carriers if the memory -load decrease. After a peak in memory usage it is expected that not -all memory can be returned since the blocks still allocated is likely +load decreases. After a peak in memory usage it is expected that not +all memory can be returned since the blocks still allocated are likely to be dispersed over multiple carriers. Such poorly utilized carriers -can usually be reused if the memory load increase again. However, +can usually be reused if the memory load increases again. However, since each scheduler thread manages its own set of allocator -instances, and memory load is not necessarily connected to CPU load we +instances, and memory load is not necessarily correlated to CPU load, we might get into a situation where there are lots of poorly utilized multiblock carriers on some allocator instances while we need to allocate new multiblock carriers on other allocator instances. In @@ -50,13 +50,13 @@ the allocator instance manages. Free blocks in one specific carrier can be referred to from potentially every other carrier that is managed, and the amount of such references can be huge. That is, the work of removing the free blocks of such a carrier from the search -tree will be huge. One way of solving this could be to not migrate +tree will be huge. One way of solving this could be not to migrate carriers that contain lots of free blocks, but this would prevent us -from migrating carriers that potentially needs to be migrated in order +from migrating carriers that potentially need to be migrated in order to solve the problem we set out to solve. By using one data structure of free blocks in each carrier and an -allocator instance wide data structure of carriers managed by the +allocator instance-wide data structure of carriers managed by the allocator instance, the work needed in order to remove and add carriers can be kept to a minimum. When migration of carriers is enabled on a specific allocator type, we require that an allocation @@ -76,9 +76,9 @@ through a pool of carriers. In order for a carrier migration to complete, one scheduler needs to move the carrier into the pool, and another scheduler needs to take the carrier out of the pool. -The pool is implemented as a lock free, circular, double linked, +The pool is implemented as a lock-free, circular, double linked, list. The list contains a sentinel which is used as the starting point -when inserting to, or fetching from the pool. Carriers in the pool are +when inserting to, or fetching from, the pool. Carriers in the pool are elements in this list. The list can be modified by all scheduler threads @@ -108,19 +108,19 @@ all search operations need to read the content of the sentinel. If we were to modify the sentinel, the cache line containing the sentinel would unnecessarily be bounced between processors. -The `prev`, and `next` fields in the elements of the list contains the +The `prev` and `next` fields in the elements of the list contain the value of the pointer, a modification marker, and a deleted marker. Memory operations on these fields are done using atomic memory operations. When a thread has set the modification marker in a field, no-one except the thread that set the marker is allowed to modify the -field. If multiple modification markers needs to be set, we always +field. If multiple modification markers need to be set, we always begin with `next` fields followed by `prev` fields in the order following the actual pointers. This guarantees that no deadlocks will occur. When a carrier is being removed from a pool, we mark it with a thread progress value that needs to be reached before we are allowed to -modify the `next`, and `prev` fields. That is, until we reach this +modify the `next` and `prev` fields. That is, until we reach this thread progress we are not allowed to insert the carrier into the pool again, and we are not allowed to deallocate the carrier. This ensures that threads inspecting the pool always will be able to traverse the @@ -130,12 +130,12 @@ threads may have references to it via the pool. ### Migration ### -There exist one pool for each allocator type enabling migration of +There exists one pool for each allocator type enabling migration of carriers between scheduler specific allocator instances of the same allocator type. Each allocator instance keeps track of the current utilization of its -multiblock carriers. When the utilization falls below the "abandon +multiblock carriers. When the total utilization falls below the "abandon carrier utilization limit" it starts to inspect the utilization of the current carrier when deallocations are made. If also the utilization of the carrier falls below the "abandon carrier utilization limit" it @@ -146,28 +146,53 @@ Since the carrier has been unlinked from the data structure of available free blocks, no more allocations will be made in the carrier. The allocator instance putting the carrier into the pool, however, still has the responsibility of performing deallocations in -it while it remains in the pool. +it while it remains in the pool. The allocator instance with this +deallocation responsibility is here called the **employer**. -Each carrier has a flag field containing information about allocator -instance owning the carrier, a flag indicating if the carrier is in +Each carrier has a flag field containing information about the +employing allocator instance, a flag indicating if the carrier is in the pool or not, and a flag indicating if it is busy or not. When the -carrier is in the pool, the owning allocator instance needs to mark it +carrier is in the pool, the employing allocator instance needs to mark it as busy while operating on it. If another thread inspects it in order -to try to fetch it from the pool, it will abort the fetch if it is -busy. When fetching the carrier from the pool, ownership will changed -and further deallocations in the carrier will be redirected to the new -owner using the delayed dealloc functionality. +to try to fetch it from the pool, it will skip it if it is busy. When +fetching the carrier from the pool, employment will change and further +deallocations in the carrier will be redirected to the new +employer using the delayed dealloc functionality. If a carrier in the pool becomes empty, it will be withdrawn from the pool. All carriers that become empty are also always passed to its -originating allocator instance for deallocation using the delayed +**owning** allocator instance for deallocation using the delayed dealloc functionality. Since carriers this way always will be -deallocated by the allocator instance that allocated the carrier the +deallocated by the owner that allocated the carrier, the underlying functionality of allocating and deallocating carriers can remain simple and doesn't have to bother about multiple threads. In a NUMA system we will also not mix carriers originating from multiple NUMA nodes. +In short: + +* The allocator instance that created a carrier **owns** it. +* An empty carrier is always deallocated by its **owner**. +* **Ownership** never changes. +* The allocator instance that uses a carrier **employs** it. +* An **employer** can abandon a carrier into the pool. +* Pooled carriers are not allocated from. +* Deallocation in a pooled carrier is still performed by its **employer**. +* **Employment** can only change when a carrier is fetched from the pool. + +### Searching the pool ### + +To harbor real time characteristics, searching the pool is +limited. We only inspect a limited number of carriers. If none of +those carriers had a free block large enough to satisfy the allocation +request, the search will fail. A carrier in the pool can also be busy +if another thread is currently doing block deallocation work on the +carrier. A busy carrier will also be skipped by the search as it can +not satisfy the request. The pool is lock-free and we do not want to +block, waiting for the other thread to finish. + +#### Before OTP 17.4 #### + When an allocator instance needs more carrier space, it always begins by inspecting its own carriers that are waiting for thread progress before they can be deallocated. If no such carrier could be found, it @@ -176,10 +201,69 @@ it will allocate a new carrier. Regardless of where the allocator instance gets the carrier from it the just links in the carrier into its data structure of free blocks. +#### After OTP 17.4 #### + +The old search algorithm had a problem as the search always started at +the same position in the pool, the sentinel. This could lead to +contention from concurrent searching processes. But even worse, it +could lead to a "bad" state when searches fail with a high rate +leading to new carriers instead being allocated. These new carriers +may later be inserted into the pool due to bad utilization. If the +frequency of insertions into the pool is higher than successful +fetching from the pool, memory will eventually get exhausted. + +This "bad" state consists of a cluster of small and/or highly +fragmented carriers located at the sentinel in the pool. The largest free +block in such a "bad" carrier is rather small, making it unable to satisfy +most allocation requests. As the search always started at the +sentinel, any such "bad" carriers that had been left in the pool would +eventually cluster together at the sentinel. All searches first +have to skip past this cluster of "bad" carriers to reach a "good" +carrier. When the cluster gets to the same size as the search limit, +all searches will essentially fail. + +To counter the "bad cluster" problem and also ease the contention, the +search will now always start by first looking at the allocators **own** +carriers. That is, carriers that were initially created by the +allocator itself and later had been abandoned to the pool. If none of +our own abandoned carrier would do, then the search continues into the +pool, as before, to look for carriers created by other +allocators. However, if we have at least one abandoned carrier of our +own that could not satisfy the request, we can use that as entry point +into the pool. + +The result is that we prefer carriers created by the thread itself, +which is good for NUMA performance. And we get more entry points when +searching the pool, which will ease contention and clustering. + +To do the first search among own carriers, every allocator instance +has two new lists: `pooled_list` and `traitor_list`. These lists are only +accessed by the allocator itself and they only contain the allocator's +own carriers. When an owned carrier is abandoned and put in the +pool, it is also linked into `pooled_list`. When we search our +`pooled_list` and find a carrier that is no longer in the pool, we +move that carrier from `pooled_list` to `traitor_list` as it is now +employed by another allocator. If searching `pooled_list` fails, we +also do a limited search of `traitor_list`. When finding an abandoned +carrier in `traitor_list` it is either employed or moved back to +`pooled_list` if it could not satisfy the allocation request. + +When searching `pooled_list` and `traitor_list` we always start at the +point where the last search ended. This to avoid clustering +problems and increase the probability to find a "good" carrier. As +`pooled_list` and `traitor_list` are only accessed by the owning +allocator instance, they need no thread synchronization at all. + +Furthermore, the search for own carriers that are scheduled +for deallocation is now done as the last search option. The idea is +that it is better to reuse a poorly utilized carrier than to +resurrect an empty carrier that was just about to be released back to +the OS. + ### Result ### The use of this strategy of abandoning carriers with poor utilization -and reusing these in allocator instances with an increased carrier +and reusing them in allocator instances with an increased carrier demand is extremely effective and completely eliminates the problems that otherwise sometimes occurred when CPU load dropped while memory load did not. diff --git a/erts/emulator/internal_doc/SuperCarrier.md b/erts/emulator/internal_doc/SuperCarrier.md new file mode 100644 index 0000000000..0ad6af41de --- /dev/null +++ b/erts/emulator/internal_doc/SuperCarrier.md @@ -0,0 +1,191 @@ +Super Carrier +============= + +A super carrier is large memory area, allocated at VM start, which can +be used during runtime to allocate normal carriers from. + +The super carrier feature was introduced in OTP R16B03. It is +enabled with command line option +MMscs <size in Mb> +and can be configured with other options. + +Problem +------- + +The initial motivation for this feature was customers asking for a way +to pre-allocate physcial memory at VM start for it to use. + +Other problems were different experienced limitations of the OS +implementation of mmap: + +* Increasingly bad performance of mmap/munmap as the number of mmap'ed areas grow. +* Fragmentation problem between mmap'ed areas. + +A third problem was management of low memory in the halfword +emulator. The implementation used a naive linear search structure to +hold free segments which would lead to poor performance when +fragmentation increased. + + +Solution +-------- + +Allocate one large continious area of address space at VM start and +then use that area to satisfy our dynamic memory need during +runtime. In other words: implement our own mmap. + +### Use cases ### + +If command line option +MMscrpm (Reserve Physical Memory) is set to +false, only virtual space is allocated for the super carrier from +start. The super carrier then acts as an "alternative mmap" implementation +without changing the consumption of physical memory pages. Physical +pages will be reserved on demand when an allocation is done from the super +carrier and be unreserved when the memory is released back to the +super carrier. + +If +MMscrpm is set to true, which is default, the initial allocation +will reserve physical memory for the entire super carrier. This can be +used by users that want to ensure a certain *minimum* amount of +physical memory for the VM. + +However, what reservation of physical memory actually means highly +depends on the operating system, and how it is configured. For +example, different memory overcommit settings on Linux drastically +change the behaviour. + +A third feature is to have the super carrier limit the *maximum* +amount of memory used by the VM. If +MMsco (Super Carrier Only) is set +to true, which is default, allocations will only be done from the +super carrier. When the super carrier gets full, the VM will fail due +to out of memory. +If +MMsco is false, allocations will use mmap directly if the super +carrier is full. + + + +### Implementation ### + +The entire super carrier implementation is kept in erl_mmap.c. The +name suggest that it can be viewed as our own mmap implementation. + +A super carrier needs to satisfy two slightly different kinds of +allocation requests; multi block carriers (MBC) and single block +carriers (SBC). They are both rather large blocks of continious +memory, but MBCs and SBCs have different demands on alignment and +size. + +SBCs can have arbitrary size and do only need minimum 8-byte +alignment. + +MBCs are more restricted. They can only have a number of fixed +sizes that are powers of 2. The start address need to have a very +large aligment (currently 256 kb, called "super alignment"). This is a +design choice that allows very low overhead per allocated block in the +MBC. + +To reduce fragmentation within the super carrier, it is good to keep SBCs +and MBCs apart. MBCs with their uniform alignment and sizes can be +packed very efficiently together. SBCs without demand for aligment can +also be allocated quite efficiently together. But mixing them can lead +to a lot of memory wasted when we need to create large holes of +padding to the next alignment limit. + +The super carrier thus contains two areas. One area for MBCs growing from +the bottom and up. And one area for SBCs growing from the top and +down. Like a process with a heap and a stack growing towards each +other. + + +### Data structures ### + +The MBC area is called **sa** as in super aligned and the SBC area is +called **sua** as in super un-aligned. + +Note that the "super" in super alignment and the "super" in super +carrier has nothing to do with each other. We could have choosen +another naming to avoid confusion, such as "meta" carrier or "giant" +aligment. + + +-------+ <---- sua.top + | sua | + | | + |-------| <---- sua.bot + | | + | | + | | + |-------| <---- sa.top + | | + | sa | + | | + +-------+ <---- sa.bot + + +When a carrier is deallocated a free memory segment will be created +inside the corresponding area, unless the carrier was at the very top +(in `sa`) or bottom (in `sua`) in which case the area will just shrink +down or up. + +We need to keep track of all the free segments in order to reuse them +for new carrier allocations. One initial idea was to use the same +mechanism that is used to keep track of free blocks within MBCs +(alloc_util and the different strategies). However, that would not be +as straight forward as one can think and can also waste quite a lot of +memory as it uses prepended block headers. The granularity of the +super carrier is one memory page (usually 4kb). We want to allocate +and free entire pages and we don't want to waste an entire page just +to hold the block header of the following pages. + +Instead we store the meta information about all the free segments in a +dedicated area apart from the `sa` and `sua` areas. Every free segment is +represented by a descriptor struct (`ErtsFreeSegDesc`). + + typedef struct { + RBTNode snode; /* node in 'stree' */ + RBTNode anode; /* node in 'atree' */ + char* start; + char* end; + }ErtsFreeSegDesc; + +To find the smallest free segment that will satisfy a carrier allocation +(best fit), the free segments are organized in a tree sorted by +size (`stree`). We search in this tree at allocation. If no free segment of +sufficient size was found, the area (`sa` or `sua`) is instead expanded. +If two or more free segments with equal size exist, the one at lowest +address is choosen for `sa` and highest address for `sua`. + +At carrier deallocation, we want to coalesce with any adjacent free +segments, to form one large free segment. To do that, all free +segments are also organized in a tree sorted in address order (`atree`). + +So, in total we keep four trees of free descriptors for the super +carrier; two for `sa` and two for `sua`. They all use the same +red-black-tree implementation that support the different sorting +orders used. + +When allocating a new MBC we first search after a free segment in `sa`, +then try to raise `sa.top`, and then as a fallback try to search after a +free segment in `sua`. When an MBC is allocated in `sua`, a larger segment +is allocated which is then trimmed to obtain the right +alignment. Allocation search for an SBC is done in reverse order. When +an SBC is allocated in `sa`, the size is aligned up to super aligned +size. + +### The free descriptor area ### + +As mentioned above, the descriptors for the free segments are +allocated in a separate area. This area has a constant configurable +size (+MMscrfsd) that defaults to 65536 descriptors. This should be +more than enough in most cases. If the descriptors area should fill up, +new descriptor areas will be allocated first directly from the OS, and +then from `sua` and `sa` in the super carrier, and lastly from the memory +segment itself which is being deallocated. Allocating free descriptor +areas from the super carrier is only a last resort, and should be +avoided, as it creates fragmentation. + +### Halfword emulator ### + +The halfword emulator uses the super carrier implementation to manage +its low memory mappings thar are needed for all term storage. The +super carrier can here not be configured by command line options. One +could imagine a second configurable instance of the super carrier used +by high memory allocation, but that has not been implemented. diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index 1db673e7f3..0051b45b31 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -52,8 +52,17 @@ typedef char EventStateType; #define ERTS_EV_TYPE_STOP_USE ((EventStateType) 3) /* pending stop_select */ typedef char EventStateFlags; -#define ERTS_EV_FLAG_USED ((EventStateFlags) 1) /* ERL_DRV_USE has been turned on */ +#define ERTS_EV_FLAG_USED ((EventStateFlags) 1) /* ERL_DRV_USE has been turned on */ +#define ERTS_EV_FLAG_DEFER_IN_EV ((EventStateFlags) 2) +#define ERTS_EV_FLAG_DEFER_OUT_EV ((EventStateFlags) 4) +#ifdef DEBUG +# define ERTS_ACTIVE_FD_INC 2 +#else +# define ERTS_ACTIVE_FD_INC 128 +#endif + +#define ERTS_CHECK_IO_POLL_RES_LEN 512 #if defined(ERTS_KERNEL_POLL_VERSION) # define ERTS_CIO_EXPORT(FUNC) FUNC ## _kp @@ -67,6 +76,7 @@ typedef char EventStateFlags; (ERTS_POLL_USE_POLL && !ERTS_POLL_USE_KERNEL_POLL) #define ERTS_CIO_POLL_CTL ERTS_POLL_EXPORT(erts_poll_control) +#define ERTS_CIO_POLL_CTLV ERTS_POLL_EXPORT(erts_poll_controlv) #define ERTS_CIO_POLL_WAIT ERTS_POLL_EXPORT(erts_poll_wait) #ifdef ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT #define ERTS_CIO_POLL_AS_INTR ERTS_POLL_EXPORT(erts_poll_async_sig_interrupt) @@ -85,6 +95,13 @@ static struct pollset_info { ErtsPollSet ps; erts_smp_atomic_t in_poll_wait; /* set while doing poll */ + struct { + int six; /* start index */ + int eix; /* end index */ + erts_smp_atomic32_t no; + int size; + ErtsSysFdType *array; + } active_fd; #ifdef ERTS_SMP struct removed_fd* removed_list; /* list of deselected fd's*/ erts_smp_spinlock_t removed_list_lock; @@ -97,9 +114,11 @@ typedef struct { SafeHashBucket hb; #endif ErtsSysFdType fd; - union { - ErtsDrvEventDataState *event; /* ERTS_EV_TYPE_DRV_EV */ + struct { ErtsDrvSelectDataState *select; /* ERTS_EV_TYPE_DRV_SEL */ +#if ERTS_CIO_HAVE_DRV_EVENT + ErtsDrvEventDataState *event; /* ERTS_EV_TYPE_DRV_EV */ +#endif erts_driver_t* drv_ptr; /* ERTS_EV_TYPE_STOP_USE */ } driver; ErtsPollEvents events; @@ -169,6 +188,10 @@ static ERTS_INLINE ErtsDrvEventState* hash_new_drv_ev_state(ErtsSysFdType fd) ErtsDrvEventState tmpl; tmpl.fd = fd; tmpl.driver.select = NULL; +#if ERTS_CIO_HAVE_DRV_EVENT + tmpl.driver.event = NULL; +#endif + tmpl.driver.drv_ptr = NULL; tmpl.events = 0; tmpl.remove_cnt = 0; tmpl.type = ERTS_EV_TYPE_NONE; @@ -209,6 +232,69 @@ ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(removed_fd, struct removed_fd, 64, ERTS_ALC_T_F #endif static ERTS_INLINE void +init_iotask(ErtsIoTask *io_task) +{ + erts_port_task_handle_init(&io_task->task); + erts_smp_atomic_init_nob(&io_task->executed_time, ~((erts_aint_t) 0)); +} + +static ERTS_INLINE int +is_iotask_active(ErtsIoTask *io_task, erts_aint_t current_cio_time) +{ + if (erts_port_task_is_scheduled(&io_task->task)) + return 1; + if (erts_smp_atomic_read_nob(&io_task->executed_time) == current_cio_time) + return 1; + return 0; +} + +static ERTS_INLINE ErtsDrvSelectDataState * +alloc_drv_select_data(void) +{ + ErtsDrvSelectDataState *dsp = erts_alloc(ERTS_ALC_T_DRV_SEL_D_STATE, + sizeof(ErtsDrvSelectDataState)); + dsp->inport = NIL; + dsp->outport = NIL; + init_iotask(&dsp->iniotask); + init_iotask(&dsp->outiotask); + return dsp; +} + +static ERTS_INLINE void +free_drv_select_data(ErtsDrvSelectDataState *dsp) +{ + ASSERT(!erts_port_task_is_scheduled(&dsp->iniotask.task)); + ASSERT(!erts_port_task_is_scheduled(&dsp->outiotask.task)); + erts_free(ERTS_ALC_T_DRV_SEL_D_STATE, dsp); +} + +#if ERTS_CIO_HAVE_DRV_EVENT + +static ERTS_INLINE ErtsDrvEventDataState * +alloc_drv_event_data(void) +{ + ErtsDrvEventDataState *dep = erts_alloc(ERTS_ALC_T_DRV_EV_D_STATE, + sizeof(ErtsDrvEventDataState)); + dep->port = NIL; + dep->data = NULL; + dep->removed_events = 0; +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + dep->deferred_events = 0; +#endif + init_iotask(&dep->iotask); + return dep; +} + +static ERTS_INLINE void +free_drv_event_data(ErtsDrvEventDataState *dep) +{ + ASSERT(!erts_port_task_is_scheduled(&dep->iotask.task)); + erts_free(ERTS_ALC_T_DRV_EV_D_STATE, dep); +} + +#endif /* ERTS_CIO_HAVE_DRV_EVENT */ + +static ERTS_INLINE void remember_removed(ErtsDrvEventState *state, struct pollset_info* psi) { #ifdef ERTS_SMP @@ -288,7 +374,7 @@ forget_removed(struct pollset_info* psi) drv_ptr = state->driver.drv_ptr; ASSERT(drv_ptr); state->type = ERTS_EV_TYPE_NONE; - state->flags = 0; + state->flags &= ~ERTS_EV_FLAG_USED; state->driver.drv_ptr = NULL; /* Fall through */ case ERTS_EV_TYPE_NONE: @@ -345,6 +431,10 @@ grow_drv_ev_state(int min_ix) for (i = erts_smp_atomic_read_nob(&drv_ev_state_len); i < new_len; i++) { drv_ev_state[i].fd = (ErtsSysFdType) i; drv_ev_state[i].driver.select = NULL; +#if ERTS_CIO_HAVE_DRV_EVENT + drv_ev_state[i].driver.event = NULL; +#endif + drv_ev_state[i].driver.drv_ptr = NULL; drv_ev_state[i].events = 0; drv_ev_state[i].remove_cnt = 0; drv_ev_state[i].type = ERTS_EV_TYPE_NONE; @@ -365,11 +455,7 @@ grow_drv_ev_state(int min_ix) static ERTS_INLINE void abort_task(Eterm id, ErtsPortTaskHandle *pthp, EventStateType type) { - if (is_nil(id)) { - ASSERT(type == ERTS_EV_TYPE_NONE - || !erts_port_task_is_scheduled(pthp)); - } - else if (erts_port_task_is_scheduled(pthp)) { + if (is_not_nil(id) && erts_port_task_is_scheduled(pthp)) { erts_port_task_abort(pthp); ASSERT(erts_is_port_alive(id)); } @@ -384,7 +470,7 @@ abort_tasks(ErtsDrvEventState *state, int mode) #if ERTS_CIO_HAVE_DRV_EVENT case ERTS_EV_TYPE_DRV_EV: abort_task(state->driver.event->port, - &state->driver.event->task, + &state->driver.event->iotask.task, ERTS_EV_TYPE_DRV_EV); return; #endif @@ -398,14 +484,14 @@ abort_tasks(ErtsDrvEventState *state, int mode) case ERL_DRV_WRITE: ASSERT(state->type == ERTS_EV_TYPE_DRV_SEL); abort_task(state->driver.select->outport, - &state->driver.select->outtask, + &state->driver.select->outiotask.task, state->type); if (mode == ERL_DRV_WRITE) break; case ERL_DRV_READ: ASSERT(state->type == ERTS_EV_TYPE_DRV_SEL); abort_task(state->driver.select->inport, - &state->driver.select->intask, + &state->driver.select->iniotask.task, state->type); break; default: @@ -443,16 +529,14 @@ deselect(ErtsDrvEventState *state, int mode) if (!(state->events)) { switch (state->type) { case ERTS_EV_TYPE_DRV_SEL: - ASSERT(!erts_port_task_is_scheduled(&state->driver.select->intask)); - ASSERT(!erts_port_task_is_scheduled(&state->driver.select->outtask)); - erts_free(ERTS_ALC_T_DRV_SEL_D_STATE, - state->driver.select); + state->driver.select->inport = NIL; + state->driver.select->outport = NIL; break; #if ERTS_CIO_HAVE_DRV_EVENT case ERTS_EV_TYPE_DRV_EV: - ASSERT(!erts_port_task_is_scheduled(&state->driver.event->task)); - erts_free(ERTS_ALC_T_DRV_EV_D_STATE, - state->driver.event); + state->driver.event->port = NIL; + state->driver.event->data = NULL; + state->driver.event->removed_events = (ErtsPollEvents) 0; break; #endif case ERTS_EV_TYPE_NONE: @@ -462,20 +546,297 @@ deselect(ErtsDrvEventState *state, int mode) break; } - state->driver.select = NULL; state->type = ERTS_EV_TYPE_NONE; - state->flags = 0; + state->flags &= ~ERTS_EV_FLAG_USED; remember_removed(state, &pollset); } } - #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS # define IS_FD_UNKNOWN(state) ((state)->type == ERTS_EV_TYPE_NONE && (state)->remove_cnt == 0) #else # define IS_FD_UNKNOWN(state) ((state) == NULL) #endif +static ERTS_INLINE void +check_fd_cleanup(ErtsDrvEventState *state, +#if ERTS_CIO_HAVE_DRV_EVENT + ErtsDrvEventDataState **free_event, +#endif + ErtsDrvSelectDataState **free_select) +{ + erts_aint_t current_cio_time; + + ERTS_SMP_LC_ASSERT(erts_smp_lc_mtx_is_locked(fd_mtx(state->fd))); + + current_cio_time = erts_smp_atomic_read_acqb(&erts_check_io_time); + *free_select = NULL; + if (state->driver.select + && (state->type != ERTS_EV_TYPE_DRV_SEL) + && !is_iotask_active(&state->driver.select->iniotask, current_cio_time) + && !is_iotask_active(&state->driver.select->outiotask, current_cio_time)) { + + *free_select = state->driver.select; + state->driver.select = NULL; + } + +#if ERTS_CIO_HAVE_DRV_EVENT + *free_event = NULL; + if (state->driver.event + && (state->type != ERTS_EV_TYPE_DRV_EV) + && !is_iotask_active(&state->driver.event->iotask, current_cio_time)) { + + *free_event = state->driver.event; + state->driver.event = NULL; + } +#endif + +#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS + if (((state->type != ERTS_EV_TYPE_NONE) + | state->remove_cnt +#if ERTS_CIO_HAVE_DRV_EVENT + | (state->driver.event != NULL) +#endif + | (state->driver.select != NULL)) == 0) { + + hash_erase_drv_ev_state(state); + + } +#endif +} + +static ERTS_INLINE int +check_cleanup_active_fd(ErtsSysFdType fd, +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + ErtsPollControlEntry *pce, + int *pce_ix, +#endif + erts_aint_t current_cio_time) +{ + ErtsDrvEventState *state; + int active = 0; + erts_smp_mtx_t *mtx = fd_mtx(fd); + void *free_select = NULL; +#if ERTS_CIO_HAVE_DRV_EVENT + void *free_event = NULL; +#endif +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + ErtsPollEvents evon = 0, evoff = 0; +#endif + + erts_smp_mtx_lock(mtx); + +#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS + state = &drv_ev_state[(int) fd]; +#else + state = hash_get_drv_ev_state(fd); /* may be NULL! */ + if (state) +#endif + { + if (state->driver.select) { +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + if (is_iotask_active(&state->driver.select->iniotask, current_cio_time)) { + active = 1; + if ((state->events & ERTS_POLL_EV_IN) + && !(state->flags & ERTS_EV_FLAG_DEFER_IN_EV)) { + evoff |= ERTS_POLL_EV_IN; + state->flags |= ERTS_EV_FLAG_DEFER_IN_EV; + } + } + else if (state->flags & ERTS_EV_FLAG_DEFER_IN_EV) { + if (state->events & ERTS_POLL_EV_IN) + evon |= ERTS_POLL_EV_IN; + state->flags &= ~ERTS_EV_FLAG_DEFER_IN_EV; + } + if (is_iotask_active(&state->driver.select->outiotask, current_cio_time)) { + active = 1; + if ((state->events & ERTS_POLL_EV_OUT) + && !(state->flags & ERTS_EV_FLAG_DEFER_OUT_EV)) { + evoff |= ERTS_POLL_EV_OUT; + state->flags |= ERTS_EV_FLAG_DEFER_OUT_EV; + } + } + else if (state->flags & ERTS_EV_FLAG_DEFER_OUT_EV) { + if (state->events & ERTS_POLL_EV_OUT) + evon |= ERTS_POLL_EV_OUT; + state->flags &= ~ERTS_EV_FLAG_DEFER_OUT_EV; + } + if (active) + (void) 0; + else +#else + if (is_iotask_active(&state->driver.select->iniotask, current_cio_time) + || is_iotask_active(&state->driver.select->outiotask, current_cio_time)) + active = 1; + else +#endif + if (state->type != ERTS_EV_TYPE_DRV_SEL) { + free_select = state->driver.select; + state->driver.select = NULL; + } + } + +#if ERTS_CIO_HAVE_DRV_EVENT + if (state->driver.event) { + if (is_iotask_active(&state->driver.event->iotask, current_cio_time)) { +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + ErtsPollEvents evs = state->events & ~state->driver.event->deferred_events; + if (evs) { + evoff |= evs; + state->driver.event->deferred_events |= evs; + } +#endif + active = 1; + } + else if (state->type != ERTS_EV_TYPE_DRV_EV) { + free_event = state->driver.event; + state->driver.event = NULL; + } +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + else { + ErtsPollEvents evs = state->events & state->driver.event->deferred_events; + if (evs) { + evon |= evs; + state->driver.event->deferred_events = 0; + } + } +#endif + + } +#endif + +#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS + if (((state->type != ERTS_EV_TYPE_NONE) | state->remove_cnt | active) == 0) + hash_erase_drv_ev_state(state); +#endif + + } + + erts_smp_mtx_unlock(mtx); + + if (free_select) + free_drv_select_data(free_select); +#if ERTS_CIO_HAVE_DRV_EVENT + if (free_event) + free_drv_event_data(free_event); +#endif + +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + if (evoff) { + ErtsPollControlEntry *pcep = &pce[(*pce_ix)++]; + pcep->fd = fd; + pcep->events = evoff; + pcep->on = 0; + } + if (evon) { + ErtsPollControlEntry *pcep = &pce[(*pce_ix)++]; + pcep->fd = fd; + pcep->events = evon; + pcep->on = 1; + } +#endif + + return active; +} + +static void +check_cleanup_active_fds(erts_aint_t current_cio_time) +{ + int six = pollset.active_fd.six; + int eix = pollset.active_fd.eix; + erts_aint32_t no = erts_smp_atomic32_read_dirty(&pollset.active_fd.no); + int size = pollset.active_fd.size; + int ix = six; +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + /* every fd might add two entries */ + Uint pce_sz = 2*sizeof(ErtsPollControlEntry)*no; + ErtsPollControlEntry *pctrl_entries = (pce_sz + ? erts_alloc(ERTS_ALC_T_TMP, pce_sz) + : NULL); + int pctrl_ix = 0; +#endif + + while (ix != eix) { + ErtsSysFdType fd = pollset.active_fd.array[ix]; + int nix = ix + 1; + if (nix >= size) + nix = 0; + ASSERT(fd != ERTS_SYS_FD_INVALID); + if (!check_cleanup_active_fd(fd, +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + pctrl_entries, + &pctrl_ix, +#endif + current_cio_time)) { + no--; + if (ix == six) { +#ifdef DEBUG + pollset.active_fd.array[ix] = ERTS_SYS_FD_INVALID; +#endif + six = nix; + } + else { + pollset.active_fd.array[ix] = pollset.active_fd.array[six]; +#ifdef DEBUG + pollset.active_fd.array[six] = ERTS_SYS_FD_INVALID; +#endif + six++; + if (six >= size) + six = 0; + } + } + ix = nix; + } + +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + ASSERT(pctrl_ix <= pce_sz/sizeof(ErtsPollControlEntry)); + if (pctrl_ix) + ERTS_CIO_POLL_CTLV(pollset.ps, pctrl_entries, pctrl_ix); + if (pctrl_entries) + erts_free(ERTS_ALC_T_TMP, pctrl_entries); +#endif + + pollset.active_fd.six = six; + pollset.active_fd.eix = eix; + erts_smp_atomic32_set_relb(&pollset.active_fd.no, no); +} + +static ERTS_INLINE void +add_active_fd(ErtsSysFdType fd) +{ + int eix = pollset.active_fd.eix; + int size = pollset.active_fd.size; + + + pollset.active_fd.array[eix] = fd; + + erts_smp_atomic32_set_relb(&pollset.active_fd.no, + (erts_smp_atomic32_read_dirty(&pollset.active_fd.no) + + 1)); + + eix++; + if (eix >= size) + eix = 0; + if (pollset.active_fd.six == eix) { + pollset.active_fd.six = 0; + eix = size; + size += ERTS_ACTIVE_FD_INC; + pollset.active_fd.array = erts_realloc(ERTS_ALC_T_ACTIVE_FD_ARR, + pollset.active_fd.array, + sizeof(ErtsSysFdType)*size); + pollset.active_fd.size = size; +#ifdef DEBUG + { + int i; + for (i = eix + 1; i < size; i++) + pollset.active_fd.array[i] = ERTS_SYS_FD_INVALID; + } +#endif + + } + + pollset.active_fd.eix = eix; +} int ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, @@ -492,6 +853,10 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, ErtsDrvEventState *state; int wake_poller; int ret; +#if ERTS_CIO_HAVE_DRV_EVENT + ErtsDrvEventDataState *free_event = NULL; +#endif + ErtsDrvSelectDataState *free_select = NULL; #ifdef USE_VM_PROBES DTRACE_CHARBUF(name, 64); #endif @@ -593,9 +958,9 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, if (new_events & (ERTS_POLL_EV_ERR|ERTS_POLL_EV_NVAL)) { if (state->type == ERTS_EV_TYPE_DRV_SEL && !state->events) { state->type = ERTS_EV_TYPE_NONE; - state->flags = 0; - erts_free(ERTS_ALC_T_DRV_SEL_D_STATE, state->driver.select); - state->driver.select = NULL; + state->flags &= ~ERTS_EV_FLAG_USED; + state->driver.select->inport = NIL; + state->driver.select->outport = NIL; } ret = -1; goto done; @@ -613,18 +978,10 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, state->events = new_events; if (ctl_events) { if (on) { - if (state->type == ERTS_EV_TYPE_NONE) { - ErtsDrvSelectDataState *dsdsp - = erts_alloc(ERTS_ALC_T_DRV_SEL_D_STATE, - sizeof(ErtsDrvSelectDataState)); - dsdsp->inport = NIL; - dsdsp->outport = NIL; - erts_port_task_handle_init(&dsdsp->intask); - erts_port_task_handle_init(&dsdsp->outtask); - ASSERT(state->driver.select == NULL); - state->driver.select = dsdsp; + if (!state->driver.select) + state->driver.select = alloc_drv_select_data(); + if (state->type == ERTS_EV_TYPE_NONE) state->type = ERTS_EV_TYPE_DRV_SEL; - } ASSERT(state->type == ERTS_EV_TYPE_DRV_SEL); if (ctl_events & ERTS_POLL_EV_IN) state->driver.select->inport = id; @@ -645,17 +1002,12 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, state->driver.select->outport = NIL; } if (new_events == 0) { - ASSERT(!erts_port_task_is_scheduled(&state->driver.select->intask)); - ASSERT(!erts_port_task_is_scheduled(&state->driver.select->outtask)); if (old_events != 0) { remember_removed(state, &pollset); } if ((mode & ERL_DRV_USE) || !(state->flags & ERTS_EV_FLAG_USED)) { state->type = ERTS_EV_TYPE_NONE; - state->flags = 0; - erts_free(ERTS_ALC_T_DRV_SEL_D_STATE, - state->driver.select); - state->driver.select = NULL; + state->flags &= ~ERTS_EV_FLAG_USED; } /*else keep it, as fd will probably be selected upon again */ } @@ -686,13 +1038,15 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix, ret = 0; -done:; -#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS - if (state->type == ERTS_EV_TYPE_NONE && state->remove_cnt == 0) { - hash_erase_drv_ev_state(state); - } +done: + + check_fd_cleanup(state, +#if ERTS_CIO_HAVE_DRV_EVENT + &free_event, #endif -done_unknown: + &free_select); + +done_unknown: erts_smp_mtx_unlock(fd_mtx(fd)); if (stop_select_fn) { int was_unmasked = erts_block_fpe(); @@ -700,6 +1054,12 @@ done_unknown: (*stop_select_fn)(e, NULL); erts_unblock_fpe(was_unmasked); } + if (free_select) + free_drv_select_data(free_select); +#if ERTS_CIO_HAVE_DRV_EVENT + if (free_event) + free_drv_event_data(free_event); +#endif return ret; } @@ -719,6 +1079,10 @@ ERTS_CIO_EXPORT(driver_event)(ErlDrvPort ix, ErtsDrvEventState *state; int do_wake = 0; int ret; +#if ERTS_CIO_HAVE_DRV_EVENT + ErtsDrvEventDataState *free_event; +#endif + ErtsDrvSelectDataState *free_select; Port *prt = erts_drvport2port(ix); if (prt == ERTS_INVALID_ERL_DRV_PORT) @@ -799,10 +1163,8 @@ ERTS_CIO_EXPORT(driver_event)(ErlDrvPort ix, state->driver.event->removed_events |= remove_events; } else { - state->driver.event - = erts_alloc(ERTS_ALC_T_DRV_EV_D_STATE, - sizeof(ErtsDrvEventDataState)); - erts_port_task_handle_init(&state->driver.event->task); + if (!state->driver.event) + state->driver.event = alloc_drv_event_data(); state->driver.event->port = id; state->driver.event->removed_events = (ErtsPollEvents) 0; state->type = ERTS_EV_TYPE_DRV_EV; @@ -812,10 +1174,10 @@ ERTS_CIO_EXPORT(driver_event)(ErlDrvPort ix, else { if (state->type == ERTS_EV_TYPE_DRV_EV) { abort_tasks(state, 0); - erts_free(ERTS_ALC_T_DRV_EV_D_STATE, - state->driver.event); + state->driver.event->port = NIL; + state->driver.event->data = NULL; + state->driver.event->removed_events = (ErtsPollEvents) 0; } - state->driver.select = NULL; state->type = ERTS_EV_TYPE_NONE; remember_removed(state, &pollset); } @@ -825,12 +1187,22 @@ ERTS_CIO_EXPORT(driver_event)(ErlDrvPort ix, ret = 0; done: -#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS - if (state->type == ERTS_EV_TYPE_NONE && state->remove_cnt == 0) { - hash_erase_drv_ev_state(state); - } + + check_fd_cleanup(state, +#if ERTS_CIO_HAVE_DRV_EVENT + &free_event, #endif + &free_select); + erts_smp_mtx_unlock(fd_mtx(fd)); + + if (free_select) + free_drv_select_data(free_select); +#if ERTS_CIO_HAVE_DRV_EVENT + if (free_event) + free_drv_event_data(free_event); +#endif + return ret; #endif } @@ -1027,7 +1399,7 @@ steal_pending_stop_select(erts_dsprintf_buf_t *dsbufp, ErlDrvPort ix, * In either case stop_select should not be called. */ state->type = ERTS_EV_TYPE_NONE; - state->flags = 0; + state->flags &= ~ERTS_EV_FLAG_USED; if (state->driver.drv_ptr->handle) { erts_ddll_dereference_driver(state->driver.drv_ptr->handle); } @@ -1099,38 +1471,103 @@ event_large_fd_error(ErlDrvPort ix, ErtsSysFdType fd, ErlDrvEventData event_data #endif #endif +static ERTS_INLINE int +io_task_schedule_allowed(ErtsDrvEventState *state, + ErtsPortTaskType type, + erts_aint_t current_cio_time) +{ + ErtsIoTask *io_task; + + switch (type) { + case ERTS_PORT_TASK_INPUT: + if (!state->driver.select) + return 0; +#if ERTS_CIO_HAVE_DRV_EVENT + if (state->driver.event) + return 0; +#endif + io_task = &state->driver.select->iniotask; + break; + case ERTS_PORT_TASK_OUTPUT: + if (!state->driver.select) + return 0; +#if ERTS_CIO_HAVE_DRV_EVENT + if (state->driver.event) + return 0; +#endif + io_task = &state->driver.select->outiotask; + break; +#if ERTS_CIO_HAVE_DRV_EVENT + case ERTS_PORT_TASK_EVENT: + if (!state->driver.event) + return 0; + if (state->driver.select) + return 0; + io_task = &state->driver.event->iotask; + break; +#endif + default: + ERTS_INTERNAL_ERROR("Invalid I/O-task type"); + return 0; + } + + return !is_iotask_active(io_task, current_cio_time); +} + static ERTS_INLINE void -iready(Eterm id, ErtsDrvEventState *state) +iready(Eterm id, ErtsDrvEventState *state, erts_aint_t current_cio_time) { - if (erts_port_task_schedule(id, - &state->driver.select->intask, - ERTS_PORT_TASK_INPUT, - (ErlDrvEvent) state->fd) != 0) { - stale_drv_select(id, state, ERL_DRV_READ); + if (io_task_schedule_allowed(state, + ERTS_PORT_TASK_INPUT, + current_cio_time)) { + ErtsIoTask *iotask = &state->driver.select->iniotask; + erts_smp_atomic_set_nob(&iotask->executed_time, current_cio_time); + if (erts_port_task_schedule(id, + &iotask->task, + ERTS_PORT_TASK_INPUT, + (ErlDrvEvent) state->fd) != 0) { + stale_drv_select(id, state, ERL_DRV_READ); + } + add_active_fd(state->fd); } } static ERTS_INLINE void -oready(Eterm id, ErtsDrvEventState *state) +oready(Eterm id, ErtsDrvEventState *state, erts_aint_t current_cio_time) { - if (erts_port_task_schedule(id, - &state->driver.select->outtask, - ERTS_PORT_TASK_OUTPUT, - (ErlDrvEvent) state->fd) != 0) { - stale_drv_select(id, state, ERL_DRV_WRITE); + if (io_task_schedule_allowed(state, + ERTS_PORT_TASK_OUTPUT, + current_cio_time)) { + ErtsIoTask *iotask = &state->driver.select->outiotask; + erts_smp_atomic_set_nob(&iotask->executed_time, current_cio_time); + if (erts_port_task_schedule(id, + &iotask->task, + ERTS_PORT_TASK_OUTPUT, + (ErlDrvEvent) state->fd) != 0) { + stale_drv_select(id, state, ERL_DRV_WRITE); + } + add_active_fd(state->fd); } } #if ERTS_CIO_HAVE_DRV_EVENT static ERTS_INLINE void -eready(Eterm id, ErtsDrvEventState *state, ErlDrvEventData event_data) +eready(Eterm id, ErtsDrvEventState *state, ErlDrvEventData event_data, + erts_aint_t current_cio_time) { - if (erts_port_task_schedule(id, - &state->driver.event->task, - ERTS_PORT_TASK_EVENT, - (ErlDrvEvent) state->fd, - event_data) != 0) { - stale_drv_select(id, state, 0); + if (io_task_schedule_allowed(state, + ERTS_PORT_TASK_EVENT, + current_cio_time)) { + ErtsIoTask *iotask = &state->driver.event->iotask; + erts_smp_atomic_set_nob(&iotask->executed_time, current_cio_time); + if (erts_port_task_schedule(id, + &iotask->task, + ERTS_PORT_TASK_EVENT, + (ErlDrvEvent) state->fd, + event_data) != 0) { + stale_drv_select(id, state, 0); + } + add_active_fd(state->fd); } } #endif @@ -1161,10 +1598,11 @@ ERTS_CIO_EXPORT(erts_check_io_interrupt_timed)(int set, void ERTS_CIO_EXPORT(erts_check_io)(int do_wait) { - ErtsPollResFd pollres[256]; + ErtsPollResFd *pollres; int pollres_len; SysTimeval wait_time; int poll_ret, i; + erts_aint_t current_cio_time; restart: @@ -1181,10 +1619,24 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) wait_time.tv_usec = 0; } + /* + * No need for an atomic inc op when incrementing + * erts_check_io_time, since only one thread can + * check io at a time. + */ + current_cio_time = erts_smp_atomic_read_dirty(&erts_check_io_time); + current_cio_time++; + erts_smp_atomic_set_relb(&erts_check_io_time, current_cio_time); + + check_cleanup_active_fds(current_cio_time); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_check_exact(NULL, 0); /* No locks should be locked */ #endif - pollres_len = sizeof(pollres)/sizeof(ErtsPollResFd); + + pollres_len = erts_smp_atomic32_read_dirty(&pollset.active_fd.no) + ERTS_CHECK_IO_POLL_RES_LEN; + + pollres = erts_alloc(ERTS_ALC_T_TMP, sizeof(ErtsPollResFd)*pollres_len); erts_smp_atomic_set_nob(&pollset.in_poll_wait, 1); @@ -1204,6 +1656,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) if (poll_ret != 0) { erts_smp_atomic_set_nob(&pollset.in_poll_wait, 0); forget_removed(&pollset); + erts_free(ERTS_ALC_T_TMP, pollres); if (poll_ret == EAGAIN) { goto restart; } @@ -1263,15 +1716,15 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) if ((revents & ERTS_POLL_EV_IN) || (!(revents & ERTS_POLL_EV_OUT) && state->events & ERTS_POLL_EV_IN)) { - iready(state->driver.select->inport, state); + iready(state->driver.select->inport, state, current_cio_time); } else if (state->events & ERTS_POLL_EV_OUT) { - oready(state->driver.select->outport, state); + oready(state->driver.select->outport, state, current_cio_time); } } else if (revents & (ERTS_POLL_EV_IN|ERTS_POLL_EV_OUT)) { if (revents & ERTS_POLL_EV_OUT) { - oready(state->driver.select->outport, state); + oready(state->driver.select->outport, state, current_cio_time); } /* Someone might have deselected input since revents was read (true also on the non-smp emulator since @@ -1279,7 +1732,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) revents... */ revents &= ~(~state->events & ERTS_POLL_EV_IN); if (revents & ERTS_POLL_EV_IN) { - iready(state->driver.select->inport, state); + iready(state->driver.select->inport, state, current_cio_time); } } else if (revents & ERTS_POLL_EV_NVAL) { @@ -1287,6 +1740,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) state->driver.select->inport, state->driver.select->outport, state->events); + add_active_fd(state->fd); } break; } @@ -1304,8 +1758,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) if (revents) { event_data->events = state->events; event_data->revents = revents; - - eready(state->driver.event->port, state, event_data); + eready(state->driver.event->port, state, event_data, current_cio_time); } break; } @@ -1323,6 +1776,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) (int) state->type); ASSERT(0); deselect(state, 0); + add_active_fd(state->fd); break; } } @@ -1334,6 +1788,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) } erts_smp_atomic_set_nob(&pollset.in_poll_wait, 0); + erts_free(ERTS_ALC_T_TMP, pollres); forget_removed(&pollset); } @@ -1469,10 +1924,27 @@ static void drv_ev_state_free(void *des) void ERTS_CIO_EXPORT(erts_init_check_io)(void) { + erts_smp_atomic_init_nob(&erts_check_io_time, 0); erts_smp_atomic_init_nob(&pollset.in_poll_wait, 0); + ERTS_CIO_POLL_INIT(); pollset.ps = ERTS_CIO_NEW_POLLSET(); + pollset.active_fd.six = 0; + pollset.active_fd.eix = 0; + erts_smp_atomic32_init_nob(&pollset.active_fd.no, 0); + pollset.active_fd.size = ERTS_ACTIVE_FD_INC; + pollset.active_fd.array = erts_alloc(ERTS_ALC_T_ACTIVE_FD_ARR, + sizeof(ErtsSysFdType)*ERTS_ACTIVE_FD_INC); +#ifdef DEBUG + { + int i; + for (i = 0; i < ERTS_ACTIVE_FD_INC; i++) + pollset.active_fd.array[i] = ERTS_SYS_FD_INVALID; + } +#endif + + #ifdef ERTS_SMP init_removed_fd_alloc(); pollset.removed_list = NULL; @@ -1548,12 +2020,27 @@ Eterm ERTS_CIO_EXPORT(erts_check_io_info)(void *proc) { Process *p = (Process *) proc; - Eterm tags[15], values[15], res; + Eterm tags[16], values[16], res; Uint sz, *szp, *hp, **hpp, memory_size; Sint i; ErtsPollInfo pi; - - ERTS_CIO_POLL_INFO(pollset.ps, &pi); + erts_aint_t cio_time = erts_smp_atomic_read_acqb(&erts_check_io_time); + int active_fds = (int) erts_smp_atomic32_read_acqb(&pollset.active_fd.no); + + while (1) { + erts_aint_t post_cio_time; + int post_active_fds; + + ERTS_CIO_POLL_INFO(pollset.ps, &pi); + + post_cio_time = erts_smp_atomic_read_mb(&erts_check_io_time); + post_active_fds = (int) erts_smp_atomic32_read_acqb(&pollset.active_fd.no); + if (cio_time == post_cio_time && active_fds == post_active_fds) + break; + cio_time = post_cio_time; + active_fds = post_active_fds; + } + memory_size = pi.memory_size; #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS memory_size += sizeof(ErtsDrvEventState) * erts_smp_atomic_read_nob(&drv_ev_state_len); @@ -1617,6 +2104,9 @@ ERTS_CIO_EXPORT(erts_check_io_info)(void *proc) tags[i] = erts_bld_atom(hpp, szp, "max_fds"); values[i++] = erts_bld_uint(hpp, szp, (Uint) pi.max_fds); + tags[i] = erts_bld_atom(hpp, szp, "active_fds"); + values[i++] = erts_bld_uint(hpp, szp, (Uint) active_fds); + #ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS tags[i] = erts_bld_atom(hpp, szp, "no_avoided_wakeups"); values[i++] = erts_bld_uint(hpp, szp, (Uint) pi.no_avoided_wakeups); @@ -1671,6 +2161,8 @@ print_events(ErtsPollEvents ev) typedef struct { int used_fds; int num_errors; + int no_driver_select_structs; + int no_driver_event_structs; #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS int internal_fds; ErtsPollEvents *epep; @@ -1693,6 +2185,13 @@ static void doit_erts_check_io_debug(void *vstate, void *vcounters) struct stat stat_buf; #endif + if (state->driver.select) + counters->no_driver_select_structs++; +#if ERTS_CIO_HAVE_DRV_EVENT + if (state->driver.event) + counters->no_driver_event_structs++; +#endif + #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS if (state->events || ep_events) { if (ep_events & ERTS_POLL_EV_NVAL) { @@ -1831,6 +2330,7 @@ static void doit_erts_check_io_debug(void *vstate, void *vcounters) } } } +#if ERTS_CIO_HAVE_DRV_EVENT else if (state->type == ERTS_EV_TYPE_DRV_EV) { Eterm id; erts_printf("driver_event "); @@ -1866,6 +2366,7 @@ static void doit_erts_check_io_debug(void *vstate, void *vcounters) erts_free_port_names(pnp); } } +#endif #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS else if (internal) { erts_printf("internal "); @@ -1905,7 +2406,7 @@ static void doit_erts_check_io_debug(void *vstate, void *vcounters) } int -ERTS_CIO_EXPORT(erts_check_io_debug)(void) +ERTS_CIO_EXPORT(erts_check_io_debug)(ErtsCheckIoDebugInfo *ciodip) { #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS int fd, len; @@ -1915,6 +2416,10 @@ ERTS_CIO_EXPORT(erts_check_io_debug)(void) ErtsDrvEventState null_des; null_des.driver.select = NULL; +#if ERTS_CIO_HAVE_DRV_EVENT + null_des.driver.event = NULL; +#endif + null_des.driver.drv_ptr = NULL; null_des.events = 0; null_des.remove_cnt = 0; null_des.type = ERTS_EV_TYPE_NONE; @@ -1935,6 +2440,8 @@ ERTS_CIO_EXPORT(erts_check_io_debug)(void) #endif counters.used_fds = 0; counters.num_errors = 0; + counters.no_driver_select_structs = 0; + counters.no_driver_event_structs = 0; #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS len = erts_smp_atomic_read_nob(&drv_ev_state_len); @@ -1951,8 +2458,16 @@ ERTS_CIO_EXPORT(erts_check_io_debug)(void) erts_smp_thr_progress_unblock(); + ciodip->no_used_fds = counters.used_fds; + ciodip->no_driver_select_structs = counters.no_driver_select_structs; + ciodip->no_driver_event_structs = counters.no_driver_event_structs; + erts_printf("\n"); erts_printf("used fds=%d\n", counters.used_fds); + erts_printf("Number of driver_select() structures=%d\n", counters.no_driver_select_structs); +#if ERTS_CIO_HAVE_DRV_EVENT + erts_printf("Number of driver_event() structures=%d\n", counters.no_driver_event_structs); +#endif #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS erts_printf("internal fds=%d\n", counters.internal_fds); #endif @@ -1961,6 +2476,7 @@ ERTS_CIO_EXPORT(erts_check_io_debug)(void) #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS erts_free(ERTS_ALC_T_TMP, (void *) counters.epep); #endif + return counters.num_errors; } diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h index edab7947ba..d01297d55c 100644 --- a/erts/emulator/sys/common/erl_check_io.h +++ b/erts/emulator/sys/common/erl_check_io.h @@ -26,6 +26,7 @@ #ifndef ERL_CHECK_IO_H__ #define ERL_CHECK_IO_H__ +#include "sys.h" #include "erl_sys_driver.h" #ifdef ERTS_ENABLE_KERNEL_POLL @@ -52,8 +53,8 @@ void erts_check_io_kp(int); void erts_check_io_nkp(int); void erts_init_check_io_kp(void); void erts_init_check_io_nkp(void); -int erts_check_io_debug_kp(void); -int erts_check_io_debug_nkp(void); +int erts_check_io_debug_kp(ErtsCheckIoDebugInfo *); +int erts_check_io_debug_nkp(ErtsCheckIoDebugInfo *); #else /* !ERTS_ENABLE_KERNEL_POLL */ @@ -70,6 +71,27 @@ void erts_init_check_io(void); #endif +extern erts_smp_atomic_t erts_check_io_time; + +typedef struct { + ErtsPortTaskHandle task; + erts_smp_atomic_t executed_time; +} ErtsIoTask; + +ERTS_GLB_INLINE void erts_io_notify_port_task_executed(ErtsPortTaskHandle *pthp); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +ERTS_GLB_INLINE void +erts_io_notify_port_task_executed(ErtsPortTaskHandle *pthp) +{ + ErtsIoTask *itp = (ErtsIoTask *) (((char *) pthp) - offsetof(ErtsIoTask, task)); + erts_aint_t ci_time = erts_smp_atomic_read_acqb(&erts_check_io_time); + erts_smp_atomic_set_relb(&itp->executed_time, ci_time); +} + +#endif + #endif /* ERL_CHECK_IO_H__ */ #if !defined(ERL_CHECK_IO_C__) && !defined(ERTS_ALLOC_C__) @@ -81,6 +103,16 @@ void erts_init_check_io(void); #include "erl_poll.h" #include "erl_port_task.h" +#ifdef __WIN32__ +/* + * Current erts_poll implementation for Windows cannot handle + * active events in the set of events polled. + */ +# define ERTS_CIO_DEFER_ACTIVE_EVENTS 1 +#else +# define ERTS_CIO_DEFER_ACTIVE_EVENTS 0 +#endif + /* * ErtsDrvEventDataState is used by driver_event() which is almost never * used. We allocate ErtsDrvEventDataState separate since we dont wan't @@ -91,13 +123,16 @@ typedef struct { Eterm port; ErlDrvEventData data; ErtsPollEvents removed_events; - ErtsPortTaskHandle task; +#if ERTS_CIO_DEFER_ACTIVE_EVENTS + ErtsPollEvents deferred_events; +#endif + ErtsIoTask iotask; } ErtsDrvEventDataState; typedef struct { Eterm inport; Eterm outport; - ErtsPortTaskHandle intask; - ErtsPortTaskHandle outtask; + ErtsIoTask iniotask; + ErtsIoTask outiotask; } ErtsDrvSelectDataState; #endif /* #ifndef ERL_CHECK_IO_INTERNAL__ */ diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c index e3ba741058..e63f0bda54 100644 --- a/erts/emulator/sys/common/erl_sys_common_misc.c +++ b/erts/emulator/sys/common/erl_sys_common_misc.c @@ -44,6 +44,14 @@ #endif #endif +/* + * erts_check_io_time is used by the erl_check_io implementation. The + * global erts_check_io_time variable is declared here since there + * (often) exist two versions of erl_check_io (kernel-poll and + * non-kernel-poll), and we dont want two versions of this variable. + */ +erts_smp_atomic_t erts_check_io_time; + /* Written once and only once */ static int filename_encoding = ERL_FILENAME_UNKNOWN; diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 94eb6b1547..5ad92dad02 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -101,7 +101,9 @@ main(int argc, char *argv[]) if (sscanf(argv[CS_ARGV_FD_CR_IX], "%d:%d", &from, &to) != 2) return 1; -#if defined(__ANDROID__) +#if defined(HAVE_CLOSEFROM) + closefrom(from); +#elif defined(__ANDROID__) for (i = from; i <= to; i++) { if (i!=__system_properties_fd) (void) close(i); @@ -109,13 +111,6 @@ main(int argc, char *argv[]) #else for (i = from; i <= to; i++) (void) close(i); -#endif /* __ANDROID__ */ - -#if defined(HAVE_CLOSEFROM) - closefrom(from); -#else - for (i = from; i <= to; i++) - (void) close(i); #endif if (!(argv[CS_ARGV_WD_IX][0] == '.' && argv[CS_ARGV_WD_IX][1] == '\0') @@ -147,8 +142,6 @@ main(int argc, char *argv[]) return 1; } - - #if defined(__ANDROID__) int __system_properties_fd(void) { diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h index 176fc049a7..26ed2fb558 100644 --- a/erts/emulator/sys/unix/erl_unix_sys.h +++ b/erts/emulator/sys/unix/erl_unix_sys.h @@ -135,9 +135,6 @@ /* File descriptors are numbers anc consecutively allocated on Unix */ #define ERTS_SYS_CONTINOUS_FD_NUMBERS -#define HAVE_ERTS_CHECK_IO_DEBUG -int erts_check_io_debug(void); - #ifndef ERTS_SMP # undef ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT # define ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT @@ -230,8 +227,24 @@ extern void sys_stop_cat(void); */ #ifdef USE_ISINF_ISNAN /* simulate finite() */ -# define finite(f) (!isinf(f) && !isnan(f)) -# define HAVE_FINITE +# define isfinite(f) (!isinf(f) && !isnan(f)) +# define HAVE_ISFINITE +#elif (defined(__GNUC__) && !defined(__llvm__)) && defined(HAVE_FINITE) +/* We use finite in gcc as it emits assembler instead of + the function call that isfinite emits. The assembler is + significantly faster. */ +# ifdef isfinite +# undef isfinite +# endif +# define isfinite finite +# ifndef HAVE_ISFINITE +# define HAVE_ISFINITE +# endif +#elif defined(isfinite) && !defined(HAVE_ISFINITE) +# define HAVE_ISFINITE +#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE) +# define isfinite finite +# define HAVE_ISFINITE #endif #ifdef NO_FPE_SIGNALS @@ -241,7 +254,7 @@ extern void sys_stop_cat(void); #define erts_thread_init_fp_exception() do{}while(0) #endif # define __ERTS_FP_CHECK_INIT(fpexnp) do {} while (0) -# define __ERTS_FP_ERROR(fpexnp, f, Action) if (!finite(f)) { Action; } else {} +# define __ERTS_FP_ERROR(fpexnp, f, Action) if (!isfinite(f)) { Action; } else {} # define __ERTS_FP_ERROR_THOROUGH(fpexnp, f, Action) __ERTS_FP_ERROR(fpexnp, f, Action) # define __ERTS_SAVE_FP_EXCEPTION(fpexnp) # define __ERTS_RESTORE_FP_EXCEPTION(fpexnp) @@ -305,7 +318,7 @@ static __inline__ void __ERTS_FP_CHECK_INIT(volatile unsigned long *fp_exception code to always throw floating-point exceptions on errors. */ static __inline__ int erts_check_fpe_thorough(volatile unsigned long *fp_exception, double f) { - return erts_check_fpe(fp_exception, f) || !finite(f); + return erts_check_fpe(fp_exception, f) || !isfinite(f); } # define __ERTS_FP_ERROR_THOROUGH(fpexnp, f, Action) \ do { if (erts_check_fpe_thorough((fpexnp),(f))) { Action; } } while (0) diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index c3d7440409..cd87b320e2 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -202,8 +202,6 @@ static erts_smp_atomic_t sys_misc_mem_sz; #if defined(ERTS_SMP) static void smp_sig_notify(char c); static int sig_notify_fds[2] = {-1, -1}; -#elif defined(USE_THREADS) -static int async_fd[2]; #endif #if CHLDWTHR || defined(ERTS_SMP) @@ -246,6 +244,8 @@ static void note_child_death(int, int); static void* child_waiter(void *); #endif +static int crashdump_companion_cube_fd = -1; + /********************* General functions ****************************/ /* This is used by both the drivers and general I/O, must be set early */ @@ -284,7 +284,7 @@ struct { void (*check_io)(int); Uint (*size)(void); Eterm (*info)(void *); - int (*check_io_debug)(void); + int (*check_io_debug)(ErtsCheckIoDebugInfo *); } io_func = {0}; @@ -306,9 +306,9 @@ Eterm erts_check_io_info(void *p) } int -erts_check_io_debug(void) +erts_check_io_debug(ErtsCheckIoDebugInfo *ip) { - return (*io_func.check_io_debug)(); + return (*io_func.check_io_debug)(ip); } @@ -575,6 +575,14 @@ erts_sys_pre_init(void) close(fd); } + /* We need a file descriptor to close in the crashdump creation. + * We close this one to be sure we can get a fd for our real file ... + * so, we create one here ... a stone to carry all the way home. + */ + + crashdump_companion_cube_fd = open("/dev/null", O_RDONLY); + + /* don't lose it, there will be cake */ } void @@ -719,14 +727,13 @@ static ERTS_INLINE int prepare_crash_dump(int secs) { #define NUFBUF (3) - int i, max; + int i; char env[21]; /* enough to hold any 64-bit integer */ size_t envsz; DeclareTmpHeapNoproc(heap,NUFBUF); Port *heart_port; Eterm *hp = heap; Eterm list = NIL; - int heart_fd[2] = {-1,-1}; int has_heart = 0; UseTmpHeapNoproc(NUFBUF); @@ -749,43 +756,22 @@ prepare_crash_dump(int secs) alarm((unsigned int)secs); } - if (heart_port) { - /* hearts input fd - * We "know" drv_data is the in_fd since the port is started with read|write - */ - heart_fd[0] = (int)heart_port->drv_data; - heart_fd[1] = (int)driver_data[heart_fd[0]].ofd; - has_heart = 1; + /* close all viable sockets via emergency close callbacks. + * Specifically we want to close epmd sockets. + */ - list = CONS(hp, make_small(8), list); hp += 2; + erts_emergency_close_ports(); + if (heart_port) { + has_heart = 1; + list = CONS(hp, make_small(8), list); hp += 2; /* send to heart port, CMD = 8, i.e. prepare crash dump =o */ erts_port_output(NULL, ERTS_PORT_SIG_FLG_FORCE_IMM_CALL, heart_port, heart_port->common.id, list, NULL); } - /* Make sure we unregister at epmd (unknown fd) and get at least - one free filedescriptor (for erl_crash.dump) */ - - max = max_files; - if (max < 1024) - max = 1024; - for (i = 3; i < max; i++) { -#if defined(ERTS_SMP) - /* We don't want to close the signal notification pipe... */ - if (i == sig_notify_fds[0] || i == sig_notify_fds[1]) - continue; -#elif defined(USE_THREADS) - /* We don't want to close the async notification pipe... */ - if (i == async_fd[0] || i == async_fd[1]) - continue; -#endif - /* We don't want to close our heart yet ... */ - if (i == heart_fd[0] || i == heart_fd[1]) - continue; - - close(i); - } + /* Make sure we have a fd for our crashdump file. */ + close(crashdump_companion_cube_fd); envsz = sizeof(env); i = erts_sys_getenv__("ERL_CRASH_DUMP_NICE", env, &envsz); @@ -1574,9 +1560,13 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op goto child_error; } +#if defined(HAVE_CLOSEFROM) + closefrom(opts->use_stdio ? 3 : 5); +#else for (i = opts->use_stdio ? 3 : 5; i < max_files; i++) (void) close(i); - +#endif + if (opts->wd && chdir(opts->wd) < 0) goto child_error; diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c index 7a1d129cd5..972170d465 100644 --- a/erts/emulator/sys/win32/erl_poll.c +++ b/erts/emulator/sys/win32/erl_poll.c @@ -1085,7 +1085,7 @@ void erts_poll_controlv(ErtsPollSet ps, pcev[i].events, pcev[i].on); } - ERTS_POLLSET_LOCK(ps); + ERTS_POLLSET_UNLOCK(ps); HARDTRACEF(("Out erts_poll_controlv")); } diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h index a78dbf64af..838f0c61eb 100644 --- a/erts/emulator/sys/win32/erl_win_sys.h +++ b/erts/emulator/sys/win32/erl_win_sys.h @@ -113,12 +113,10 @@ /* * Our own type of "FD's" */ +#define ERTS_SYS_FD_INVALID INVALID_HANDLE_VALUE #define ERTS_SYS_FD_TYPE HANDLE #define NO_FSTAT_ON_SYS_FD_TYPE 1 /* They are events, not files */ -#define HAVE_ERTS_CHECK_IO_DEBUG -int erts_check_io_debug(void); - /* * For erl_time_sup */ diff --git a/erts/emulator/test/a_SUITE.erl b/erts/emulator/test/a_SUITE.erl index 195c9c0a5f..17579be416 100644 --- a/erts/emulator/test/a_SUITE.erl +++ b/erts/emulator/test/a_SUITE.erl @@ -97,23 +97,13 @@ display_check_io(ChkIo) -> catch erlang:display('--- CHECK IO INFO ---'), catch erlang:display(ChkIo), catch erts_debug:set_internal_state(available_internal_state, true), - NoOfErrorFds = (catch erts_debug:get_internal_state(check_io_debug)), + NoOfErrorFds = (catch element(1, erts_debug:get_internal_state(check_io_debug))), catch erlang:display({'NoOfErrorFds', NoOfErrorFds}), catch erts_debug:set_internal_state(available_internal_state, false), catch erlang:display('--- CHECK IO INFO ---'), ok. get_check_io_info() -> - ChkIo = erlang:system_info(check_io), - case lists:keysearch(pending_updates, 1, ChkIo) of - {value, {pending_updates, 0}} -> - display_check_io(ChkIo), - ChkIo; - false -> - ChkIo; - _ -> - receive after 10 -> ok end, - get_check_io_info() - end. + z_SUITE:get_check_io_info(). diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index 336b6188f6..623d62f876 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -31,8 +31,9 @@ end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2, + + a_test/1, outputv_echo/1, - timer_measure/1, timer_cancel/1, timer_change/1, @@ -79,7 +80,8 @@ thr_free_drv/1, async_blast/1, thr_msg_blast/1, - consume_timeslice/1]). + consume_timeslice/1, + z_test/1]). -export([bin_prefix/2]). @@ -122,19 +124,19 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> _ -> erts_debug:set_internal_state(available_internal_state, true) end, erlang:display({init_per_testcase, Case}), - ?line 0 = erts_debug:get_internal_state(check_io_debug), + ?line 0 = element(1, erts_debug:get_internal_state(check_io_debug)), [{watchdog, Dog},{testcase, Case}|Config]. end_per_testcase(Case, Config) -> Dog = ?config(watchdog, Config), erlang:display({end_per_testcase, Case}), - ?line 0 = erts_debug:get_internal_state(check_io_debug), + ?line 0 = element(1, erts_debug:get_internal_state(check_io_debug)), ?t:timetrap_cancel(Dog). suite() -> [{ct_hooks,[ts_install_cth]}]. -all() -> - [outputv_errors, outputv_echo, queue_echo, {group, timer}, +all() -> %% Keep a_test first and z_test last... + [a_test, outputv_errors, outputv_echo, queue_echo, {group, timer}, driver_unloaded, io_ready_exit, use_fallback_pollset, bad_fd_in_pollset, driver_event, fd_change, steal_control, otp_6602, driver_system_info_base_ver, @@ -151,7 +153,8 @@ all() -> thr_free_drv, async_blast, thr_msg_blast, - consume_timeslice]. + consume_timeslice, + z_test]. groups() -> [{timer, [], @@ -917,8 +920,7 @@ steal_control_test(Hndl = {erts_poll_info, Before}) -> end. chkio_test_init(Config) when is_list(Config) -> - ?line wait_until_no_pending_updates(), - ?line ChkIo = erlang:system_info(check_io), + ?line ChkIo = get_stable_check_io_info(), ?line case catch lists:keysearch(name, 1, ChkIo) of {value, {name, erts_poll}} -> ?line ?t:format("Before test: ~p~n", [ChkIo]), @@ -937,8 +939,7 @@ chkio_test_fini({skipped, _} = Res) -> chkio_test_fini({chkio_test_result, Res, Before}) -> ?line ok = erl_ddll:unload_driver('chkio_drv'), ?line ok = erl_ddll:stop(), - ?line wait_until_no_pending_updates(), - ?line After = erlang:system_info(check_io), + ?line After = get_stable_check_io_info(), ?line ?t:format("After test: ~p~n", [After]), ?line verify_chkio_state(Before, After), ?line Res. @@ -985,7 +986,7 @@ chkio_test({erts_poll_info, Before}, ?line Fun(), ?line During = erlang:system_info(check_io), ?line erlang:display(During), - ?line 0 = erts_debug:get_internal_state(check_io_debug), + ?line 0 = element(1, erts_debug:get_internal_state(check_io_debug)), ?line ?t:format("During test: ~p~n", [During]), ?line chk_chkio_port(Port), ?line case erlang:port_control(Port, ?CHKIO_STOP, "") of @@ -1034,18 +1035,22 @@ verify_chkio_state(Before, After) -> After) end, ?line ok. - - -wait_until_no_pending_updates() -> - case lists:keysearch(pending_updates, 1, erlang:system_info(check_io)) of - {value, {pending_updates, 0}} -> - ok; - false -> - ok; +get_stable_check_io_info() -> + ChkIo = erlang:system_info(check_io), + PendUpdNo = case lists:keysearch(pending_updates, 1, ChkIo) of + {value, {pending_updates, PendNo}} -> + PendNo; + false -> + 0 + end, + {value, {active_fds, ActFds}} = lists:keysearch(active_fds, 1, ChkIo), + case {PendUpdNo, ActFds} of + {0, 0} -> + ChkIo; _ -> receive after 10 -> ok end, - wait_until_no_pending_updates() + get_stable_check_io_info() end. otp_6602(doc) -> ["Missed port lock when stealing control of fd from a " @@ -1199,8 +1204,8 @@ check_si_res(["sched_thrs", Value]) -> ?line Value = integer_to_list(erlang:system_info(schedulers)); %% Data added in 3rd version of driver_system_info() (driver version 1.5) -check_si_res(["emu_nif_vsn", _Value]) -> - true; +check_si_res(["emu_nif_vsn", Value]) -> + ?line Value = erlang:system_info(nif_version); %% Data added in 4th version of driver_system_info() (driver version 3.1) check_si_res(["dirty_sched", _Value]) -> @@ -2387,10 +2392,25 @@ count_proc_sched(Ps, PNs) -> PNs end. +a_test(Config) when is_list(Config) -> + check_io_debug(). + +z_test(Config) when is_list(Config) -> + check_io_debug(). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Utilities %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +check_io_debug() -> + get_stable_check_io_info(), + {NoErrorFds, NoUsedFds, NoDrvSelStructs, NoDrvEvStructs} + = erts_debug:get_internal_state(check_io_debug), + 0 = NoErrorFds, + NoUsedFds = NoDrvSelStructs, + 0 = NoDrvEvStructs, + ok. + %flush_msgs() -> % receive % M -> diff --git a/erts/emulator/test/float_SUITE_data/fp_drv.c b/erts/emulator/test/float_SUITE_data/fp_drv.c index b80385c3f9..82d18d6440 100644 --- a/erts/emulator/test/float_SUITE_data/fp_drv.c +++ b/erts/emulator/test/float_SUITE_data/fp_drv.c @@ -29,9 +29,14 @@ #if defined (__GNUC__) int _finite(double x); #endif -#ifndef finite -#define finite _finite +#ifndef isfinite +#define isfinite _finite #endif +#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE) +/* If not windows and we do not have isfinite */ +#define isfinite finite +#elif !defined(HAVE_ISFINITE) +# error "No finite function found!" #endif #include "erl_driver.h" @@ -79,21 +84,21 @@ do_test(void *unused) x = 3.23e133; y = 3.57e257; z = x*y; - if (finite(z)) + if (isfinite(z)) return "is finite (1)"; x = 5.0; y = 0.0; z = x/y; - if (finite(z)) + if (isfinite(z)) return "is finite (2)"; z = log(-1.0); - if (finite(z)) + if (isfinite(z)) return "is finite (3)"; z = log(0.0); - if (finite(z)) + if (isfinite(z)) return "is finite (4)"; return "ok"; diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 14e6585220..4560077a51 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -1564,6 +1564,8 @@ dirty_nif(Config) when is_list(Config) -> Val2 = "Erlang", Val3 = list_to_binary([Val2, 0]), {Val1, Val2, Val3} = call_dirty_nif(Val1, Val2, Val3), + LargeArray = lists:duplicate(1000, ok), + LargeArray = call_dirty_nif_zero_args(), ok catch error:badarg -> @@ -1740,6 +1742,7 @@ call_nif_schedule(_,_) -> ?nif_stub. call_dirty_nif(_,_,_) -> ?nif_stub. send_from_dirty_nif(_) -> ?nif_stub. call_dirty_nif_exception() -> ?nif_stub. +call_dirty_nif_zero_args() -> ?nif_stub. %% maps is_map_nif(_) -> ?nif_stub. diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 291c903947..85544db2ab 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -1623,6 +1623,18 @@ static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL call_dirty_nif_exception, argc-1, argv); } } + +static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + int i; + ERL_NIF_TERM result[1000]; + ERL_NIF_TERM ok = enif_make_atom(env, "ok"); + assert(argc == 0); + for (i = 0; i < sizeof(result)/sizeof(*result); i++) { + result[i] = ok; + } + return enif_make_list_from_array(env, result, i); +} #endif static ERL_NIF_TERM is_map_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) @@ -1807,6 +1819,7 @@ static ErlNifFunc nif_funcs[] = {"call_dirty_nif", 3, call_dirty_nif}, {"send_from_dirty_nif", 1, send_from_dirty_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"call_dirty_nif_exception", 0, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"call_dirty_nif_zero_args", 0, call_dirty_nif_zero_args, ERL_NIF_DIRTY_JOB_CPU_BOUND}, #endif {"is_map_nif", 1, is_map_nif}, {"get_map_size_nif", 1, get_map_size_nif}, diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 8792f25d76..9083545060 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -2343,8 +2343,10 @@ port_setget_data(Config) when is_list(Config) -> Port = erlang:open_port({spawn_driver, "echo_drv"}, []), NSched = erlang:system_info(schedulers_online), + HeapData = {1,2,3,<<"A heap binary">>,fun()->"This is fun"end, + list_to_binary(lists:seq(1,100))}, PRs = lists:map(fun(I) -> - spawn_opt(fun() -> port_setget_data_hammer(Port,1) end, + spawn_opt(fun() -> port_setget_data_hammer(Port,HeapData,false,1) end, [monitor, {scheduler, I rem NSched}]) end, lists:seq(1,10)), @@ -2362,13 +2364,17 @@ port_setget_data(Config) when is_list(Config) -> PRs), ok. -port_setget_data_hammer(Port, N) -> +port_setget_data_hammer(Port, HeapData, IsSet0, N) -> Rand = random:uniform(3), - try case Rand of - 1 -> true = erlang:port_set_data(Port, atom); - 2 -> true = erlang:port_set_data(Port, {1,2,3}); - 3 -> erlang:port_get_data(Port) - end + IsSet1 = try case Rand of + 1 -> true = erlang:port_set_data(Port, atom), true; + 2 -> true = erlang:port_set_data(Port, HeapData), true; + 3 -> case erlang:port_get_data(Port) of + atom -> true; + HeapData -> true; + undefined -> false=IsSet0 + end + end catch error:badarg -> true = get(prepare_for_close), @@ -2381,7 +2387,7 @@ port_setget_data_hammer(Port, N) -> after 0 -> ok end, - port_setget_data_hammer(Port, N+1). + port_setget_data_hammer(Port, HeapData, IsSet1, N+1). wait_until(Fun) -> diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl index 4b3075a164..b0c6224dfe 100644 --- a/erts/emulator/test/z_SUITE.erl +++ b/erts/emulator/test/z_SUITE.erl @@ -38,7 +38,7 @@ -export([schedulers_alive/1, node_container_refc_check/1, long_timers/1, pollset_size/1, - check_io_debug/1]). + check_io_debug/1, get_check_io_info/0]). -define(DEFAULT_TIMEOUT, ?t:minutes(5)). @@ -288,11 +288,14 @@ check_io_debug(Config) when is_list(Config) -> end. check_io_debug_test() -> + ?line erlang:display(get_check_io_info()), ?line erts_debug:set_internal_state(available_internal_state, true), - ?line erlang:display(erlang:system_info(check_io)), - ?line NoOfErrorFds = erts_debug:get_internal_state(check_io_debug), + ?line {NoErrorFds, NoUsedFds, NoDrvSelStructs, NoDrvEvStructs} + = erts_debug:get_internal_state(check_io_debug), ?line erts_debug:set_internal_state(available_internal_state, false), - ?line 0 = NoOfErrorFds, + ?line 0 = NoErrorFds, + ?line NoUsedFds = NoDrvSelStructs, + ?line 0 = NoDrvEvStructs, ?line ok. @@ -305,7 +308,7 @@ display_check_io(ChkIo) -> catch erlang:display('--- CHECK IO INFO ---'), catch erlang:display(ChkIo), catch erts_debug:set_internal_state(available_internal_state, true), - NoOfErrorFds = (catch erts_debug:get_internal_state(check_io_debug)), + NoOfErrorFds = (catch element(1, erts_debug:get_internal_state(check_io_debug))), catch erlang:display({'NoOfErrorFds', NoOfErrorFds}), catch erts_debug:set_internal_state(available_internal_state, false), catch erlang:display('--- CHECK IO INFO ---'), @@ -313,14 +316,19 @@ display_check_io(ChkIo) -> get_check_io_info() -> ChkIo = erlang:system_info(check_io), - case lists:keysearch(pending_updates, 1, ChkIo) of - {value, {pending_updates, 0}} -> + PendUpdNo = case lists:keysearch(pending_updates, 1, ChkIo) of + {value, {pending_updates, PendNo}} -> + PendNo; + false -> + 0 + end, + {value, {active_fds, ActFds}} = lists:keysearch(active_fds, 1, ChkIo), + case {PendUpdNo, ActFds} of + {0, 0} -> display_check_io(ChkIo), ChkIo; - false -> - ChkIo; _ -> - receive after 10 -> ok end, + receive after 100 -> ok end, get_check_io_info() end. diff --git a/erts/emulator/utils/make_compiler_flags b/erts/emulator/utils/make_compiler_flags index cebe8cd0c5..ca1bc47113 100755 --- a/erts/emulator/utils/make_compiler_flags +++ b/erts/emulator/utils/make_compiler_flags @@ -70,7 +70,7 @@ my($prog) = $prog[$#prog]; print "/* Warning: Do not edit this file.\n"; print " Auto-generated by '$prog'.*/\n"; -foreach(keys %constants) { +foreach (sort(keys %constants)) { print "const char* erts_build_flags_$_ = \"$constants{$_}\";\n" } diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c index 9630e0cdf0..9699491526 100644 --- a/erts/epmd/src/epmd.c +++ b/erts/epmd/src/epmd.c @@ -175,9 +175,9 @@ int main(int argc, char** argv) g->nodes.reg = g->nodes.unreg = g->nodes.unreg_tail = NULL; g->nodes.unreg_count = 0; g->active_conn = 0; -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON g->is_systemd = 0; -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ for (i = 0; i < MAX_LISTEN_SOCKETS; i++) g->listenfd[i] = -1; @@ -251,11 +251,11 @@ int main(int argc, char** argv) else usage(g); epmd_cleanup_exit(g,0); -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON } else if (strcmp(argv[0], "-systemd") == 0) { g->is_systemd = 1; argv++; argc--; -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ } else usage(g); } @@ -461,11 +461,11 @@ static void usage(EpmdVars *g) fprintf(stderr, " Forcibly unregisters a name with epmd\n"); fprintf(stderr, " (only allowed if -relaxed_command_check was given when \n"); fprintf(stderr, " epmd was started).\n"); -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON fprintf(stderr, " -systemd\n"); fprintf(stderr, " Wait for socket from systemd. The option makes sense\n"); fprintf(stderr, " when started from .socket unit.\n"); -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ epmd_cleanup_exit(g,1); } @@ -593,9 +593,11 @@ void epmd_cleanup_exit(EpmdVars *g, int exitval) for(i=0; g->argv[i] != NULL; ++i) free(g->argv[i]); free(g->argv); - } - - + } +#ifdef HAVE_SYSTEMD_DAEMON + sd_notifyf(0, "STATUS=Exited.\n" + "ERRNO=%i", exitval); +#endif /* HAVE_SYSTEMD_DAEMON */ exit(exitval); } diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h index c8f2192f7f..52badd7086 100644 --- a/erts/epmd/src/epmd_int.h +++ b/erts/epmd/src/epmd_int.h @@ -125,9 +125,9 @@ # include "sys/select.h" #endif -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON # include <systemd/sd-daemon.h> -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ /* ************************************************************************ */ /* Replace some functions by others by making the function name a macro */ @@ -340,9 +340,9 @@ typedef struct { int listenfd[MAX_LISTEN_SOCKETS]; char *addresses; char **argv; -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON int is_systemd; -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ } EpmdVars; void dbg_printf(EpmdVars*,int,const char*,...); diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index 48fd7a5f9c..26e42adb19 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -244,7 +244,7 @@ void run(EpmdVars *g) } else { -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ dbg_printf(g,2,"try to initiate listening port %d", g->port); @@ -312,7 +312,7 @@ void run(EpmdVars *g) } #ifdef HAVE_SYSTEMD_DAEMON } -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ #if !defined(__WIN32__) && !defined(__OSE__) /* We ignore the SIGPIPE signal that is raised when we call write @@ -330,13 +330,13 @@ void run(EpmdVars *g) FD_ZERO(&g->orig_read_mask); g->select_fd_top = 0; -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON if (g->is_systemd) for (i = 0; i < num_sockets; i++) select_fd_set(g, listensock[i]); else { -#endif +#endif /* HAVE_SYSTEMD_DAEMON */ for (i = 0; i < num_sockets; i++) { if ((listensock[i] = socket(FAMILY,SOCK_STREAM,0)) < 0) @@ -399,9 +399,12 @@ void run(EpmdVars *g) } select_fd_set(g, listensock[i]); } -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON } -#endif + sd_notifyf(0, "READY=1\n" + "STATUS=Processing port mapping requests...\n" + "MAINPID=%lu", (unsigned long) getpid()); +#endif /* HAVE_SYSTEMD_DAEMON */ dbg_tty_printf(g,2,"entering the main select() loop"); diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 709c6f02d1..5ebde8ca3c 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -128,6 +128,7 @@ static char *pluss_val_switches[] = { "bwt", "cl", "ct", + "ecio", "fwi", "tbt", "wct", diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c index 580b6cc3c5..20b78eb05e 100644 --- a/erts/etc/common/run_erl_common.c +++ b/erts/etc/common/run_erl_common.c @@ -36,6 +36,10 @@ # include <syslog.h> #endif +#ifdef HAVE_SYS_IOCTL_H +# include <sys/ioctl.h> +#endif + #ifdef __OSE__ # include "ramlog.h" #endif @@ -637,7 +641,7 @@ int erts_run_erl_open_fifo(char *pipename,char *w_pipename,char *r_pipename) { /* Extract any control sequences that are ment only for run_erl * and should not be forwarded to the pty. */ -int erts_run_erl_extract_ctrl_seq(char* buf, int len) +int erts_run_erl_extract_ctrl_seq(char* buf, int len, int mfd) { static const char prefix[] = "\033_"; static const char suffix[] = "\033\\"; @@ -662,7 +666,7 @@ int erts_run_erl_extract_ctrl_seq(char* buf, int len) struct winsize ws; ws.ws_col = col; ws.ws_row = row; - if (ioctl(MFD, TIOCSWINSZ, &ws) < 0) { + if (ioctl(mfd, TIOCSWINSZ, &ws) < 0) { ERRNO_ERR0(LOG_ERR,"Failed to set window size"); } #endif diff --git a/erts/etc/common/run_erl_common.h b/erts/etc/common/run_erl_common.h index c47a0db054..14207ee4de 100644 --- a/erts/etc/common/run_erl_common.h +++ b/erts/etc/common/run_erl_common.h @@ -40,7 +40,7 @@ void erts_run_erl_log_error(int priority, int line, const char *format,...); int erts_run_erl_open_fifo(char *pipename,char *w_pipename,char *r_pipename); int erts_run_erl_log_alive_minutes(void); -int erts_run_erl_extract_ctrl_seq(char* buf, int len); +int erts_run_erl_extract_ctrl_seq(char* buf, int len, int mfd); /* File operations */ ssize_t sf_read(int fd, void *buffer, size_t len); diff --git a/erts/etc/ose/run_erl.c b/erts/etc/ose/run_erl.c index 6bb59b7f7e..8bc49a485e 100644 --- a/erts/etc/ose/run_erl.c +++ b/erts/etc/ose/run_erl.c @@ -495,7 +495,7 @@ int pass_on(ProgramState *s) { #ifdef DEBUG erts_run_erl_log_status("Pty master write; "); #endif - len = erts_run_erl_extract_ctrl_seq(buffer,len); + len = erts_run_erl_extract_ctrl_seq(buffer,len, s->ofd); if (len > 0) { int wlen = erts_run_erl_write_all(s->ofd, buffer, len); diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index e22771c582..141d51824f 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1130,6 +1130,39 @@ document etp-cp %--------------------------------------------------------------------------- end +define etp-check-beam-ranges + set $etp_ci = 0 + while $etp_ci < 3 + printf "Checking code index %i...\n", $etp_ci + set $etp_j = 0 + while $etp_j < r[$etp_ci].n + set $etp_p = &r[$etp_ci].modules[$etp_j] + if $etp_j > 0 && $etp_p->start < (Range*)$etp_p[-1].end.counter + printf "r[%i].modules[%i]: ERROR start < previous\n", $etp_ci, $etp_j + end + if $etp_p->start > (Range*)$etp_p->end.counter + printf "r[%i].modules[%i]: ERROR start > end\n", $etp_ci, $etp_j + else + if $etp_p->start == (Range*)$etp_p->end.counter + printf "r[%i].modules[%i]: Purged\n", $etp_ci, $etp_j + end + end + set $etp_j = $etp_j + 1 + end + set $etp_ci = $etp_ci + 1 + end +end + +document etp-check-beam-ranges +%--------------------------------------------------------------------------- +% etp-check-beam-ranges +% +% Do consistency check of beam_ranges data structure +% and print errors and empty slots from purged modules. +%--------------------------------------------------------------------------- +end + + ############################################################################ # Commands for special term bunches. # @@ -2401,7 +2434,7 @@ define etp-system-info printf "ERTS version: %s\n", etp_erts_version printf "Compile date: %s\n", etp_compile_date printf "Arch: %s\n", etp_arch - printf "Endianess: " + printf "Endianness: " if (etp_big_endian) printf "Big\n" else diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index 4b123b8911..049e83f9e4 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -490,7 +490,7 @@ static void pass_on(pid_t childpid) #ifdef DEBUG erts_run_erl_log_status("Pty master write; "); #endif - len = erts_run_erl_extract_ctrl_seq(buf, len); + len = erts_run_erl_extract_ctrl_seq(buf, len, mfd); if(len==1 && buf[0] == '\003') { kill(childpid,SIGINT); diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h index 72c054b588..ad5d05704c 100644 --- a/erts/include/internal/ethread.h +++ b/erts/include/internal/ethread.h @@ -364,8 +364,8 @@ extern ethr_runtime_t ethr_runtime__; # include "sparc64/ethread.h" # endif # endif -# include "gcc/ethread.h" # include "libatomic_ops/ethread.h" +# include "gcc/ethread.h" # endif # elif defined(ETHR_HAVE_LIBATOMIC_OPS) # include "libatomic_ops/ethread.h" diff --git a/erts/include/internal/libatomic_ops/ethr_atomic.h b/erts/include/internal/libatomic_ops/ethr_atomic.h index fb1288c330..734cdf0890 100644 --- a/erts/include/internal/libatomic_ops/ethr_atomic.h +++ b/erts/include/internal/libatomic_ops/ethr_atomic.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2010-2011. All Rights Reserved. + * Copyright Ericsson AB 2010-2014. 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 @@ -32,22 +32,23 @@ * These operations need to be defined by libatomic_ops; * otherwise, we won't compile: * - AO_nop_full() - * - AO_load() - * - AO_store() - * - AO_compare_and_swap() + * - AO_load() || AO_load_aquire() + * - AO_store() || AO_store_release() + * - AO_compare_and_swap() || AO_compare_and_swap_acquire() + * || AO_compare_and_swap_release() || AO_compare_and_swap_full() * */ #if ETHR_SIZEOF_AO_T == 4 #define ETHR_HAVE_NATIVE_ATOMIC32 1 -#define ETHR_NATIVE_ATOMIC32_IMPL "libatomic_ops" +#define ETHR_NATIVE_ATOMIC32_IMPL ETHR_NATIVE_IMPL__ #define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X #define ETHR_ATMC_T__ ethr_native_atomic32_t #define ETHR_AINT_T__ ethr_sint32_t #define ETHR_AINT_SUFFIX__ "l" #elif ETHR_SIZEOF_AO_T == 8 #define ETHR_HAVE_NATIVE_ATOMIC64 1 -#define ETHR_NATIVE_ATOMIC64_IMPL "libatomic_ops" +#define ETHR_NATIVE_ATOMIC64_IMPL ETHR_NATIVE_IMPL__ #define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X #define ETHR_ATMC_T__ ethr_native_atomic64_t #define ETHR_AINT_T__ ethr_sint64_t @@ -74,6 +75,8 @@ ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var) return (ETHR_AINT_T__ *) &var->counter; } +#ifdef AO_HAVE_store + #if ETHR_SIZEOF_AO_T == 4 # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1 #else @@ -86,6 +89,24 @@ ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value) AO_store(&var->counter, (AO_t) value); } +#endif + +#ifdef AO_HAVE_store_write + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_WB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_WB 1 +#endif + +static ETHR_INLINE void +ETHR_NATMC_FUNC__(set_wb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value) +{ + AO_store_write(&var->counter, (AO_t) value); +} + +#endif + #ifdef AO_HAVE_store_release #if ETHR_SIZEOF_AO_T == 4 @@ -102,6 +123,24 @@ ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value) #endif +#ifdef AO_HAVE_store_full + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_MB 1 +#endif + +static ETHR_INLINE void +ETHR_NATMC_FUNC__(set_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value) +{ + AO_store_full(&var->counter, (AO_t) value); +} + +#endif + +#ifdef AO_HAVE_load + #if ETHR_SIZEOF_AO_T == 4 # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1 #else @@ -114,6 +153,24 @@ ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var) return (ETHR_AINT_T__) AO_load(&var->counter); } +#endif + +#ifdef AO_HAVE_load_read + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_RB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_RB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(read_rb)(ETHR_ATMC_T__ *var) +{ + return (ETHR_AINT_T__) AO_load_read(&var->counter); +} + +#endif + #ifdef AO_HAVE_load_acquire #if ETHR_SIZEOF_AO_T == 4 @@ -130,6 +187,22 @@ ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var) #endif +#ifdef AO_HAVE_load_full + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_MB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(read_mb)(ETHR_ATMC_T__ *var) +{ + return (ETHR_AINT_T__) AO_load_full(&var->counter); +} + +#endif + #ifdef AO_HAVE_fetch_and_add #if ETHR_SIZEOF_AO_T == 4 @@ -146,6 +219,54 @@ ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr) #endif +#ifdef AO_HAVE_fetch_and_add_acquire + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_ACQB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_ACQB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(add_return_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr) +{ + return ((ETHR_AINT_T__) AO_fetch_and_add_acquire(&var->counter, (AO_t) incr)) + incr; +} + +#endif + +#ifdef AO_HAVE_fetch_and_add_release + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_RELB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_RELB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(add_return_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr) +{ + return ((ETHR_AINT_T__) AO_fetch_and_add_release(&var->counter, (AO_t) incr)) + incr; +} + +#endif + +#ifdef AO_HAVE_fetch_and_add_full + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_MB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(add_return_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr) +{ + return ((ETHR_AINT_T__) AO_fetch_and_add_full(&var->counter, (AO_t) incr)) + incr; +} + +#endif + #ifdef AO_HAVE_fetch_and_add1 #if ETHR_SIZEOF_AO_T == 4 @@ -178,6 +299,38 @@ ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var) #endif +#ifdef AO_HAVE_fetch_and_add1_release + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_INC_RETURN_RELB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_INC_RETURN_RELB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(inc_return_relb)(ETHR_ATMC_T__ *var) +{ + return ((ETHR_AINT_T__) AO_fetch_and_add1_release(&var->counter)) + 1; +} + +#endif + +#ifdef AO_HAVE_fetch_and_add1_full + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_INC_RETURN_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_INC_RETURN_MB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(inc_return_mb)(ETHR_ATMC_T__ *var) +{ + return ((ETHR_AINT_T__) AO_fetch_and_add1_full(&var->counter)) + 1; +} + +#endif + #ifdef AO_HAVE_fetch_and_sub1 #if ETHR_SIZEOF_AO_T == 4 @@ -194,6 +347,22 @@ ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var) #endif +#ifdef AO_HAVE_fetch_and_sub1_acquire + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_DEC_RETURN_ACQB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_DEC_RETURN_ACQB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(dec_return_acqb)(ETHR_ATMC_T__ *var) +{ + return ((ETHR_AINT_T__) AO_fetch_and_sub1_acquire(&var->counter)) - 1; +} + +#endif + #ifdef AO_HAVE_fetch_and_sub1_release #if ETHR_SIZEOF_AO_T == 4 @@ -210,7 +379,60 @@ ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var) #endif -#ifdef AO_HAVE_compare_and_swap +#ifdef AO_HAVE_fetch_and_sub1_full + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_DEC_RETURN_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_DEC_RETURN_MB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(dec_return_mb)(ETHR_ATMC_T__ *var) +{ + return ((ETHR_AINT_T__) AO_fetch_and_sub1_full(&var->counter)) - 1; +} + +#endif + +#if defined(AO_HAVE_compare_and_swap_full) || defined(AO_HAVE_fetch_compare_and_swap_full) + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_MB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_MB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(cmpxchg_mb)(ETHR_ATMC_T__ *var, + ETHR_AINT_T__ new, + ETHR_AINT_T__ exp) +{ +#if defined(AO_HAVE_fetch_compare_and_swap_full) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap_full(&var->counter, + (AO_t) exp, + (AO_t) new); +#else + ETHR_AINT_T__ act; + do { + if (AO_compare_and_swap_full(&var->counter, (AO_t) exp, (AO_t) new)) + return exp; +#ifdef AO_HAVE_load_acquire + act = (ETHR_AINT_T__) AO_load_acquire(&var->counter); +#else + act = (ETHR_AINT_T__) AO_load(&var->counter); +#endif + } while (act == exp); +#ifndef AO_HAVE_load_acquire + AO_nop_full(); +#endif + return act; +#endif +} + +#endif + +#if defined(AO_HAVE_compare_and_swap) || defined(AO_HAVE_fetch_compare_and_swap) #if ETHR_SIZEOF_AO_T == 4 # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG 1 @@ -223,18 +445,28 @@ ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ exp) { +#if defined(AO_HAVE_fetch_compare_and_swap) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap(&var->counter, + (AO_t) exp, + (AO_t) new); +#else ETHR_AINT_T__ act; do { if (AO_compare_and_swap(&var->counter, (AO_t) exp, (AO_t) new)) return exp; +#ifdef AO_HAVE_load act = (ETHR_AINT_T__) AO_load(&var->counter); +#else + act = (ETHR_AINT_T__) AO_load_aquire(&var->counter); +#endif } while (act == exp); return act; +#endif } #endif -#ifdef AO_HAVE_compare_and_swap_acquire +#if defined(AO_HAVE_compare_and_swap_acquire) || defined(AO_HAVE_fetch_compare_and_swap_acquire) #if ETHR_SIZEOF_AO_T == 4 # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_ACQB 1 @@ -247,6 +479,11 @@ ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ exp) { +#if defined(AO_HAVE_fetch_compare_and_swap_acquire) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap_acquire(&var->counter, + (AO_t) exp, + (AO_t) new); +#else ETHR_AINT_T__ act; do { if (AO_compare_and_swap_acquire(&var->counter, (AO_t) exp, (AO_t) new)) @@ -261,11 +498,55 @@ ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var, AO_nop_full(); #endif return act; +#endif +} + +#endif + +#if defined(AO_HAVE_compare_and_swap_read) || defined(AO_HAVE_fetch_compare_and_swap_read) + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_RB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_RB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(cmpxchg_rb)(ETHR_ATMC_T__ *var, + ETHR_AINT_T__ new, + ETHR_AINT_T__ exp) +{ +#if defined(AO_HAVE_fetch_compare_and_swap_read) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap_read(&var->counter, + (AO_t) exp, + (AO_t) new); +#else + ETHR_AINT_T__ act; + do { + if (AO_compare_and_swap_read(&var->counter, (AO_t) exp, (AO_t) new)) + return exp; +#if defined(AO_HAVE_load_read) + act = (ETHR_AINT_T__) AO_load_read(&var->counter); +#elif defined(AO_HAVE_load) + act = (ETHR_AINT_T__) AO_load(&var->counter); +#else + act = (ETHR_AINT_T__) AO_load_acquire(&var->counter); +#endif + } while (act == exp); +#ifndef AO_HAVE_load_read +#ifdef AO_HAVE_nop_read + AO_nop_read(); +#else + AO_nop_full(); +#endif +#endif + return act; +#endif } #endif -#ifdef AO_HAVE_compare_and_swap_release +#if defined(AO_HAVE_compare_and_swap_release) || defined(AO_HAVE_fetch_compare_and_swap_release) #if ETHR_SIZEOF_AO_T == 4 # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_RELB 1 @@ -278,13 +559,57 @@ ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ exp) { +#if defined(AO_HAVE_fetch_compare_and_swap_release) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap_release(&var->counter, + (AO_t) exp, + (AO_t) new); +#else ETHR_AINT_T__ act; do { if (AO_compare_and_swap_release(&var->counter, (AO_t) exp, (AO_t) new)) return exp; +#ifdef AO_HAVE_load act = (ETHR_AINT_T__) AO_load(&var->counter); +#else + act = (ETHR_AINT_T__) AO_load_acquire(&var->counter); +#endif + } while (act == exp); + return act; +#endif +} + +#endif + +#if defined(AO_HAVE_compare_and_swap_write) || defined(AO_HAVE_fetch_compare_and_swap_write) + +#if ETHR_SIZEOF_AO_T == 4 +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_WB 1 +#else +# define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_WB 1 +#endif + +static ETHR_INLINE ETHR_AINT_T__ +ETHR_NATMC_FUNC__(cmpxchg_wb)(ETHR_ATMC_T__ *var, + ETHR_AINT_T__ new, + ETHR_AINT_T__ exp) +{ +#if defined(AO_HAVE_fetch_compare_and_swap_write) + return (ETHR_AINT_T__) AO_fetch_compare_and_swap_write(&var->counter, + (AO_t) exp, + (AO_t) new); +#else + ETHR_AINT_T__ act; + do { + if (AO_compare_and_swap_write(&var->counter, (AO_t) exp, (AO_t) new)) + return exp; +#ifdef AO_HAVE_load + act = (ETHR_AINT_T__) AO_load(&var->counter); +#else + act = (ETHR_AINT_T__) AO_load_acquire(&var->counter); +#endif } while (act == exp); return act; +#endif } #endif diff --git a/erts/include/internal/libatomic_ops/ethr_dw_atomic.h b/erts/include/internal/libatomic_ops/ethr_dw_atomic.h new file mode 100644 index 0000000000..4dd9f41e96 --- /dev/null +++ b/erts/include/internal/libatomic_ops/ethr_dw_atomic.h @@ -0,0 +1,567 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. 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% + */ + +/* + * Description: Native double word atomics using libatomic_ops + * Author: Rickard Green + */ + +#ifndef ETHR_LIBATOMIC_OPS_DW_ATOMIC_H__ +#define ETHR_LIBATOMIC_OPS_DW_ATOMIC_H__ + +#if defined(AO_HAVE_double_t) \ + && (defined(AO_HAVE_double_load_acquire) \ + || defined(AO_HAVE_double_load)) \ + && (defined(AO_HAVE_compare_double_and_swap_double) \ + || defined(AO_HAVE_compare_double_and_swap_double_full) \ + || defined(AO_HAVE_compare_double_and_swap_double_acquire) \ + || defined(AO_HAVE_compare_double_and_swap_double_release) \ + || defined(AO_HAVE_double_compare_and_swap) \ + || defined(AO_HAVE_double_compare_and_swap_full) \ + || defined(AO_HAVE_double_compare_and_swap_acquire) \ + || defined(AO_HAVE_double_compare_and_swap_release)) + +#if ETHR_SIZEOF_PTR == 4 +# define ETHR_NATIVE_SU_DW_SINT_T ethr_sint64_t +#elif ETHR_SIZEOF_PTR == 8 && defined(ETHR_HAVE_INT128_T) +# define ETHR_NATIVE_SU_DW_SINT_T ethr_sint128_t +#endif + +typedef union { + volatile AO_double_t dw_mem; +#if defined(ETHR_NATIVE_SU_DW_SINT_T) + ETHR_NATIVE_SU_DW_SINT_T su_dw_sint; +#endif +} ethr_native_dw_atomic_t; + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_NATIVE_SU_DW_ATOMIC +#else +# define ETHR_HAVE_NATIVE_DW_ATOMIC +#endif + +#define ETHR_NATIVE_DW_ATOMIC_IMPL ETHR_NATIVE_IMPL__ + +#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__) + + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_NDWA_FUNC__(Func) ethr_native_su_dw_atomic_ ## Func +# define ETHR_NDWA_RET_3_TYPE__ ETHR_NATIVE_SU_DW_SINT_T +# define ETHR_NDWA_RET_2_TYPE__ ETHR_NATIVE_SU_DW_SINT_T +# define ETHR_NDWA_VAL_ARG_TYPE__ ETHR_NATIVE_SU_DW_SINT_T +# define ETHR_NDWA_DECL_ARG__(Arg) +# if defined(AO_HAVE_DOUBLE_PTR_STORAGE) +# define ETHR_NDWA_VAL2AOVAL__(AOV, V) \ + ((AOV).AO_whole = (double_ptr_storage) (V)) +# define ETHR_NDWA_AOVAL2VAL__(AOV, V) \ + ((V) = (ETHR_NATIVE_SU_DW_SINT_T) (AOV).AO_whole) +# define ETHR_NDWA_RETURN_VAL_3__(SUCCESS, AOVAL, VAL) \ + do { \ + return (ETHR_NATIVE_SU_DW_SINT_T) (AOVAL).AO_whole; \ + } while (0) +# define ETHR_NDWA_RETURN_VAL_2__(AOVAL, VAL) \ + do { \ + return (ETHR_NATIVE_SU_DW_SINT_T) (AOVAL).AO_whole; \ + } while (0) +# define ETHR_NDWA_AOVAL_EQ__(AOV1, AOV2) \ + ((AOV1).AO_whole == (AOV2).AO_whole) +# else +typedef union { + ethr_sint_t sint[2]; + ETHR_NATIVE_SU_DW_SINT_T dw_sint; +} ethr_dw_splitter_t; +# define ETHR_NDWA_VAL2AOVAL__(AOV, V) \ + do { \ + ethr_dw_splitter_t tmp__; \ + tmp__.dw_sint = (V); \ + (AOV).AO_val1 = (AO_t) tmp__.sint[0]; \ + (AOV).AO_val2 = (AO_t) tmp__.sint[1]; \ + } while (0) +# define ETHR_NDWA_AOVAL2VAL__(AOV, V) \ + do { \ + ethr_dw_splitter_t tmp__; \ + tmp__.sint[0] = (ethr_sint_t) (AOV).AO_val1; \ + tmp__.sint[1] = (ethr_sint_t) (AOV).AO_val2; \ + (V) = tmp__.dw_sint; \ + } while (0) +# define ETHR_NDWA_RETURN_VAL_3__(SUCCESS, AOVAL, VAL) \ + do { \ + ethr_dw_splitter_t tmp__; \ + tmp__.sint[0] = (ethr_sint_t) (AOVAL).AO_val1; \ + tmp__.sint[1] = (ethr_sint_t) (AOVAL).AO_val2; \ + return tmp__.dw_sint; \ + } while (0) +# define ETHR_NDWA_AOVAL_EQ__(AOV1, AOV2) \ + ((AOV1).AO_val1 == (AOV2).AO_val1 \ + && (AOV1).AO_val2 == (AOV2).AO_val2) +# endif +#else +# define ETHR_NDWA_FUNC__(Func) ethr_native_dw_atomic_ ## Func +# define ETHR_NDWA_RET_3_TYPE__ int +# define ETHR_NDWA_RET_2_TYPE__ void +# define ETHR_NDWA_VAL_ARG_TYPE__ ethr_sint_t * +# define ETHR_NDWA_DECL_ARG__(Arg) , ETHR_NDWA_VAL_ARG_TYPE__ Arg +# define ETHR_NDWA_VAL2AOVAL__(AOV, V) \ + do { \ + (AOV).AO_val1 = (AO_t) (V)[0]; \ + (AOV).AO_val2 = (AO_t) (V)[1]; \ + } while (0) +# define ETHR_NDWA_AOVAL2VAL__(AOV, V) \ + do { \ + ethr_dw_splitter_t tmp__; \ + (V)[0] = (ethr_sint_t) (AOV).AO_val1; \ + (V)[1] = (ethr_sint_t) (AOV).AO_val2; \ + } while (0) +# define ETHR_NDWA_RETURN_VAL_3__(SUCCESS, AOVAL, VAL) \ + do { \ + (VAL)[0] = (ethr_sint_t) (AOVAL).AO_val1; \ + (VAL)[1] = (ethr_sint_t) (AOVAL).AO_val2; \ + return (SUCCESS); \ + } while (0) +# define ETHR_NDWA_RETURN_VAL_2__(AOVAL, VAL) \ + do { \ + (VAL)[0] = (ethr_sint_t) (AOVAL).AO_val1; \ + (VAL)[1] = (ethr_sint_t) (AOVAL).AO_val2; \ + return; \ + } while (0) +# if defined(AO_HAVE_DOUBLE_PTR_STORAGE) +# define ETHR_NDWA_AOVAL_EQ__(AOV1, AOV2) \ + ((AOV1).AO_whole == (AOV2).AO_whole) +# else +# define ETHR_NDWA_AOVAL_EQ__(AOV1, AOV2) \ + ((AOV1).AO_val1 == (AOV2).AO_val1 \ + && (AOV1).AO_val2 == (AOV2).AO_val2) +# endif +#endif + +#define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_ADDR +static ETHR_INLINE ethr_sint_t * +ethr_native_dw_atomic_addr(ethr_native_dw_atomic_t *var) +{ + return (ethr_sint_t *) &var->dw_mem; +} + +#ifdef AO_HAVE_double_load + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_READ +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_READ +#endif + +static ETHR_INLINE ETHR_NDWA_RET_2_TYPE__ +ETHR_NDWA_FUNC__(read)(ethr_native_dw_atomic_t *var + ETHR_NDWA_DECL_ARG__(val)) +{ + AO_double_t act = AO_double_load(&var->dw_mem); + ETHR_NDWA_RETURN_VAL_2__(act, val); +} + +#endif + +#ifdef AO_HAVE_double_load_read + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_READ_RB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_READ_RB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_2_TYPE__ +ETHR_NDWA_FUNC__(read_rb)(ethr_native_dw_atomic_t *var + ETHR_NDWA_DECL_ARG__(val)) +{ + AO_double_t act = AO_double_load_read(&var->dw_mem); + ETHR_NDWA_RETURN_VAL_2__(act, val); +} + +#endif + +#ifdef AO_HAVE_double_load_acquire + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_READ_ACQB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_READ_ACQB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_2_TYPE__ +ETHR_NDWA_FUNC__(read_acqb)(ethr_native_dw_atomic_t *var + ETHR_NDWA_DECL_ARG__(val)) +{ + AO_double_t act = AO_double_load_acquire(&var->dw_mem); + ETHR_NDWA_RETURN_VAL_2__(act, val); +} + +#endif + +#ifdef AO_HAVE_double_store + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_SET +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_SET +#endif + +static ETHR_INLINE void +ETHR_NDWA_FUNC__(set)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ val) +{ + AO_double_t new; + ETHR_NDWA_VAL2AOVAL__(new, val); + AO_double_store(&var->dw_mem, new); +} + +#endif + +#ifdef AO_HAVE_double_store_write + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_SET_WB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_SET_WB +#endif + +static ETHR_INLINE void +ETHR_NDWA_FUNC__(set_wb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ val) +{ + AO_double_t new; + ETHR_NDWA_VAL2AOVAL__(new, val); + AO_double_store_write(&var->dw_mem, new); +} + +#endif + +#ifdef AO_HAVE_double_store_release + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_SET_RELB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_SET_RELB +#endif + +static ETHR_INLINE void +ETHR_NDWA_FUNC__(set_relb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ val) +{ + AO_double_t new; + ETHR_NDWA_VAL2AOVAL__(new, val); + AO_double_store_release(&var->dw_mem, new); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap_full) || defined(AO_HAVE_compare_double_and_swap_double_full) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_MB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG_MB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg_mb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap_full) + xchgd = AO_double_compare_and_swap_full(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double_full) + xchgd = AO_compare_double_and_swap_double_full(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + +#ifdef AO_HAVE_double_load_acquire + ao_act = AO_double_load_acquire(&var->dw_mem); +#else + ao_act = AO_double_load(&var->dw_mem); +#endif + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + +#ifndef AO_HAVE_double_load_acquire + AO_nop_full(); +#endif + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap) || defined(AO_HAVE_compare_double_and_swap_double) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap) + xchgd = AO_double_compare_and_swap(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double) + xchgd = AO_compare_double_and_swap_double(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + +#ifdef AO_HAVE_double_load + ao_act = AO_double_load(&var->dw_mem); +#else + ao_act = AO_double_load_acquire(&var->dw_mem); +#endif + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap_read) || defined(AO_HAVE_compare_double_and_swap_double_read) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_RB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG_RB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg_rb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap_read) + xchgd = AO_double_compare_and_swap_read(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double_read) + xchgd = AO_compare_double_and_swap_double_read(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + +#if defined(AO_HAVE_double_load_read) + ao_act = AO_double_load_read(&var->dw_mem); +#elif defined(AO_HAVE_double_load) + ao_act = AO_double_load(&var->dw_mem); +#else + ao_act = AO_double_load_acquire(&var->dw_mem); +#endif + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + +#ifndef AO_HAVE_double_load_read +#ifdef AO_HAVE_nop_read + AO_nop_read(); +#else + AO_nop_full(); +#endif +#endif + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap_acquire) || defined(AO_HAVE_compare_double_and_swap_double_acquire) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_ACQB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG_ACQB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg_acqb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap_acquire) + xchgd = AO_double_compare_and_swap_acquire(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double_acquire) + xchgd = AO_compare_double_and_swap_double_acquire(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + +#ifdef AO_HAVE_double_load_acquire + ao_act = AO_double_load_acquire(&var->dw_mem); +#else + ao_act = AO_double_load(&var->dw_mem); +#endif + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + +#ifndef AO_HAVE_double_load_acquire + AO_nop_full(); +#endif + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap_write) || defined(AO_HAVE_compare_double_and_swap_double_write) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_WB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG_WB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg_wb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap_write) + xchgd = AO_double_compare_and_swap_write(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double_write) + xchgd = AO_compare_double_and_swap_double_write(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + +#ifdef AO_HAVE_double_load + ao_act = AO_double_load(&var->dw_mem); +#else + ao_act = AO_double_load_acquire(&var->dw_mem); +#endif + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#if defined(AO_HAVE_double_compare_and_swap_release) || defined(AO_HAVE_compare_double_and_swap_double_release) + +#if defined(ETHR_NATIVE_SU_DW_SINT_T) +# define ETHR_HAVE_ETHR_NATIVE_SU_DW_ATOMIC_CMPXCHG_RELB +#else +# define ETHR_HAVE_ETHR_NATIVE_DW_ATOMIC_CMPXCHG_RELB +#endif + +static ETHR_INLINE ETHR_NDWA_RET_3_TYPE__ +ETHR_NDWA_FUNC__(cmpxchg_relb)(ethr_native_dw_atomic_t *var, + ETHR_NDWA_VAL_ARG_TYPE__ new, + ETHR_NDWA_VAL_ARG_TYPE__ exp) +{ + AO_double_t ao_act, ao_new, ao_exp; + + ETHR_NDWA_VAL2AOVAL__(ao_exp, exp); + ETHR_NDWA_VAL2AOVAL__(ao_new, new); + + do { + int xchgd; +#if defined(AO_HAVE_double_compare_and_swap_release) + xchgd = AO_double_compare_and_swap_release(&var->dw_mem, ao_exp, ao_new); +#elif defined(AO_HAVE_compare_double_and_swap_double_release) + xchgd = AO_compare_double_and_swap_double_release(&var->dw_mem, + ao_exp.AO_val1, + ao_exp.AO_val2, + ao_new.AO_val1, + ao_new.AO_val2); +#endif + + if (xchgd) + ETHR_NDWA_RETURN_VAL_3__(1, ao_exp, exp); + + ao_act = AO_double_load(&var->dw_mem); + + } while (ETHR_NDWA_AOVAL_EQ__(ao_exp, ao_act)); + + ETHR_NDWA_RETURN_VAL_3__(1, ao_act, exp); +} + +#endif + +#endif /* defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__) */ + +#endif /* Have AO double functionality ... */ + +#endif /* ETHR_LIBATOMIC_OPS_DW_ATOMIC_H__ */ + diff --git a/erts/include/internal/libatomic_ops/ethread.h b/erts/include/internal/libatomic_ops/ethread.h index e1fdd588bb..d65ee19b04 100644 --- a/erts/include/internal/libatomic_ops/ethread.h +++ b/erts/include/internal/libatomic_ops/ethread.h @@ -33,9 +33,12 @@ #define AO_USE_PENTIUM4_INSTRS #endif +#define ETHR_NATIVE_IMPL__ "libatomic_ops" + #include "atomic_ops.h" #include "ethr_membar.h" #include "ethr_atomic.h" +#include "ethr_dw_atomic.h" #endif diff --git a/erts/include/internal/ppc32/atomic.h b/erts/include/internal/ppc32/atomic.h index 6001620677..b558626b09 100644 --- a/erts/include/internal/ppc32/atomic.h +++ b/erts/include/internal/ppc32/atomic.h @@ -91,6 +91,20 @@ ethr_native_atomic32_add_return_acqb(ethr_native_atomic32_t *var, ethr_sint32_t return res; } + +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_add_return_relb(ethr_native_atomic32_t *var, ethr_sint32_t incr) +{ + ethr_lwsync__(); + return ethr_native_atomic32_add_return(var, incr); +} + +#endif + #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_INC_RETURN 1 static ETHR_INLINE ethr_sint32_t @@ -120,7 +134,19 @@ ethr_native_atomic32_inc_return_acqb(ethr_native_atomic32_t *var) __asm__ __volatile("isync\n\t" : : : "memory"); return res; } - + +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_INC_RETURN_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_inc_return_relb(ethr_native_atomic32_t *var) +{ + ethr_lwsync__(); + return ethr_native_atomic32_inc_return(var); +} + +#endif #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_DEC_RETURN 1 @@ -152,6 +178,19 @@ ethr_native_atomic32_dec_return_acqb(ethr_native_atomic32_t *var) return res; } +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_DEC_RETURN_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_dec_return_relb(ethr_native_atomic32_t *var) +{ + ethr_lwsync__(); + return ethr_native_atomic32_dec_return(var); +} + +#endif + #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD 1 static ETHR_INLINE ethr_sint32_t @@ -182,6 +221,19 @@ ethr_native_atomic32_and_retold_acqb(ethr_native_atomic32_t *var, ethr_sint32_t return res; } +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_and_retold_relb(ethr_native_atomic32_t *var, ethr_sint32_t mask) +{ + ethr_lwsync__(); + return ethr_native_atomic32_and_retold(var, mask); +} + +#endif + #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD 1 static ETHR_INLINE ethr_sint32_t @@ -212,6 +264,18 @@ ethr_native_atomic32_or_retold_acqb(ethr_native_atomic32_t *var, ethr_sint32_t m return res; } +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_or_retold_relb(ethr_native_atomic32_t *var, ethr_sint32_t mask) +{ + ethr_lwsync__(); + return ethr_native_atomic32_or_retold(var, mask); +} + +#endif #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_XCHG 1 @@ -242,6 +306,19 @@ ethr_native_atomic32_xchg_acqb(ethr_native_atomic32_t *var, ethr_sint32_t val) return res; } +#ifndef ETHR_PPC_HAVE_NO_LWSYNC + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_XCHG_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_xchg_relb(ethr_native_atomic32_t *var, ethr_sint32_t val) +{ + ethr_lwsync__(); + return ethr_native_atomic32_xchg(var, val); +} + +#endif + #define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG 1 static ETHR_INLINE ethr_sint32_t @@ -291,6 +368,73 @@ ethr_native_atomic32_cmpxchg_acqb(ethr_native_atomic32_t *var, return old; } +#if !defined(ETHR_DISABLE_LWSYNC_FOR_CMPXCHG_RELB) && !defined(ETHR_PPC_HAVE_NO_LWSYNC) + +#define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_RELB 1 + +static ETHR_INLINE ethr_sint32_t +ethr_native_atomic32_cmpxchg_relb(ethr_native_atomic32_t *var, + ethr_sint32_t new, + ethr_sint32_t expected) +{ + ethr_sint32_t actual; + + /* + * We want to implement the release barrier using the + * 'lwsync' instruction instead of using the more + * expensive 'sync' instruction. + * + * cmpxchg looks something like this: + * + * lwarx # Load + * ... + * if (fail) + * goto done; + * stwcx # Store + * if (fail) + * goto done; + * ... + * + * In the case we succeeded, 'lwsync' will have + * ordered all previously issued loads and stores + * against the successful store to this variable. + * That is everything is fine! + * + * In the case we did not succeed, we need to order + * all previously issued loads and stores against + * the load of this variable. 'lwsync' does not + * guarantee this. In order to solve this we issue + * a 'sync' and redo the load. If the value has + * changed to what the user passed as expected value + * we need to try the cmpxchg operation again, since + * this value indicates success. + */ + + ethr_lwsync__(); + + actual = ethr_native_atomic32_cmpxchg(var, new, expected); + +#ifndef ETHR_PPC_HAVE_LWSYNC + /* We checked for lwsync support in runtime... */ + if (ETHR_PPC_RUNTIME_CONF_HAVE_NO_LWSYNC__) + return actual; /* No need to; ethr_lwsync__() issued a sync... */ +#endif + + /* ethr_lwsync__() issued an lwsync... */ + if (actual == expected) + return actual; /* Successful operation */ + + /* Failure... need to issue a sync... */ + ethr_sync__(); + actual = ethr_native_atomic32_read(var); + if (actual != expected) + return actual; /* Fail... */ + /* Try again... */ + return ethr_native_atomic32_cmpxchg(var, new, expected); +} + +#endif + #endif /* ETHR_TRY_INLINE_FUNCS */ #endif /* ETHREAD_PPC_ATOMIC_H */ diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c index d58a28b5cb..7833dd8219 100644 --- a/erts/lib_src/common/erl_misc_utils.c +++ b/erts/lib_src/common/erl_misc_utils.c @@ -1515,7 +1515,7 @@ const char* parse_topology_spec_group(erts_cpu_info_t *cpuinfo, const char* xml, if (is_thread_group) { thread++; } else { - *core_p = (*core_p)++; + *core_p = (*core_p) + 1; } index_procs++; } @@ -1535,9 +1535,9 @@ const char* parse_topology_spec_group(erts_cpu_info_t *cpuinfo, const char* xml, if (parentCacheLevel == 0) { *core_p = 0; - *processor_p = (*processor_p)++; + *processor_p = (*processor_p) + 1; } else { - *core_p = (*core_p)++; + *core_p = (*core_p) + 1; } if (error) diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam Binary files differindex 001c9c76ed..10138cab22 100644 --- a/erts/preloaded/ebin/erl_prim_loader.beam +++ b/erts/preloaded/ebin/erl_prim_loader.beam diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex c5cf4b459f..7a3d94dd16 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam Binary files differindex b467633a4d..9b364d8b21 100644 --- a/erts/preloaded/ebin/erts_internal.beam +++ b/erts/preloaded/ebin/erts_internal.beam diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam Binary files differindex 915a2d1aef..a190129b2c 100644 --- a/erts/preloaded/ebin/init.beam +++ b/erts/preloaded/ebin/init.beam diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam Binary files differindex df1bf932a3..621f036f33 100644 --- a/erts/preloaded/ebin/otp_ring0.beam +++ b/erts/preloaded/ebin/otp_ring0.beam diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam Binary files differindex 95b4bbca2d..6695f4cd15 100644 --- a/erts/preloaded/ebin/prim_eval.beam +++ b/erts/preloaded/ebin/prim_eval.beam diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam Binary files differindex 5e4fc5ba84..5e9230826d 100644 --- a/erts/preloaded/ebin/prim_file.beam +++ b/erts/preloaded/ebin/prim_file.beam diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex 9d9a4886d9..83230d42ae 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam Binary files differindex d98b0275f4..b3abba3223 100644 --- a/erts/preloaded/ebin/prim_zip.beam +++ b/erts/preloaded/ebin/prim_zip.beam diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam Binary files differindex 0744bdb21d..7006764d96 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 98d7a942a6..611a568014 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -2233,6 +2233,7 @@ tuple_to_list(_Tuple) -> (dynamic_trace) -> none | dtrace | systemtap; (dynamic_trace_probes) -> boolean(); (elib_malloc) -> false; + (eager_check_io) -> boolean(); (ets_limit) -> pos_integer(); (fullsweep_after) -> {fullsweep_after, non_neg_integer()}; (garbage_collection) -> [{atom(), integer()}]; @@ -2251,6 +2252,7 @@ tuple_to_list(_Tuple) -> (modified_timing_level) -> integer() | undefined; (multi_scheduling) -> disabled | blocked | enabled; (multi_scheduling_blockers) -> [PID :: pid()]; + (nif_version) -> string(); (otp_release) -> string(); (port_count) -> non_neg_integer(); (port_limit) -> pos_integer(); diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl index 229d10ccee..385353f046 100644 --- a/erts/test/otp_SUITE.erl +++ b/erts/test/otp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2013. All Rights Reserved. +%% Copyright Ericsson AB 2000-2015. 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 @@ -94,7 +94,9 @@ undefined_functions(Config) when is_list(Config) -> Undef4 = eunit_filter(Undef3), Undef5 = dialyzer_filter(Undef4), Undef6 = wx_filter(Undef5), - Undef = gs_filter(Undef6), + Undef7 = gs_filter(Undef6), + Undef8 = diameter_filter(Undef7), + Undef = ssh_filter(Undef8), case Undef of [] -> ok; @@ -217,6 +219,28 @@ gs_filter(Undef) -> _ -> Undef end. +diameter_filter(Undef) -> + %% Filter away function calls that are catched for OTP 18 time API + filter(fun({{diameter_lib,_,_},{erlang,convert_time_resolution,3}}) -> + false; + ({{diameter_lib,_,_},{erlang,monotonic_time,0}}) -> + false; + ({{diameter_lib,_,_},{erlang,time_resolution,0}}) -> + false; + ({{diameter_lib,_,_},{erlang,unique_integer,0}}) -> + false; + ({{diameter_lib,_,_},{erlang,time_offset,0}}) -> + false; + (_) -> true + end, Undef). + +ssh_filter(Undef) -> + %% Filter away function calls that are catched for OTP 18 time API + filter(fun({{ssh_info,_,_},{erlang,timestamp,0}}) -> + false; + (_) -> true + end, Undef). + deprecated_not_in_obsolete(Config) when is_list(Config) -> ?line Server = ?config(xref_server, Config), ?line {ok,DeprecatedFunctions} = xref:q(Server, "DF"), diff --git a/erts/test/upgrade_SUITE.erl b/erts/test/upgrade_SUITE.erl index d5a920e03d..217056971e 100644 --- a/erts/test/upgrade_SUITE.erl +++ b/erts/test/upgrade_SUITE.erl @@ -37,8 +37,9 @@ %% - hipe does not support any upgrade at all %% - dialyzer requires hipe (in the .app file) %% - typer requires hipe (in the .app file) +%% - erl_interface, jinterface support no upgrade -define(appup_exclude, - [dialyzer,hipe,typer]). + [dialyzer,hipe,typer,erl_interface,jinterface]). init_per_suite(Config) -> %% Check that a real release is running, not e.g. cerl diff --git a/erts/vsn.mk b/erts/vsn.mk index b6a38f9361..e4b071b090 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -17,7 +17,7 @@ # %CopyrightEnd% # -VSN = 6.2 +VSN = 6.3.1 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index a7032737bd..cf87c01658 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -31,6 +31,38 @@ <p>This document describes the changes made to the asn1 application.</p> +<section><title>Asn1 3.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + When decoding BER, primitives with an indefinite length + will be immediately rejected. (Thanks to Simon Cornish + for reporting this bug.)</p> + <p> + Own Id: OTP-12205</p> + </item> + <item> + <p> + BER: A bug with compliance to X.680 (200811) s31.2.7 has + been fixed. Basically, when TagDefault is AUTOMATIC then + tags are IMPLICIT unless EXPLICIT is given.</p> + <p> + Own Id: OTP-12318</p> + </item> + <item> + <p> + Usage of the <c>EXTERNAL</c> 1994 variant type was + broken.</p> + <p> + Own Id: OTP-12326</p> + </item> + </list> + </section> + +</section> + <section><title>Asn1 3.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 5d8740b92e..240f1cbb16 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -2148,11 +2148,9 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) -> {'INTEGER',NamedNumberList} -> ok = validate_integer(SVal, Value, NamedNumberList, Constr), V#valuedef{value=normalize_value(SVal, Vtype, Value, [])}; - #'SEQUENCE'{components=Components} -> - {ok,SeqVal} = validate_sequence(SVal, Value, - Components, Constr), - V#valuedef{value=normalize_value(SVal, Vtype, - SeqVal, TopName)}; + #'SEQUENCE'{} -> + {ok,SeqVal} = convert_external(SVal, Value), + V#valuedef{value=normalize_value(SVal, Vtype, SeqVal, TopName)}; {'SelectionType',SelName,SelT} -> CheckedT = check_selectiontype(SVal, SelName, SelT), NewV = V#valuedef{type=CheckedT}, @@ -2412,13 +2410,13 @@ valid_objectid(o_id,_I,[1]) -> false; valid_objectid(o_id,_I,[2]) -> true; valid_objectid(_,_,_) -> true. -validate_sequence(S=#state{type=Vtype},Value,_Components,_Constr) -> +convert_external(S=#state{type=Vtype}, Value) -> case Vtype of #type{tag=[{tag,'UNIVERSAL',8,'IMPLICIT',32}]} -> %% this is an 'EXTERNAL' (or INSTANCE OF) case Value of - [{identification,_}|_RestVal] -> - {ok,to_EXTERNAL1990(S,Value)}; + [{#seqtag{val=identification},_}|_] -> + {ok,to_EXTERNAL1990(S, Value)}; _ -> {ok,Value} end; @@ -2426,21 +2424,25 @@ validate_sequence(S=#state{type=Vtype},Value,_Components,_Constr) -> {ok,Value} end. -to_EXTERNAL1990(S,[{identification,{'CHOICE',{syntax,Stx}}}|Rest]) -> - to_EXTERNAL1990(S,Rest,[{'direct-reference',Stx}]); -to_EXTERNAL1990(S,[{identification,{'CHOICE',{'presentation-context-id',I}}}|Rest]) -> - to_EXTERNAL1990(S,Rest,[{'indirect-reference',I}]); -to_EXTERNAL1990(S,[{identification,{'CHOICE',{'context-negotiation',[{_,PCid},{_,TrStx}]}}}|Rest]) -> - to_EXTERNAL1990(S,Rest,[{'indirect-reference',PCid},{'direct-reference',TrStx}]); -to_EXTERNAL1990(S,_) -> +to_EXTERNAL1990(S, [{#seqtag{val=identification}=T, + {'CHOICE',{syntax,Stx}}}|Rest]) -> + to_EXTERNAL1990(S, Rest, [{T#seqtag{val='direct-reference'},Stx}]); +to_EXTERNAL1990(S, [{#seqtag{val=identification}=T, + {'CHOICE',{'presentation-context-id',I}}}|Rest]) -> + to_EXTERNAL1990(S, Rest, [{T#seqtag{val='indirect-reference'},I}]); +to_EXTERNAL1990(S, [{#seqtag{val=identification}=T, + {'CHOICE',{'context-negotiation',[{_,PCid},{_,TrStx}]}}}|Rest]) -> + to_EXTERNAL1990(S, Rest, [{T#seqtag{val='indirect-reference'},PCid}, + {T#seqtag{val='direct-reference'},TrStx}]); +to_EXTERNAL1990(S, _) -> error({value,"illegal value in EXTERNAL type",S}). -to_EXTERNAL1990(S,[V={'data-value-descriptor',_}|Rest],Acc) -> - to_EXTERNAL1990(S,Rest,[V|Acc]); -to_EXTERNAL1990(_S,[{'data-value',Val}],Acc) -> - Encoding = {encoding,{'CHOICE',{'octet-aligned',Val}}}, +to_EXTERNAL1990(S, [V={#seqtag{val='data-value-descriptor'},_}|Rest], Acc) -> + to_EXTERNAL1990(S, Rest, [V|Acc]); +to_EXTERNAL1990(_S, [{#seqtag{val='data-value'}=T,Val}], Acc) -> + Encoding = {T#seqtag{val=encoding},{'CHOICE',{'octet-aligned',Val}}}, lists:reverse([Encoding|Acc]); -to_EXTERNAL1990(S,_,_) -> +to_EXTERNAL1990(S, _, _) -> error({value,"illegal value in EXTERNAL type",S}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -6581,6 +6583,8 @@ merge_tags2([T1= #tag{type='IMPLICIT'}, T2 |Rest], Acc) -> merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc); merge_tags2([T1= #tag{type={default,'IMPLICIT'}}, T2 |Rest], Acc) -> merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc); +merge_tags2([T1= #tag{type={default,'AUTOMATIC'}}, T2 |Rest], Acc) -> + merge_tags2([T1#tag{type=T2#tag.type, form=T2#tag.form}|Rest],Acc); merge_tags2([H|T],Acc) -> merge_tags2(T, [H|Acc]); merge_tags2([], Acc) -> diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index 888339a4d2..432197eec0 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -60,7 +60,8 @@ groups() -> {ber, Parallel, [ber_choiceinseq, % Uses 'SOpttest' - ber_optional]}, + ber_optional, + tagdefault_automatic]}, {app_test, [], [{asn1_app_test, all}]}, @@ -659,6 +660,19 @@ ber_optional(Config, Rule, Opts) -> {'C', asn1_NOVALUE, 111, asn1_NOVALUE}}, asn1_test_lib:roundtrip('SOpttest', 'S', V). +tagdefault_automatic(Config) -> + test(Config, fun tagdefault_automatic/3, [ber]). +tagdefault_automatic(Config, Rule, Opts) -> + asn1_test_lib:compile("TAGDEFAULT-AUTOMATIC", Config, [Rule|Opts]), + << 48,8,128,2,100,101,129,2,110,111 >> = + asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Tagged', {'Tagged', << 100,101 >>, << 110,111 >>}), + << 48,8,128,2,100,101,129,2,110,111 >> = + asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Untagged', {'Untagged', << 100,101 >>, << 110,111 >>}), + << 48,8,4,2,100,101,130,2,110,111 >> = + asn1_test_lib:roundtrip_enc('TAGDEFAULT-AUTOMATIC', 'Mixed', {'Mixed', << 100,101 >>, << 110,111 >>}), + + ok. + %% records used by test-case default -record('Def1', {bool0, bool1 = asn1_DEFAULT, diff --git a/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 index c8145bad63..e279a180c1 100644 --- a/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/ContextSwitchingTypes.asn1 @@ -21,6 +21,10 @@ val3-T T ::= {identification context-negotiation:{presentation-context-id 12, transfer-syntax {1 2 3}}, data-value '123'H} +val4-T T ::= {identification presentation-context-id:42, + data-value-descriptor "FooBar", + data-value '123'H} + -- EMBEDDED PDV type EP ::= EMBEDDED PDV diff --git a/lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn b/lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn new file mode 100644 index 0000000000..2fcba1f71e --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/TAGDEFAULT-AUTOMATIC.asn @@ -0,0 +1,25 @@ +TAGDEFAULT-AUTOMATIC DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + +EXPORTS + Tagged, + Untagged, + Mixed +; + +Tagged ::= SEQUENCE { + o0 [0] OCTET STRING, + o1 [1] OCTET STRING +} + +Untagged ::= SEQUENCE { + o0 OCTET STRING, + o1 OCTET STRING +} + +Mixed ::= SEQUENCE { + o0 OCTET STRING, + o2 [2] OCTET STRING +} + +END diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl index bdd6883dac..61d1fbdd69 100644 --- a/lib/asn1/test/testContextSwitchingTypes.erl +++ b/lib/asn1/test/testContextSwitchingTypes.erl @@ -24,11 +24,21 @@ -include_lib("test_server/include/test_server.hrl"). test(Config) -> - ValT = 'ContextSwitchingTypes':'val1-T'(), - check_EXTERNAL(enc_dec('T', ValT)), + ValT_1 = 'ContextSwitchingTypes':'val1-T'(), + check_EXTERNAL(enc_dec('T', ValT_1)), + + ValT_2 = 'ContextSwitchingTypes':'val2-T'(), + check_EXTERNAL(enc_dec('T', ValT_2)), + + ValT_3 = 'ContextSwitchingTypes':'val3-T'(), + check_EXTERNAL(enc_dec('T', ValT_3)), + + ValT_4 = 'ContextSwitchingTypes':'val4-T'(), + check_EXTERNAL(enc_dec('T', ValT_4)), {ok,ValT2} = asn1ct:value('ContextSwitchingTypes', 'T', [{i,?config(case_dir, Config)}]), + io:format("ValT2 ~p~n",[ValT2]), check_EXTERNAL(enc_dec('T', ValT2)), ValEP = 'ContextSwitchingTypes':'val1-EP'(), diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index d87c50637d..daaf26a17f 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,2 +1,2 @@ #next version number to use is 2.0 -ASN1_VSN = 3.0.2 +ASN1_VSN = 3.0.3 diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index f4ce5369f7..94738d2eff 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -32,6 +32,94 @@ <file>notes.xml</file> </header> +<section><title>Common_Test 1.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The source code to html code generator in Test Server + (and Common Test) would fail to generate anchors in the + html code for functions with non-expandable macros, + resulting in bad html links to such functions. This + correction lets the code generator ignore macros that + can't be expanded (i.e. not pre-process them), so that + correct anchors will always be produced.</p> + <p> + Own Id: OTP-11766 Aux Id: seq12556 </p> + </item> + <item> + <p> + OTP-11971 erroneously changed the handling of relative + paths (import/export files) specified in the cover spec + file. This is now corrected so these are expected to be + relative to the directory where the cover spec file + itself is stored.</p> + <p> + Own Id: OTP-12031</p> + </item> + <item> + <p> + Common Test would sometimes crash while trying to print + large amounts of SASL reports to log on a computer with a + slow file system. This problem (due to an error in IO + message buffering in ct_logs) has been fixed.</p> + <p> + Own Id: OTP-12159</p> + </item> + <item> + <p> + The common_test telnet client, ct_telnet and friends, had + some unstable test cases. Some of these were caused by + the unix_telnet callback sending an extra newline after + sending the password. This caused the sever to send an + extra prompt back which confused the tests. The extra + newline is no longer sent.</p> + <p> + Also, debug printouts and logging from the telnet client + is improved, and some test cases are slightly modified in + order to stabilize the test.</p> + <p> + Own Id: OTP-12329</p> + </item> + <item> + <p> + ct_netconfc did not expect the return value + {error,timeout} from ssh_connection:subsystem/4. This has + been corrected.</p> + <p> + Own Id: OTP-12334</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new option, <c>{newline,boolean()}</c> is added to all + functions in <c>ct_telnet</c> that send data (command + strings) to the telnet server. By default, + <c>ct_telnet</c> adds a newline to all command strings, + and by setting the new option to <c>false</c> this + behavior is turned off.</p> + <p> + Own Id: OTP-12252 Aux Id: seq12730 </p> + </item> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + </list> + </section> + +</section> + <section><title>Common_Test 1.8.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in index 5a9fabbe45..1bc6b82ebb 100644 --- a/lib/common_test/priv/Makefile.in +++ b/lib/common_test/priv/Makefile.in @@ -71,7 +71,7 @@ debug opt: $(V_at)sed -e 's;@CT_VSN@;$(VSN);' \ -e 's;@TS_VSN@;$(TEST_SERVER_VSN);' \ ../install.sh.in > install.sh - $(V_at)chmod 775 install.sh + - $(V_at)chmod -f 775 install.sh docs: diff --git a/lib/common_test/priv/auxdir/config.guess b/lib/common_test/priv/auxdir/config.guess deleted file mode 100755 index f475ceb413..0000000000 --- a/lib/common_test/priv/auxdir/config.guess +++ /dev/null @@ -1,1534 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to [email protected]. - - -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 1992-2013 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - 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 ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <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:*:[4567]) - 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 -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <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:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-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 ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </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 i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <[email protected]> - 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*) - # From [email protected]. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From [email protected]. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From [email protected]. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - 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 ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -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/common_test/priv/auxdir/config.sub b/lib/common_test/priv/auxdir/config.sub deleted file mode 100755 index bb6edbdb47..0000000000 --- a/lib/common_test/priv/auxdir/config.sub +++ /dev/null @@ -1,1789 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to [email protected]. -# -# 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. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# 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 1992-2013 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-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - 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 | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -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 \ - | aarch64 | aarch64_be \ - | 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[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-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-* \ - | aarch64-* | aarch64_be-* \ - | 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-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | 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-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - 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-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - 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 - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - 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 | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - 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 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - 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 - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -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* | -es*) - # 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 - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -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 - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - 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 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or1k-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: - diff --git a/lib/common_test/priv/auxdir/install-sh b/lib/common_test/priv/auxdir/install-sh deleted file mode 100755 index a5897de6ea..0000000000 --- a/lib/common_test/priv/auxdir/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/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl index c7f446dee9..b630a51835 100644 --- a/lib/common_test/src/ct_cover.erl +++ b/lib/common_test/src/ct_cover.erl @@ -174,7 +174,7 @@ get_spec_test(File) -> [] -> [#cover{app=none, level=details}]; _ -> Res end, - case get_cover_opts(Apps, Terms, []) of + case get_cover_opts(Apps, Terms, Dir, []) of E = {error,_} -> E; [CoverSpec] -> @@ -205,124 +205,125 @@ collect_apps([], Apps) -> %% get_cover_opts(Terms) -> AppCoverInfo %% AppCoverInfo: [#cover{app=App,...}] -get_cover_opts([App | Apps], Terms, CoverInfo) -> - case get_app_info(App, Terms) of +get_cover_opts([App | Apps], Terms, Dir, CoverInfo) -> + case get_app_info(App, Terms, Dir) of E = {error,_} -> E; AppInfo -> AppInfo1 = files2mods(AppInfo), - get_cover_opts(Apps, Terms, [AppInfo1|CoverInfo]) + get_cover_opts(Apps, Terms, Dir, [AppInfo1|CoverInfo]) end; -get_cover_opts([], _, CoverInfo) -> +get_cover_opts([], _, _, CoverInfo) -> lists:reverse(CoverInfo). -%% get_app_info(App, Terms) -> App1 +%% get_app_info(App, Terms, Dir) -> App1 -get_app_info(App=#cover{app=none}, [{incl_dirs,Dirs}|Terms]) -> - get_app_info(App, [{incl_dirs,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{incl_dirs,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".beam", false, []) of +get_app_info(App=#cover{app=none}, [{incl_dirs,Dirs}|Terms], Dir) -> + get_app_info(App, [{incl_dirs,none,Dirs}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{incl_dirs,Name,Dirs}|Terms], Dir) -> + case get_files(Dirs, Dir, ".beam", false, []) of E = {error,_} -> E; Mods1 -> Mods = App#cover.incl_mods, - get_app_info(App#cover{incl_mods=Mods++Mods1},Terms) + get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{incl_dirs_r,Dirs}|Terms]) -> - get_app_info(App, [{incl_dirs_r,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{incl_dirs_r,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".beam", true, []) of +get_app_info(App=#cover{app=none}, [{incl_dirs_r,Dirs}|Terms], Dir) -> + get_app_info(App, [{incl_dirs_r,none,Dirs}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{incl_dirs_r,Name,Dirs}|Terms], Dir) -> + case get_files(Dirs, Dir, ".beam", true, []) of E = {error,_} -> E; Mods1 -> Mods = App#cover.incl_mods, - get_app_info(App#cover{incl_mods=Mods++Mods1},Terms) + get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{incl_mods,Mods1}|Terms]) -> - get_app_info(App, [{incl_mods,none,Mods1}|Terms]); -get_app_info(App=#cover{app=Name}, [{incl_mods,Name,Mods1}|Terms]) -> +get_app_info(App=#cover{app=none}, [{incl_mods,Mods1}|Terms], Dir) -> + get_app_info(App, [{incl_mods,none,Mods1}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{incl_mods,Name,Mods1}|Terms], Dir) -> Mods = App#cover.incl_mods, - get_app_info(App#cover{incl_mods=Mods++Mods1},Terms); + get_app_info(App#cover{incl_mods=Mods++Mods1},Terms,Dir); -get_app_info(App=#cover{app=none}, [{excl_dirs,Dirs}|Terms]) -> - get_app_info(App, [{excl_dirs,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{excl_dirs,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".beam", false, []) of +get_app_info(App=#cover{app=none}, [{excl_dirs,Dirs}|Terms], Dir) -> + get_app_info(App, [{excl_dirs,none,Dirs}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{excl_dirs,Name,Dirs}|Terms], Dir) -> + case get_files(Dirs, Dir, ".beam", false, []) of E = {error,_} -> E; Mods1 -> Mods = App#cover.excl_mods, - get_app_info(App#cover{excl_mods=Mods++Mods1},Terms) + get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{excl_dirs_r,Dirs}|Terms]) -> - get_app_info(App, [{excl_dirs_r,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{excl_dirs_r,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".beam", true, []) of +get_app_info(App=#cover{app=none}, [{excl_dirs_r,Dirs}|Terms],Dir) -> + get_app_info(App, [{excl_dirs_r,none,Dirs}|Terms],Dir); +get_app_info(App=#cover{app=Name}, [{excl_dirs_r,Name,Dirs}|Terms],Dir) -> + case get_files(Dirs, Dir, ".beam", true, []) of E = {error,_} -> E; Mods1 -> Mods = App#cover.excl_mods, - get_app_info(App#cover{excl_mods=Mods++Mods1},Terms) + get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{excl_mods,Mods1}|Terms]) -> - get_app_info(App, [{excl_mods,none,Mods1}|Terms]); -get_app_info(App=#cover{app=Name}, [{excl_mods,Name,Mods1}|Terms]) -> +get_app_info(App=#cover{app=none}, [{excl_mods,Mods1}|Terms], Dir) -> + get_app_info(App, [{excl_mods,none,Mods1}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{excl_mods,Name,Mods1}|Terms], Dir) -> Mods = App#cover.excl_mods, - get_app_info(App#cover{excl_mods=Mods++Mods1},Terms); + get_app_info(App#cover{excl_mods=Mods++Mods1},Terms,Dir); -get_app_info(App=#cover{app=none}, [{cross,Cross}|Terms]) -> - get_app_info(App, [{cross,none,Cross}|Terms]); -get_app_info(App=#cover{app=Name}, [{cross,Name,Cross1}|Terms]) -> +get_app_info(App=#cover{app=none}, [{cross,Cross}|Terms], Dir) -> + get_app_info(App, [{cross,none,Cross}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{cross,Name,Cross1}|Terms], Dir) -> Cross = App#cover.cross, - get_app_info(App#cover{cross=Cross++Cross1},Terms); + get_app_info(App#cover{cross=Cross++Cross1},Terms,Dir); -get_app_info(App=#cover{app=none}, [{src_dirs,Dirs}|Terms]) -> - get_app_info(App, [{src_dirs,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{src_dirs,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".erl", false, []) of +get_app_info(App=#cover{app=none}, [{src_dirs,Dirs}|Terms], Dir) -> + get_app_info(App, [{src_dirs,none,Dirs}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{src_dirs,Name,Dirs}|Terms], Dir) -> + case get_files(Dirs, Dir, ".erl", false, []) of E = {error,_} -> E; Src1 -> Src = App#cover.src, - get_app_info(App#cover{src=Src++Src1},Terms) + get_app_info(App#cover{src=Src++Src1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{src_dirs_r,Dirs}|Terms]) -> - get_app_info(App, [{src_dirs_r,none,Dirs}|Terms]); -get_app_info(App=#cover{app=Name}, [{src_dirs_r,Name,Dirs}|Terms]) -> - case get_files(Dirs, ".erl", true, []) of +get_app_info(App=#cover{app=none}, [{src_dirs_r,Dirs}|Terms], Dir) -> + get_app_info(App, [{src_dirs_r,none,Dirs}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{src_dirs_r,Name,Dirs}|Terms], Dir) -> + case get_files(Dirs, Dir, ".erl", true, []) of E = {error,_} -> E; Src1 -> Src = App#cover.src, - get_app_info(App#cover{src=Src++Src1},Terms) + get_app_info(App#cover{src=Src++Src1},Terms,Dir) end; -get_app_info(App=#cover{app=none}, [{src_files,Src1}|Terms]) -> - get_app_info(App, [{src_files,none,Src1}|Terms]); -get_app_info(App=#cover{app=Name}, [{src_files,Name,Src1}|Terms]) -> +get_app_info(App=#cover{app=none}, [{src_files,Src1}|Terms], Dir) -> + get_app_info(App, [{src_files,none,Src1}|Terms], Dir); +get_app_info(App=#cover{app=Name}, [{src_files,Name,Src1}|Terms], Dir) -> Src = App#cover.src, - get_app_info(App#cover{src=Src++Src1},Terms); + get_app_info(App#cover{src=Src++Src1},Terms,Dir); -get_app_info(App, [_|Terms]) -> - get_app_info(App, Terms); +get_app_info(App, [_|Terms], Dir) -> + get_app_info(App, Terms, Dir); -get_app_info(App, []) -> +get_app_info(App, [], _) -> App. %% get_files(...) -get_files([Dir|Dirs], Ext, Recurse, Files) -> - case file:list_dir(Dir) of +get_files([Dir|Dirs], RootDir, Ext, Recurse, Files) -> + DirAbs = filename:absname(Dir, RootDir), + case file:list_dir(DirAbs) of {ok,Entries} -> - {SubDirs,Matches} = analyse_files(Entries, Dir, Ext, [], []), + {SubDirs,Matches} = analyse_files(Entries, DirAbs, Ext, [], []), if Recurse == false -> - get_files(Dirs, Ext, Recurse, Files++Matches); + get_files(Dirs, RootDir, Ext, Recurse, Files++Matches); true -> - Files1 = get_files(SubDirs, Ext, Recurse, Files++Matches), - get_files(Dirs, Ext, Recurse, Files1) + Files1 = get_files(SubDirs, RootDir, Ext, Recurse, Files++Matches), + get_files(Dirs, RootDir, Ext, Recurse, Files1) end; {error,Reason} -> - {error,{Reason,Dir}} + {error,{Reason,DirAbs}} end; -get_files([], _Ext, _R, Files) -> +get_files([], _RootDir, _Ext, _R, Files) -> Files. %% analyse_files(...) diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index e8ea7992b4..ec525784ec 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -1268,6 +1268,11 @@ report(What,Data) -> Data1 = if GrName == undefined -> {Suite,Func,Result}; true -> Data end, + %% Register the group leader for the process calling the report + %% function, making it possible for a hook function to print + %% in the test case log file + ReportingPid = self(), + ct_logs:register_groupleader(ReportingPid, group_leader()), case Result of {failed, _} -> ct_hooks:on_tc_fail(What, Data1); @@ -1282,6 +1287,7 @@ report(What,Data) -> _Else -> ok end, + ct_logs:unregister_groupleader(ReportingPid), case {Func,Result} of {init_per_suite,_} -> ok; diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index 7037cdca73..23332ad268 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -29,6 +29,7 @@ -module(ct_logs). -export([init/2, close/2, init_tc/1, end_tc/1]). +-export([register_groupleader/2, unregister_groupleader/1]). -export([get_log_dir/0, get_log_dir/1]). -export([log/3, start_log/1, cont_log/2, end_log/0]). -export([set_stylesheet/2, clear_stylesheet/1]). @@ -267,7 +268,7 @@ init_tc(RefreshLog) -> ok. %%%----------------------------------------------------------------- -%%% @spec end_tc(TCPid) -> ok | {error,Reason} +%%% @spec end_tc(TCPid) -> ok %%% %%% @doc Test case clean up (tool-internal use only). %%% @@ -278,6 +279,26 @@ end_tc(TCPid) -> call({end_tc,TCPid}). %%%----------------------------------------------------------------- +%%% @spec register_groupleader(Pid,GroupLeader) -> ok +%%% +%%% @doc To enable logging to a group leader (tool-internal use only). +%%% +%%% <p>This function is called by ct_framework:report/2</p> +register_groupleader(Pid,GroupLeader) -> + call({register_groupleader,Pid,GroupLeader}), + ok. + +%%%----------------------------------------------------------------- +%%% @spec unregister_groupleader(Pid) -> ok +%%% +%%% @doc To disable logging to a group leader (tool-internal use only). +%%% +%%% <p>This function is called by ct_framework:report/2</p> +unregister_groupleader(Pid) -> + call({unregister_groupleader,Pid}), + ok. + +%%%----------------------------------------------------------------- %%% @spec log(Heading,Format,Args) -> ok %%% %%% @doc Log internal activity (tool-internal use only). @@ -764,6 +785,14 @@ logger_loop(State) -> return(From,ok), logger_loop(State#logger_state{tc_groupleaders = rm_tc_gl(TCPid,State)}); + {{register_groupleader,Pid,GL},From} -> + GLs = add_tc_gl(Pid,GL,State), + return(From,ok), + logger_loop(State#logger_state{tc_groupleaders = GLs}); + {{unregister_groupleader,Pid},From} -> + return(From,ok), + logger_loop(State#logger_state{tc_groupleaders = + rm_tc_gl(Pid,State)}); {{get_log_dir,true},From} -> return(From,{ok,State#logger_state.log_dir}), logger_loop(State); diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl index a3861dc745..bded5a15cb 100644 --- a/lib/common_test/src/ct_netconfc.erl +++ b/lib/common_test/src/ct_netconfc.erl @@ -1858,7 +1858,9 @@ ssh_open(#options{host=Host,timeout=Timeout,port=Port,ssh=SshOpts,name=Name}) -> name = Name}}; failure -> ssh:close(CM), - {error,{ssh,could_not_execute_netconf_subsystem}} + {error,{ssh,could_not_execute_netconf_subsystem}}; + {error,timeout} -> + {error,{ssh,could_not_execute_netconf_subsystem,timeout}} end; {error, Reason} -> ssh:close(CM), diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 00d0aab507..4a12481214 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -293,10 +293,10 @@ script_start1(Parent, Args) -> application:set_env(common_test, auto_compile, true), InclDirs = case proplists:get_value(include, Args) of - Incl when is_list(hd(Incl)) -> - Incl; + Incls when is_list(hd(Incls)) -> + [filename:absname(IDir) || IDir <- Incls]; Incl when is_list(Incl) -> - [Incl]; + [filename:absname(Incl)]; undefined -> [] end, @@ -774,7 +774,8 @@ script_usage() -> "\n\t[-basic_html]\n\n"), io:format("Run tests from command line:\n\n" "\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |" - "\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]" + "\n\t[[-dir TestDir] -suite Suite1 Suite2 .. SuiteN" + "\n\t [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]]" "\n\t[-step [config | keep_inactive]]" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" "\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]" @@ -1023,10 +1024,10 @@ run_test2(StartOpts) -> case proplists:get_value(include, StartOpts) of undefined -> []; - Incl when is_list(hd(Incl)) -> - Incl; + Incls when is_list(hd(Incls)) -> + [filename:absname(IDir) || IDir <- Incls]; Incl when is_list(Incl) -> - [Incl] + [filename:absname(Incl)] end, case os:getenv("CT_INCLUDE_PATH") of false -> @@ -1393,6 +1394,7 @@ run_testspec2(TestSpec) -> EnvInclude++Opts#opts.include end, application:set_env(common_test, include, AllInclude), + LogDir1 = which(logdir,Opts#opts.logdir), case check_and_install_configfiles( Opts#opts.config, LogDir1, Opts) of @@ -2134,6 +2136,14 @@ do_run_test(Tests, Skip, Opts0) -> case check_and_add(Tests, [], []) of {ok,AddedToPath} -> ct_util:set_testdata({stats,{0,0,{0,0}}}), + + %% test_server needs to know the include path too + InclPath = case application:get_env(common_test, include) of + {ok,Incls} -> Incls; + _ -> [] + end, + application:set_env(test_server, include, InclPath), + test_server_ctrl:start_link(local), %% let test_server expand the test tuples and count no of cases diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl index 3b2652d06c..4e03bf8630 100644 --- a/lib/common_test/src/ct_telnet.erl +++ b/lib/common_test/src/ct_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2014. 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 @@ -141,7 +141,8 @@ -export([open/1, open/2, open/3, open/4, close/1]). -export([cmd/2, cmd/3, cmdf/3, cmdf/4, get_data/1, - send/2, sendf/3, expect/2, expect/3]). + send/2, send/3, sendf/3, sendf/4, + expect/2, expect/3]). %% Callbacks -export([init/3,handle_msg/2,reconnect/2,terminate/2]). @@ -304,42 +305,74 @@ close(Connection) -> %%% Test suite interface %%%----------------------------------------------------------------- %%% @spec cmd(Connection,Cmd) -> {ok,Data} | {error,Reason} -%%% @equiv cmd(Connection,Cmd,DefaultTimeout) +%%% @equiv cmd(Connection,Cmd,[]) cmd(Connection,Cmd) -> - cmd(Connection,Cmd,default). + cmd(Connection,Cmd,[]). %%%----------------------------------------------------------------- -%%% @spec cmd(Connection,Cmd,Timeout) -> {ok,Data} | {error,Reason} +%%% @spec cmd(Connection,Cmd,Opts) -> {ok,Data} | {error,Reason} %%% Connection = ct_telnet:connection() %%% Cmd = string() -%%% Timeout = integer() +%%% Opts = [Opt] +%%% Opt = {timeout,timeout()} | {newline,boolean()} %%% Data = [string()] %%% Reason = term() %%% @doc Send a command via telnet and wait for prompt. -cmd(Connection,Cmd,Timeout) -> - case get_handle(Connection) of - {ok,Pid} -> - call(Pid,{cmd,Cmd,Timeout}); +%%% +%%% This function will by default add a newline to the end of the +%%% given command. If this is not desired, the option +%%% `{newline,false}' can be used. This is necessary, for example, +%%% when sending telnet command sequences (prefixed with the +%%% Interprete As Command, IAC, character). +%%% +%%% The option `timeout' specifies how long the client shall wait for +%%% prompt. If the time expires, the function returns +%%% `{error,timeout}'. See the module description for information +%%% about the default value for the command timeout. +cmd(Connection,Cmd,Opts) when is_list(Opts) -> + case check_cmd_opts(Opts) of + ok -> + case get_handle(Connection) of + {ok,Pid} -> + call(Pid,{cmd,Cmd,Opts}); + Error -> + Error + end; Error -> Error - end. + end; +cmd(Connection,Cmd,Timeout) when is_integer(Timeout); Timeout==default -> + %% This clause is kept for backwards compatibility only + cmd(Connection,Cmd,[{timeout,Timeout}]). + +check_cmd_opts([{timeout,Timeout}|Opts]) when is_integer(Timeout); + Timeout==default -> + check_cmd_opts(Opts); +check_cmd_opts([]) -> + ok; +check_cmd_opts(Opts) -> + check_send_opts(Opts). + %%%----------------------------------------------------------------- %%% @spec cmdf(Connection,CmdFormat,Args) -> {ok,Data} | {error,Reason} -%%% @equiv cmdf(Connection,CmdFormat,Args,DefaultTimeout) +%%% @equiv cmdf(Connection,CmdFormat,Args,[]) cmdf(Connection,CmdFormat,Args) -> - cmdf(Connection,CmdFormat,Args,default). + cmdf(Connection,CmdFormat,Args,[]). %%%----------------------------------------------------------------- -%%% @spec cmdf(Connection,CmdFormat,Args,Timeout) -> {ok,Data} | {error,Reason} +%%% @spec cmdf(Connection,CmdFormat,Args,Opts) -> {ok,Data} | {error,Reason} %%% Connection = ct_telnet:connection() %%% CmdFormat = string() %%% Args = list() -%%% Timeout = integer() +%%% Opts = [Opt] +%%% Opt = {timeout,timeout()} | {newline,boolean()} %%% Data = [string()] %%% Reason = term() %%% @doc Send a telnet command and wait for prompt %%% (uses a format string and list of arguments to build the command). -cmdf(Connection,CmdFormat,Args,Timeout) when is_list(Args) -> +%%% +%%% See {@link cmd/3} further description. +cmdf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), - cmd(Connection,Cmd,Timeout). + cmd(Connection,Cmd,Opts). %%%----------------------------------------------------------------- %%% @spec get_data(Connection) -> {ok,Data} | {error,Reason} @@ -358,32 +391,67 @@ get_data(Connection) -> %%%----------------------------------------------------------------- %%% @spec send(Connection,Cmd) -> ok | {error,Reason} +%%% @equiv send(Connection,Cmd,[]) +send(Connection,Cmd) -> + send(Connection,Cmd,[]). + +%%%----------------------------------------------------------------- +%%% @spec send(Connection,Cmd,Opts) -> ok | {error,Reason} %%% Connection = ct_telnet:connection() %%% Cmd = string() +%%% Opts = [Opt] +%%% Opt = {newline,boolean()} %%% Reason = term() %%% @doc Send a telnet command and return immediately. %%% +%%% This function will by default add a newline to the end of the +%%% given command. If this is not desired, the option +%%% `{newline,false}' can be used. This is necessary, for example, +%%% when sending telnet command sequences (prefixed with the +%%% Interprete As Command, IAC, character). +%%% %%% <p>The resulting output from the command can be read with %%% <code>get_data/1</code> or <code>expect/2/3</code>.</p> -send(Connection,Cmd) -> - case get_handle(Connection) of - {ok,Pid} -> - call(Pid,{send,Cmd}); +send(Connection,Cmd,Opts) -> + case check_send_opts(Opts) of + ok -> + case get_handle(Connection) of + {ok,Pid} -> + call(Pid,{send,Cmd,Opts}); + Error -> + Error + end; Error -> Error end. +check_send_opts([{newline,Bool}|Opts]) when is_boolean(Bool) -> + check_send_opts(Opts); +check_send_opts([Invalid|_]) -> + {error,{invalid_option,Invalid}}; +check_send_opts([]) -> + ok. + + %%%----------------------------------------------------------------- %%% @spec sendf(Connection,CmdFormat,Args) -> ok | {error,Reason} +%%% @equiv sendf(Connection,CmdFormat,Args,[]) +sendf(Connection,CmdFormat,Args) when is_list(Args) -> + sendf(Connection,CmdFormat,Args,[]). + +%%%----------------------------------------------------------------- +%%% @spec sendf(Connection,CmdFormat,Args,Opts) -> ok | {error,Reason} %%% Connection = ct_telnet:connection() %%% CmdFormat = string() %%% Args = list() +%%% Opts = [Opt] +%%% Opt = {newline,boolean()} %%% Reason = term() %%% @doc Send a telnet command and return immediately (uses a format %%% string and a list of arguments to build the command). -sendf(Connection,CmdFormat,Args) when is_list(Args) -> +sendf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), - send(Connection,Cmd). + send(Connection,Cmd,Opts). %%%----------------------------------------------------------------- %%% @spec expect(Connection,Patterns) -> term() @@ -559,7 +627,7 @@ set_telnet_defaults([],S) -> S. %% @hidden -handle_msg({cmd,Cmd,Timeout},State) -> +handle_msg({cmd,Cmd,Opts},State) -> start_gen_log(heading(cmd,State#state.name)), log(State,cmd,"Cmd: ~p",[Cmd]), @@ -584,11 +652,14 @@ handle_msg({cmd,Cmd,Timeout},State) -> {ip,true} -> ok end, - TO = if Timeout == default -> State#state.com_to; - true -> Timeout + TO = case proplists:get_value(timeout,Opts,default) of + default -> State#state.com_to; + Timeout -> Timeout end, + Newline = proplists:get_value(newline,Opts,true), {Return,NewBuffer,Prompt} = - case teln_cmd(State#state.teln_pid, Cmd, State#state.prx, TO) of + case teln_cmd(State#state.teln_pid, Cmd, State#state.prx, + Newline, TO) of {ok,Data,_PromptType,Rest} -> log(State,recv,"Return: ~p",[{ok,Data}]), {{ok,Data},Rest,true}; @@ -597,13 +668,13 @@ handle_msg({cmd,Cmd,Timeout},State) -> {State#state.name, State#state.type}, State#state.teln_pid, - {cmd,Cmd,TO}}}, + {cmd,Cmd,Opts}}}, log(State,recv,"Return: ~p",[Error]), {Retry,[],false} end, end_gen_log(), {Return,State#state{buffer=NewBuffer,prompt=Prompt}}; -handle_msg({send,Cmd},State) -> +handle_msg({send,Cmd,Opts},State) -> start_gen_log(heading(send,State#state.name)), log(State,send,"Sending: ~p",[Cmd]), @@ -628,7 +699,8 @@ handle_msg({send,Cmd},State) -> {ip,true} -> ok end, - ct_telnet_client:send_data(State#state.teln_pid,Cmd), + Newline = proplists:get_value(newline,Opts,true), + ct_telnet_client:send_data(State#state.teln_pid,Cmd,Newline), end_gen_log(), {ok,State#state{buffer=[],prompt=false}}; handle_msg(get_data,State) -> @@ -868,8 +940,8 @@ format_data(_How,{String,Args}) -> %%%================================================================= %%% Abstraction layer on top of ct_telnet_client.erl -teln_cmd(Pid,Cmd,Prx,Timeout) -> - ct_telnet_client:send_data(Pid,Cmd), +teln_cmd(Pid,Cmd,Prx,Newline,Timeout) -> + ct_telnet_client:send_data(Pid,Cmd,Newline), teln_receive_until_prompt(Pid,Prx,Timeout). teln_get_all_data(Pid,Prx,Data,Acc,LastLine) -> @@ -1050,7 +1122,8 @@ teln_expect1(Name,Pid,Data,Pattern,Acc,EO=#eo{idle_timeout=IdleTO, NotFinished -> %% Get more data Fun = fun() -> get_data1(EO#eo.teln_pid) end, - case timer:tc(ct_gen_conn, do_within_time, [Fun, IdleTO]) of + BreakAfter = if TotalTO < IdleTO -> TotalTO; true -> IdleTO end, + case timer:tc(ct_gen_conn, do_within_time, [Fun, BreakAfter]) of {_,{error,Reason}} -> %% A timeout will occur when the telnet connection %% is idle for EO#eo.idle_timeout milliseconds. diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl index ce30dcb74b..36d33522a3 100644 --- a/lib/common_test/src/ct_telnet_client.erl +++ b/lib/common_test/src/ct_telnet_client.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2014. 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 @@ -35,7 +35,7 @@ %% -define(debug, true). -export([open/2, open/3, open/4, open/5, close/1]). --export([send_data/2, get_data/1]). +-export([send_data/2, send_data/3, get_data/1]). -define(TELNET_PORT, 23). -define(OPEN_TIMEOUT,10000). @@ -97,7 +97,11 @@ close(Pid) -> end. send_data(Pid, Data) -> - Pid ! {send_data, Data++"\n"}, + send_data(Pid, Data, true). +send_data(Pid, Data, true) -> + send_data(Pid, Data++"\n", false); +send_data(Pid, Data, false) -> + Pid ! {send_data, Data}, ok. get_data(Pid) -> @@ -246,7 +250,13 @@ wait(false, _) -> infinity. send(Data, Sock, ConnName) -> case Data of [?IAC|_] = Cmd -> - cmd_dbg(Cmd); + cmd_dbg("Sending",Cmd), + try io_lib:format("[~w] ~w", [?MODULE,Data]) of + Str -> + ct_telnet:log(ConnName, general_io, Str, []) + catch + _:_ -> ok + end; _ -> dbg("Sending: ~tp\n", [Data]), try io_lib:format("[~w] ~ts", [?MODULE,Data]) of @@ -267,8 +277,7 @@ check_msg(Sock, [?IAC,?IAC | T], Acc) -> check_msg(Sock, [?IAC | Cs], Acc) -> case get_cmd(Cs) of {Cmd,Cs1} -> - dbg("Got ", []), - cmd_dbg(Cmd), + cmd_dbg("Got",Cmd), respond_cmd(Cmd, Sock), check_msg(Sock, Cs1, Acc); error -> @@ -287,12 +296,12 @@ check_msg(_Sock, [], Acc) -> respond_cmd([?WILL,?ECHO], Sock) -> R = [?IAC,?DO,?ECHO], - cmd_dbg(R), + cmd_dbg("Responding",R), gen_tcp:send(Sock, R); respond_cmd([?DO,?ECHO], Sock) -> R = [?IAC,?WILL,?ECHO], - cmd_dbg(R), + cmd_dbg("Responding",R), gen_tcp:send(Sock, R); %% Answers from server @@ -312,12 +321,12 @@ respond_cmd([?WONT | _Opt], _Sock) -> % server ack? respond_cmd([?WILL,Opt], Sock) -> R = [?IAC,?DONT,Opt], - cmd_dbg(R), + cmd_dbg("Responding",R), gen_tcp:send(Sock, R); respond_cmd([?DO | Opt], Sock) -> R = [?IAC,?WONT | Opt], - cmd_dbg(R), + cmd_dbg("Responding",R), gen_tcp:send(Sock, R); %% Commands without options (which we ignore) @@ -353,13 +362,14 @@ get_subcmd([Opt | Rest], Acc) -> get_subcmd(Rest, [Opt | Acc]). -ifdef(debug). -dbg(_Str,_Args) -> - io:format(_Str,_Args). +dbg(Str,Args) -> + TS = timestamp(), + io:format("[~p ct_telnet_client, ~s]\n" ++ Str,[self(),TS|Args]). -cmd_dbg(_Cmd) -> - case _Cmd of +cmd_dbg(Prefix,Cmd) -> + case Cmd of [?IAC|Cmd1] -> - cmd_dbg(Cmd1); + cmd_dbg(Prefix,Cmd1); [Ctrl|Opts] -> CtrlStr = case Ctrl of @@ -375,15 +385,23 @@ cmd_dbg(_Cmd) -> [Opt] -> Opt; _ -> Opts end, - io:format("~ts(~w): ~w\n", [CtrlStr,Ctrl,Opts1]); + dbg("~ts: ~ts(~w): ~w\n", [Prefix,CtrlStr,Ctrl,Opts1]); Any -> - io:format("Unexpected in cmd_dbg:~n~w~n",[Any]) + dbg("Unexpected in cmd_dbg:~n~w~n",[Any]) end. +timestamp() -> + {MS,S,US} = now(), + {{Year,Month,Day}, {Hour,Min,Sec}} = + calendar:now_to_local_time({MS,S,US}), + MilliSec = trunc(US/1000), + lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B " + "~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B", + [Year,Month,Day,Hour,Min,Sec,MilliSec])). -else. dbg(_Str,_Args) -> ok. -cmd_dbg(_Cmd) -> +cmd_dbg(_Prefix,_Cmd) -> ok. -endif. diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl index 10666b979d..09b6fd1510 100644 --- a/lib/common_test/src/unix_telnet.erl +++ b/lib/common_test/src/unix_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -122,7 +122,7 @@ connect1(Name,Ip,Port,Timeout,KeepAlive,Username,Password) -> ok = ct_telnet_client:send_data(Pid,Password), Stars = lists:duplicate(length(Password),$*), log(Name,send,"Password: ~s",[Stars]), - ok = ct_telnet_client:send_data(Pid,""), +% ok = ct_telnet_client:send_data(Pid,""), case ct_telnet:silent_teln_expect(Name,Pid,[], prompt, ?prx,[]) of diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl index 87ba4ae1b9..1dab425509 100644 --- a/lib/common_test/test/ct_cover_SUITE.erl +++ b/lib/common_test/test/ct_cover_SUITE.erl @@ -77,7 +77,11 @@ all() -> ct_cover_add_remove_nodes, otp_9956, cross, - export_import + export_import, + relative_incl_dirs, + absolute_incl_dirs, + relative_excl_dirs, + absolute_excl_dirs ]. %%-------------------------------------------------------------------- @@ -215,6 +219,45 @@ export_import(Config) -> check_calls(Events2,2), ok. +relative_incl_dirs(Config) -> + false = check_cover(Config), + RelDir = rel_path(?config(priv_dir, Config), ?config(data_dir, Config)), + CoverSpec = [{incl_dirs, [RelDir]}], + CoverFile = create_cover_file(rel_incl_dirs, CoverSpec, Config), + Opts = [{cover, CoverFile}], + {ok, Events} = run_test(rel_incl_dirs, default, Opts, Config), + check_calls(Events, 1), + ok. + +absolute_incl_dirs(Config) -> + false = check_cover(Config), + CoverSpec = [{incl_dirs, [?config(data_dir, Config)]}], + CoverFile = create_cover_file(abs_incl_dirs, CoverSpec, Config), + Opts = [{cover, CoverFile}], + {ok, Events} = run_test(abs_incl_dirs, default, Opts, Config), + check_calls(Events, 1), + ok. + +relative_excl_dirs(Config) -> + false = check_cover(Config), + RelDir = rel_path(?config(priv_dir, Config), ?config(data_dir, Config)), + CoverSpec = default_cover_file_content() ++ [{excl_dirs, [RelDir]}], + CoverFile = create_cover_file(rel_excl_dirs, CoverSpec, Config), + Opts = [{cover, CoverFile}], + {ok, Events} = run_test(rel_excl_dirs, default_no_cover, Opts, Config), + check_no_cover_compiled(Events), + ok. + +absolute_excl_dirs(Config) -> + false = check_cover(Config), + AbsDir = ?config(data_dir, Config), + CoverSpec = default_cover_file_content() ++ [{excl_dirs, [AbsDir]}], + CoverFile = create_cover_file(abs_excl_dirs, CoverSpec, Config), + Opts = [{cover, CoverFile}], + {ok, Events} = run_test(abs_excl_dirs, default_no_cover, Opts, Config), + check_no_cover_compiled(Events), + ok. + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS %%%----------------------------------------------------------------- @@ -288,23 +331,36 @@ get_log_dirs(Events) -> {ct_test_support_eh, {event,start_logging,_Node,LogDir}} <- Events]. +%% Check if a module was compiled without cover +check_no_cover_compiled(Events) -> + check_no_cover_compiled(Events, ?mod). +check_no_cover_compiled(Events, Mod) -> + [ {error, {not_cover_compiled, Mod}} = analyse_log(CoverLog, Mod) + || CoverLog <- cover_logs(Events) ]. + %% Check that each coverlog includes N calls to ?mod:foo/0 check_calls(Events,N) -> check_calls(Events,{?mod,foo,0},N). check_calls(Events,MFA,N) -> - CoverLogs = [filename:join(D,"all.coverdata") || D <- get_log_dirs(Events)], - do_check_logs(CoverLogs,MFA,N). + do_check_logs(cover_logs(Events),MFA,N). do_check_logs([CoverLog|CoverLogs],{Mod,_,_} = MFA,N) -> - {ok,_} = cover:start(), - ok = cover:import(CoverLog), - {ok,Calls} = cover:analyse(Mod,calls,function), - ok = cover:stop(), + {ok, Calls} = analyse_log(CoverLog, Mod), {MFA,N} = lists:keyfind(MFA,1,Calls), do_check_logs(CoverLogs,MFA,N); do_check_logs([],_,_) -> ok. +cover_logs(Events) -> + [filename:join(D,"all.coverdata") || D <- get_log_dirs(Events)]. + +analyse_log(CoverLog, Mod) -> + {ok, _} = cover:start(), + ok = cover:import(CoverLog), + Result = cover:analyse(Mod, calls, function), + ok = cover:stop(), + Result. + fullname(Name) -> {ok,Host} = inet:gethostname(), list_to_atom(atom_to_list(Name) ++ "@" ++ Host). @@ -333,3 +389,12 @@ start_slave(Name,Args) -> {boot_timeout,10}, % extending some timers for slow test hosts {init_timeout,10}, {startup_timeout,10}]). + +rel_path(From, To) -> + Segments = do_rel_path(filename:split(From), filename:split(To)), + filename:join(Segments). + +do_rel_path([Seg|RestA], [Seg|RestB]) -> + do_rel_path(RestA, RestB); +do_rel_path(PathA, PathB) -> + lists:duplicate(length(PathA), "..") ++ PathB. diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl index 83d368c53d..789e48bd96 100644 --- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl +++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl @@ -71,6 +71,10 @@ default(_Config) -> cover_test_mod:foo(), ok. +default_no_cover(_Config) -> + cover_test_mod:foo(), + ok. + slave(_Config) -> cover_compiled = code:which(cover_test_mod), cover_test_mod:foo(), diff --git a/lib/common_test/test/ct_event_handler_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE.erl index b534a7141d..30a5e650fe 100644 --- a/lib/common_test/test/ct_event_handler_SUITE.erl +++ b/lib/common_test/test/ct_event_handler_SUITE.erl @@ -156,18 +156,21 @@ results(Config) when is_list(Config) -> TestEvents = [{eh_A,start_logging,{'DEF','RUNDIR'}}, {eh_A,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, - {eh_A,start_info,{1,1,3}}, + {eh_A,start_info,{1,1,4}}, {eh_A,tc_start,{eh_11_SUITE,init_per_suite}}, {eh_A,tc_done,{eh_11_SUITE,init_per_suite,ok}}, {eh_A,tc_start,{eh_11_SUITE,tc1}}, {eh_A,tc_done,{eh_11_SUITE,tc1,ok}}, {eh_A,test_stats,{1,0,{0,0}}}, {eh_A,tc_start,{eh_11_SUITE,tc2}}, - {eh_A,tc_done,{eh_11_SUITE,tc2,{skipped,"Skipped"}}}, + {eh_A,tc_done,{eh_11_SUITE,tc2,{skipped,"Skip"}}}, {eh_A,test_stats,{1,0,{1,0}}}, {eh_A,tc_start,{eh_11_SUITE,tc3}}, - {eh_A,tc_done,{eh_11_SUITE,tc3,{failed,{error,'Failing'}}}}, - {eh_A,test_stats,{1,1,{1,0}}}, + {eh_A,tc_done,{eh_11_SUITE,tc3,{skipped,"Skipped"}}}, + {eh_A,test_stats,{1,0,{2,0}}}, + {eh_A,tc_start,{eh_11_SUITE,tc4}}, + {eh_A,tc_done,{eh_11_SUITE,tc4,{failed,{error,'Failing'}}}}, + {eh_A,test_stats,{1,1,{2,0}}}, {eh_A,tc_start,{eh_11_SUITE,end_per_suite}}, {eh_A,tc_done,{eh_11_SUITE,end_per_suite,ok}}, {eh_A,test_done,{'DEF','STOP_TIME'}}, diff --git a/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl index 16b7129993..a52fe96f30 100644 --- a/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl +++ b/lib/common_test/test/ct_event_handler_SUITE_data/event_handling_1/test/eh_11_SUITE.erl @@ -124,7 +124,7 @@ end_per_testcase(_TestCase, _Config) -> %% Description: Returns the list of test cases that are to be executed. %%-------------------------------------------------------------------- all() -> - [tc1, tc2, tc3]. + [tc1, tc2, tc3, tc4]. %%-------------------------------------------------------------------- @@ -135,7 +135,10 @@ tc1(_Config) -> ok. tc2(_Config) -> - {skip,"Skipped"}. + {skip,"Skip"}. -tc3(_Config) -> +tc3(_Config) -> + {skipped,"Skipped"}. + +tc4(_Config) -> exit('Failing'). diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index c8fc4bd59b..d5ad8312e6 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -1075,7 +1075,37 @@ test_events(fail_n_skip_with_minimal_cth) -> {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, {?eh,cth,{'_',init,['_',[]]}}, {?eh,tc_start,{'_',init_per_suite}}, - + + {parallel, + [{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{init_per_group, + group1,[parallel]}}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{init_per_group, + group1,[parallel]},ok}}, + {parallel, + [{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{init_per_group, + group2,[parallel]}}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{init_per_group, + group2,[parallel]},ok}}, + %% Verify that 'skip' as well as 'skipped' works + {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,test_case2}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case2,{skipped,"skip it"}}}, + {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,test_case3}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case3,{skipped,"skip it"}}}, + {?eh,cth,{empty_cth,on_tc_skip,[{test_case2,group2}, + {tc_user_skip,{skipped,"skip it"}}, + []]}}, + {?eh,cth,{empty_cth,on_tc_skip,[{test_case3,group2}, + {tc_user_skip,{skipped,"skip it"}}, + []]}}, + {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{end_per_group, + group2,[parallel]}}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,group2, + [parallel]},ok}}]}, + {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{end_per_group, + group1,[parallel]}}}, + {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{end_per_group, + group1,[parallel]},ok}}]}, + {?eh,tc_done,{'_',end_per_suite,ok}}, {?eh,cth,{'_',terminate,[[]]}}, {?eh,stop_logging,[]} diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl index b2f22d8257..7b84c246ca 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl @@ -41,6 +41,8 @@ end_per_group(_Group,_Config) -> init_per_testcase(test_case2, Config) ->
{skip,"skip it"};
+init_per_testcase(test_case3, Config) ->
+ {skipped,"skip it"};
init_per_testcase(_TestCase, Config) ->
Config.
@@ -48,7 +50,9 @@ end_per_testcase(_TestCase, _Config) -> ok.
groups() ->
- [{group1,[parallel],[{group2,[parallel],[test_case1,test_case2,test_case3]}]}].
+ [{group1,[parallel],
+ [{group2,[parallel],
+ [test_case1,test_case2,test_case3,test_case4]}]}].
all() ->
[{group,group1}].
@@ -62,3 +66,6 @@ test_case2(Config) -> test_case3(Config) ->
ok.
+
+test_case4(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl index 6caac7e447..77783fccf5 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl @@ -75,6 +75,7 @@ init(Id, Opts) -> gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, init, [Id, Opts]}}), + ct:log("~w:init called", [?MODULE]), {ok,Opts}. %% @doc The ID is used to uniquly identify an CTH instance, if two CTH's @@ -85,6 +86,7 @@ init(Id, Opts) -> id(Opts) -> gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, id, [Opts]}}), + ct:log("~w:id called", [?MODULE]), now(). %% @doc Called before init_per_suite is called. Note that this callback is @@ -100,6 +102,7 @@ pre_init_per_suite(Suite,Config,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, pre_init_per_suite, [Suite,Config,State]}}), + ct:log("~w:pre_init_per_suite(~w) called", [?MODULE,Suite]), {Config, State}. %% @doc Called after init_per_suite. @@ -114,6 +117,7 @@ post_init_per_suite(Suite,Config,Return,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, post_init_per_suite, [Suite,Config,Return,State]}}), + ct:log("~w:post_init_per_suite(~w) called", [?MODULE,Suite]), {Return, State}. %% @doc Called before end_per_suite. The config/state can be changed here, @@ -127,6 +131,7 @@ pre_end_per_suite(Suite,Config,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, pre_end_per_suite, [Suite,Config,State]}}), + ct:log("~w:pre_end_per_suite(~w) called", [?MODULE,Suite]), {Config, State}. %% @doc Called after end_per_suite. Note that the config cannot be @@ -141,6 +146,7 @@ post_end_per_suite(Suite,Config,Return,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, post_end_per_suite, [Suite,Config,Return,State]}}), + ct:log("~w:post_end_per_suite(~w) called", [?MODULE,Suite]), {Return, State}. %% @doc Called before each init_per_group. @@ -154,6 +160,7 @@ pre_init_per_group(Group,Config,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, pre_init_per_group, [Group,Config,State]}}), + ct:log("~w:pre_init_per_group(~w) called", [?MODULE,Group]), {Config, State}. %% @doc Called after each init_per_group. @@ -168,6 +175,7 @@ post_init_per_group(Group,Config,Return,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, post_init_per_group, [Group,Config,Return,State]}}), + ct:log("~w:post_init_per_group(~w) called", [?MODULE,Group]), {Return, State}. %% @doc Called after each end_per_group. The config/state can be changed here, @@ -181,6 +189,7 @@ pre_end_per_group(Group,Config,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, pre_end_per_group, [Group,Config,State]}}), + ct:log("~w:pre_end_per_group(~w) called", [?MODULE,Group]), {Config, State}. %% @doc Called after each end_per_group. Note that the config cannot be @@ -195,6 +204,7 @@ post_end_per_group(Group,Config,Return,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, post_end_per_group, [Group,Config,Return,State]}}), + ct:log("~w:post_end_per_group(~w) called", [?MODULE,Group]), {Return, State}. %% @doc Called before each test case. @@ -208,6 +218,7 @@ pre_init_per_testcase(TC,Config,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, pre_init_per_testcase, [TC,Config,State]}}), + ct:log("~w:pre_init_per_testcase(~w) called", [?MODULE,TC]), {Config, State}. %% @doc Called after each test case. Note that the config cannot be @@ -222,6 +233,7 @@ post_end_per_testcase(TC,Config,Return,State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, post_end_per_testcase, [TC,Config,Return,State]}}), + ct:log("~w:post_end_per_testcase(~w) called", [?MODULE,TC]), {Return, State}. %% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, @@ -237,6 +249,7 @@ on_tc_fail(TC, Reason, State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, on_tc_fail, [TC,Reason,State]}}), + ct:log("~w:on_tc_fail(~w) called", [?MODULE,TC]), State. %% @doc Called when a test case is skipped by either user action @@ -253,6 +266,7 @@ on_tc_skip(TC, Reason, State) -> ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, on_tc_skip, [TC,Reason,State]}}), + ct:log("~w:on_tc_skip(~w) called", [?MODULE,TC]), State. %% @doc Called when the scope of the CTH is done, this depends on @@ -274,4 +288,5 @@ terminate(State) -> gen_event:notify( ?CT_EVMGR_REF, #event{ name = cth, node = node(), data = {?MODULE, terminate, [State]}}), + ct:log("~w:terminate called", [?MODULE]), ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl index 30721a6b3a..436470f46d 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl @@ -28,10 +28,14 @@ %% CT Hooks
-export([init/2]).
-export([terminate/1]).
+-export([on_tc_skip/3]).
init(Id, Opts) ->
empty_cth:init(Id, Opts).
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl index 80616af064..3885c1991d 100644 --- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl @@ -20,7 +20,7 @@ suite() -> [ operations() -> [start_stop, send_and_get, expect, already_closed, - cmd, sendf, close_wrong_type]. + cmd, sendf, no_newline, close_wrong_type]. mult_case(_Case, 0) -> []; @@ -129,6 +129,16 @@ sendf(Config) -> ok = ct_telnet:close(Handle), ok. +no_newline(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), + IAC = 255, % interprete as command + AYT = 246, % are you there + ok = ct_telnet:send(Handle, [IAC,AYT], [{newline,false}]), + {ok,_} = ct_telnet:expect(Handle,"yes",[no_prompt_check]), + {ok,_} = ct_telnet:cmd(Handle, ""), % send newline only to get back prompt + ok = ct_telnet:close(Handle), + ok. + close_wrong_type(_) -> {error, _} = ct_telnet:close(whatever), ok. diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl index c0f79d0f10..bd5d76266a 100644 --- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl @@ -4,6 +4,26 @@ -include_lib("common_test/include/ct.hrl"). +%% telnet control characters +-define(SE, 240). +-define(NOP, 241). +-define(DM, 242). +-define(BRK, 243). +-define(IP, 244). +-define(AO, 245). +-define(AYT, 246). +-define(EC, 247). +-define(EL, 248). +-define(GA, 249). +-define(SB, 250). +-define(WILL, 251). +-define(WONT, 252). +-define(DO, 253). +-define(DONT, 254). +-define(IAC, 255). + +-define(SHORT_TIME,2000). + %%-------------------------------------------------------------------- %% TEST SERVER CALLBACK FUNCTIONS %%-------------------------------------------------------------------- @@ -24,6 +44,7 @@ all() -> expect_error_timeout1, expect_error_timeout2, expect_error_timeout3, + total_timeout_less_than_idle, no_prompt_check, no_prompt_check_repeat, no_prompt_check_sequence, @@ -34,7 +55,9 @@ all() -> ignore_prompt_timeout, large_string, server_speaks, - server_disconnects + server_disconnects, + newline_ayt, + newline_break ]. groups() -> @@ -95,7 +118,7 @@ expect_error_prompt(_) -> expect_error_timeout1(_) -> {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_no_prompt xxx"), - {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [{timeout,1000}]), + {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [{timeout,?SHORT_TIME}]), ok = ct_telnet:close(Handle), ok. @@ -112,9 +135,32 @@ expect_error_timeout2(_) -> expect_error_timeout3(_) -> {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_loop 5000 xxx"), + + T0 = now(), {error,timeout} = ct_telnet:expect(Handle, ["yyy"], [{idle_timeout,infinity}, - {total_timeout,3000}]), + {total_timeout,2001}]), + Diff = trunc(timer:now_diff(now(),T0)/1000), + {_,true} = {Diff, (Diff >= 2000) and (Diff =< 4000)}, + + ok = ct_telnet:send(Handle, "echo ayt"), + {ok,["ayt"]} = ct_telnet:expect(Handle, ["ayt"]), + ok = ct_telnet:close(Handle), + ok. + +%% OTP-12335: If total_timeout < idle_timeout, expect will never timeout +%% until after idle_timeout, which is incorrect. +total_timeout_less_than_idle(_) -> + {ok, Handle} = ct_telnet:open(telnet_server_conn1), + ok = ct_telnet:send(Handle, "echo_no_prompt xxx"), + + T0 = now(), + {error,timeout} = ct_telnet:expect(Handle, ["yyy"], + [{idle_timeout,5000}, + {total_timeout,2001}]), + Diff = trunc(timer:now_diff(now(),T0)/1000), + {_,true} = {Diff, (Diff >= 2000) and (Diff =< 4000)}, + ok = ct_telnet:send(Handle, "echo ayt"), {ok,["ayt"]} = ct_telnet:expect(Handle, ["ayt"]), ok = ct_telnet:close(Handle), @@ -158,16 +204,16 @@ ignore_prompt_timeout(_) -> {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx"), {error,timeout} = ct_telnet:expect(Handle, ["yyy"], [ignore_prompt, - {timeout,1000}]), + {timeout,?SHORT_TIME}]), ok = ct_telnet:send(Handle, "echo xxx"), % sends prompt and newline {ok,["xxx"]} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt, - {timeout,1000}]), + {timeout,?SHORT_TIME}]), ok = ct_telnet:send(Handle, "echo_no_prompt xxx\n"), % no prompt, but newline {ok,["xxx"]} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt, - {timeout,1000}]), + {timeout,?SHORT_TIME}]), ok = ct_telnet:send(Handle, "echo_no_prompt xxx"), % no prompt, no newline {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [ignore_prompt, - {timeout,1000}]), + {timeout,?SHORT_TIME}]), ok = ct_telnet:close(Handle), ok. @@ -213,7 +259,7 @@ no_prompt_check_timeout(_) -> {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx"), {error,timeout} = ct_telnet:expect(Handle, ["yyy"], [no_prompt_check, - {timeout,1000}]), + {timeout,?SHORT_TIME}]), ok = ct_telnet:close(Handle), ok. @@ -254,17 +300,31 @@ large_string(_) -> %% The server says things. Manually check that it gets printed correctly %% in the general IO log. +%% +%% In this test case we simulate data sent spontaneously from the +%% server. We use ct_telnet_client:send_data instead of ct_telnet:send +%% to avoid flushing of buffers in the client, and we use +%% echo_no_prompt since the server would normally not send a prompt in +%% this case. server_speaks(_) -> {ok, Handle} = ct_telnet:open(telnet_server_conn1), - ok = ct_telnet:send(Handle, "echo_no_prompt This is the first message\r\n"), - ok = ct_telnet:send(Handle, "echo_no_prompt This is the second message\r\n"), - %% let ct_telnet_client get an idle timeout + + Backdoor = ct_gen_conn:get_conn_pid(Handle), + ok = ct_telnet_client:send_data(Backdoor, + "echo_no_prompt This is the first message"), + ok = ct_telnet_client:send_data(Backdoor, + "echo_no_prompt This is the second message"), + %% Let ct_telnet_client get an idle timeout. This should print the + %% two messages to the log. Note that the buffers are not flushed here! timer:sleep(15000), - ok = ct_telnet:send(Handle, "echo_no_prompt This is the third message\r\n"), - {ok,_} = ct_telnet:expect(Handle, ["the"], [no_prompt_check]), + ok = ct_telnet_client:send_data(Backdoor, + "echo_no_prompt This is the third message"), + {ok,_} = ct_telnet:expect(Handle, ["first.*second.*third"], + [no_prompt_check, sequence]), {error,timeout} = ct_telnet:expect(Handle, ["the"], [no_prompt_check, - {timeout,1000}]), - ok = ct_telnet:send(Handle, "echo_no_prompt This is the fourth message\r\n"), + {timeout,?SHORT_TIME}]), + ok = ct_telnet_client:send_data(Backdoor, + "echo_no_prompt This is the fourth message"), %% give the server time to respond timer:sleep(2000), %% closing the connection should print last message in log @@ -279,9 +339,28 @@ server_disconnects(_) -> %% wait until the get_data operation (triggered by send/2) times out %% before sending the msg timer:sleep(500), - ok = ct_telnet:send(Handle, "echo_no_prompt This is the message\r\n"), + ok = ct_telnet:send(Handle, "echo_no_prompt This is the message"), %% when the server closes the connection, the last message should be %% printed in the log timer:sleep(3000), _ = ct_telnet:close(Handle), ok. + +%% Test option {newline,false} to send telnet command sequence. +newline_ayt(_) -> + {ok, Handle} = ct_telnet:open(telnet_server_conn1), + ok = ct_telnet:send(Handle, [?IAC,?AYT], [{newline,false}]), + {ok,["yes"]} = ct_telnet:expect(Handle, ["yes"]), + ok = ct_telnet:close(Handle), + ok. + +%% Test option {newline,false} to send telnet command sequence. +newline_break(_) -> + {ok, Handle} = ct_telnet:open(telnet_server_conn1), + ok = ct_telnet:send(Handle, [?IAC,?BRK], [{newline,false}]), + %% '#' is the prompt in break mode + {ok,["# "]} = ct_telnet:expect(Handle, ["# "], [no_prompt_check]), + {ok,R} = ct_telnet:cmd(Handle, "q", [{newline,false}]), + "> " = lists:flatten(R), + ok = ct_telnet:close(Handle), + ok. diff --git a/lib/common_test/test/telnet_server.erl b/lib/common_test/test/telnet_server.erl index 1d341d6106..d25ee62d38 100644 --- a/lib/common_test/test/telnet_server.erl +++ b/lib/common_test/test/telnet_server.erl @@ -31,7 +31,8 @@ users, authorized=false, suppress_go_ahead=false, - buffer=[]}). + buffer=[], + break=false}). -type options() :: [{port,pos_integer()} | {users,users()}]. -type users() :: [{user(),password()}]. @@ -148,6 +149,9 @@ loop(State, N) -> stopped end. +handle_data(Cmd,#state{break=true}=State) -> + dbg("Server got data when in break mode: ~p~n",[Cmd]), + handle_break_cmd(Cmd,State); handle_data([?IAC|Cmd],State) -> dbg("Server got cmd: ~p~n",[Cmd]), handle_cmd(Cmd,State); @@ -171,24 +175,38 @@ handle_data(Data,State) -> {ok,State#state{buffer=[Data|State#state.buffer]}} end. -%% Add function clause below to handle new telnet commands (sent with -%% ?IAC from client - this is not possible to do from ct_telnet API, -%% but ct_telnet sends DONT SUPPRESS_GO_AHEAD) +%% Add function clause below to handle new telnet commands sent with +%% ?IAC from client. This can be done from ct_telnet:send or +%% ct_telnet:cmd if using the option {newline,false}. Also, ct_telnet +%% sends DONT SUPPRESS_GO_AHEAD. handle_cmd([?DO,?SUPPRESS_GO_AHEAD|T],State) -> send([?IAC,?WILL,?SUPPRESS_GO_AHEAD],State), - handle_cmd(T,State#state{suppress_go_ahead=true}); + handle_data(T,State#state{suppress_go_ahead=true}); handle_cmd([?DONT,?SUPPRESS_GO_AHEAD|T],State) -> send([?IAC,?WONT,?SUPPRESS_GO_AHEAD],State), - handle_cmd(T,State#state{suppress_go_ahead=false}); -handle_cmd([?IAC|T],State) -> - %% Multiple commands in one packet - handle_cmd(T,State); + handle_data(T,State#state{suppress_go_ahead=false}); +handle_cmd([?BRK|T],State) -> + %% Used when testing 'newline' option in ct_telnet:send and ct_telnet:cmd. + send("# ",State), + handle_data(T,State#state{break=true}); +handle_cmd([?AYT|T],State) -> + %% Used when testing 'newline' option in ct_telnet:send and ct_telnet:cmd. + send("yes\r\n> ",State), + handle_data(T,State); handle_cmd([_H|T],State) -> %% Not responding to this command handle_cmd(T,State); handle_cmd([],State) -> {ok,State}. +handle_break_cmd([$q|T],State) -> + %% Dummy cmd allowed in break mode - quit break mode + send("\r\n> ",State), + handle_data(T,State#state{break=false}); +handle_break_cmd([],State) -> + {ok,State}. + + %% Add function clause below to handle new text command (text entered %% from the telnet prompt) do_handle_data(Data,#state{authorized=false}=State) -> @@ -292,4 +310,14 @@ get_line([],_) -> dbg(_F) -> dbg(_F,[]). dbg(_F,_A) -> - io:format("[telnet_server] " ++ _F,_A). + TS = timestamp(), + io:format("[telnet_server, ~s]\n" ++ _F,[TS|_A]). + +timestamp() -> + {MS,S,US} = now(), + {{Year,Month,Day}, {Hour,Min,Sec}} = + calendar:now_to_local_time({MS,S,US}), + MilliSec = trunc(US/1000), + lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B " + "~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B", + [Year,Month,Day,Hour,Min,Sec,MilliSec])). diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index 00c0925b40..849edc15e1 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1 +1 @@ -COMMON_TEST_VSN = 1.8.2 +COMMON_TEST_VSN = 1.9 diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index d48a0a5599..84ebd2f210 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -31,6 +31,35 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 5.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Named funs with the same name and arity could get mixed + up with each other.</p> + <p> + Own Id: OTP-12262</p> + </item> + <item> + <p> + Coalesce map keys in dialyzer mode</p> + <p> + This fixes a regression introduced in commit + 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba The problem + occurred with compounded map keys compiled with dialyzer + option turned on, '+dialyzer'.</p> + <p> + Reported by: Ivan Uemlianin</p> + <p> + Own Id: OTP-12347</p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 5.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index 5a4621dc37..a452d30b61 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -126,44 +126,53 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) -> %% There was a reference to a boolean expression %% from inside a protected block (try/catch), to %% a boolean expression outside. - throw:protected_barrier -> + throw:protected_barrier -> failed; - %% The 'xor' operator was used. We currently don't - %% find it worthwile to translate 'xor' operators - %% (the code would be clumsy). - throw:'xor' -> + %% The 'xor' operator was used. We currently don't + %% find it worthwile to translate 'xor' operators + %% (the code would be clumsy). + throw:'xor' -> failed; - %% The block does not contain a boolean expression, - %% but only a call to a guard BIF. - %% For instance: ... when element(1, T) -> - throw:not_boolean_expr -> + %% The block does not contain a boolean expression, + %% but only a call to a guard BIF. + %% For instance: ... when element(1, T) -> + throw:not_boolean_expr -> failed; - %% The block contains a 'move' instruction that could - %% not be handled. - throw:move -> + %% The block contains a 'move' instruction that could + %% not be handled. + throw:move -> failed; - %% The optimization is not safe. (A register - %% used by the instructions following the - %% optimized code is either not assigned a - %% value at all or assigned a different value.) - throw:all_registers_not_killed -> + %% The optimization is not safe. (A register + %% used by the instructions following the + %% optimized code is either not assigned a + %% value at all or assigned a different value.) + throw:all_registers_not_killed -> failed; - throw:registers_used -> + throw:registers_used -> failed; - %% A protected block refered to the value - %% returned by another protected block, - %% probably because the Core Erlang code - %% used nested try/catches in the guard. - %% (v3_core never produces nested try/catches - %% in guards, so it must have been another - %% Core Erlang translator.) - throw:protected_violation -> + %% A protected block refered to the value + %% returned by another protected block, + %% probably because the Core Erlang code + %% used nested try/catches in the guard. + %% (v3_core never produces nested try/catches + %% in guards, so it must have been another + %% Core Erlang translator.) + throw:protected_violation -> + failed; + + %% Failed to work out the live registers for a GC + %% BIF. For example, if the number of live registers + %% needed to be 4 because {x,3} was a source register, + %% but {x,2} was not known to be initialized, this + %% exception would be thrown. + throw:gc_bif_alloc_failure -> failed + end end. @@ -665,10 +674,16 @@ put_reg_1(V, [], I) -> [{I,V}]. fetch_reg(V, [{I,V}|_]) -> {x,I}; fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs). -live_regs(Regs) -> - foldl(fun ({I,_}, _) -> - I - end, -1, Regs)+1. +live_regs([{_,reserved}|_]) -> + %% We are not sure that this register is initialized, so we must + %% abort the optimization. + throw(gc_bif_alloc_failure); +live_regs([{I,_}]) -> + I+1; +live_regs([{_,_}|Regs]) -> + live_regs(Regs); +live_regs([]) -> + 0. %%% diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl index 2792fd8fa5..0d95971f91 100644 --- a/lib/compiler/src/core_lib.erl +++ b/lib/compiler/src/core_lib.erl @@ -212,6 +212,8 @@ vu_pattern(V, #c_tuple{es=Es}, St) -> vu_pattern_list(V, Es, St); vu_pattern(V, #c_binary{segments=Ss}, St) -> vu_pat_seg_list(V, Ss, St); +vu_pattern(V, #c_map{es=Es}, St) -> + vu_map_pairs(V, Es, St); vu_pattern(V, #c_alias{var=Var,pat=P}, St0) -> case vu_pattern(V, Var, St0) of {true,_}=St1 -> St1; @@ -234,6 +236,13 @@ vu_pat_seg_list(V, Ss, St) -> end end, St, Ss). +vu_map_pairs(V, [#c_map_pair{val=Pat}|T], St0) -> + case vu_pattern(V, Pat, St0) of + {true,_}=St -> St; + St -> vu_map_pairs(V, T, St) + end; +vu_map_pairs(_, [], St) -> St. + -spec vu_var_list(cerl:var_name(), [cerl:c_var()]) -> boolean(). vu_var_list(V, Vs) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 82817a987a..ed8f609082 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1229,6 +1229,11 @@ is_non_numeric([H|T]) -> is_non_numeric(H) andalso is_non_numeric(T); is_non_numeric(Tuple) when is_tuple(Tuple) -> is_non_numeric_tuple(Tuple, tuple_size(Tuple)); +is_non_numeric(Map) when is_map(Map) -> + %% Note that 17.x and 18.x compare keys in different ways. + %% Be very conservative -- require that both keys and values + %% are non-numeric. + is_non_numeric(maps:to_list(Map)); is_non_numeric(Num) when is_number(Num) -> false; is_non_numeric(_) -> true. @@ -1338,9 +1343,12 @@ eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types) {ok,#c_tuple{es=Elements}} -> if 1 =< Pos, Pos =< length(Elements) -> - case lists:nth(Pos, Elements) of - #c_alias{var=Alias} -> Alias; - Res -> Res + El = lists:nth(Pos, Elements), + try + pat_to_expr(El) + catch + throw:impossible -> + Call end; true -> eval_failure(Call, badarg) @@ -2040,17 +2048,18 @@ case_opt_args([], Cs, _Sub, _LitExpr, Acc) -> %% Try to expand one argument to several arguments (if tuple/list) %% or to remove a literal argument. %% -case_opt_arg(E0, Sub, Cs, LitExpr) -> +case_opt_arg(E0, Sub, Cs0, LitExpr) -> E = maybe_replace_var(E0, Sub), case cerl:is_data(E) of false -> - {error,Cs}; + {error,Cs0}; true -> + Cs = case_opt_nomatch(E, Cs0, LitExpr), case cerl:data_type(E) of {atomic,_} -> - case_opt_lit(E, Cs, LitExpr); + case_opt_lit(E, Cs); _ -> - case_opt_data(E, Cs, LitExpr) + case_opt_data(E, Cs) end end. @@ -2072,19 +2081,67 @@ maybe_replace_var_1(E, #sub{t=Tdb}) -> false -> E; true -> - cerl_trees:map(fun(C) -> - case cerl:is_c_alias(C) of - false -> C; - true -> cerl:alias_pat(C) - end - end, T0) + %% The pattern was a tuple. Now we must make sure + %% that the elements of the tuple are suitable. In + %% particular, we don't want binary or map + %% construction here, since that means that the + %% binary or map will be constructed in the 'case' + %% argument. That is wasteful for binaries. Even + %% worse is that any map pattern that use the ':=' + %% operator will fail when used in map + %% construction (only the '=>' operator is allowed + %% when constructing a map from scratch). + ToData = fun coerce_to_data/1, + try + cerl_trees:map(ToData, T0) + catch + throw:impossible -> + %% Something unsuitable was found (map or + %% or binary). Keep the variable. + E + end end; error -> E end. -%% case_opt_lit(Literal, Clauses0, LitExpr) -> -%% {ok,[],Clauses} | error +%% coerce_to_data(Core) -> Core' +%% Coerce an element originally from a pattern to an data item or or +%% variable. Throw an 'impossible' exception if non-data Core Erlang +%% terms such as binary construction or map construction are +%% encountered. + +coerce_to_data(C) -> + case cerl:is_c_alias(C) of + false -> + case cerl:is_data(C) orelse cerl:is_c_var(C) of + true -> C; + false -> throw(impossible) + end; + true -> + coerce_to_data(cerl:alias_pat(C)) + end. + +%% case_opt_nomatch(E, Clauses, LitExpr) -> Clauses' +%% Remove all clauses that cannot possibly match. + +case_opt_nomatch(E, [{[P|_],C,_,_}=Current|Cs], LitExpr) -> + case cerl_clauses:match(P, E) of + none -> + %% The pattern will not match the case expression. Remove + %% the clause. Unless the entire case expression is a + %% literal, also emit a warning. + case LitExpr of + false -> add_warning(C, nomatch_clause_type); + true -> ok + end, + case_opt_nomatch(E, Cs, LitExpr); + _ -> + [Current|case_opt_nomatch(E, Cs, LitExpr)] + end; +case_opt_nomatch(_, [], _) -> []. + +%% case_opt_lit(Literal, Clauses0) -> {ok,[],Clauses} | error %% The current part of the case expression is a literal. That %% means that we will know at compile-time whether a clause %% will match, and we can remove the corresponding pattern from @@ -2093,68 +2150,48 @@ maybe_replace_var_1(E, #sub{t=Tdb}) -> %% The only complication is if the literal is a binary. Binary %% pattern matching is tricky, so we will give up in that case. -case_opt_lit(Lit, Cs0, LitExpr) -> - Cs1 = case_opt_lit_1(Lit, Cs0, LitExpr), - try case_opt_lit_2(Lit, Cs1) of +case_opt_lit(Lit, Cs0) -> + try case_opt_lit_1(Lit, Cs0) of Cs -> {ok,[],Cs} catch throw:impossible -> - {error,Cs1} + {error,Cs0} end. -case_opt_lit_1(E, [{[P|_],C,_,_}=Current|Cs], LitExpr) -> - case cerl_clauses:match(P, E) of - none -> - %% The pattern will not match the literal. Remove the clause. - %% Unless the entire case expression is a literal, also - %% emit a warning. - case LitExpr of - false -> add_warning(C, nomatch_clause_type); - true -> ok - end, - case_opt_lit_1(E, Cs, LitExpr); - _ -> - [Current|case_opt_lit_1(E, Cs, LitExpr)] - end; -case_opt_lit_1(_, [], _) -> []. - -case_opt_lit_2(E, [{[P|Ps],C,PsAcc,Bs0}|Cs]) -> - %% Non-matching clauses have already been removed in case_opt_lit_1/3. +case_opt_lit_1(E, [{[P|Ps],C,PsAcc,Bs0}|Cs]) -> + %% Non-matching clauses have already been removed + %% in case_opt_nomatch/3. case cerl_clauses:match(P, E) of {true,Bs} -> %% The pattern matches the literal. Remove the pattern %% and update the bindings. - [{Ps,C,PsAcc,Bs++Bs0}|case_opt_lit_2(E, Cs)]; + [{Ps,C,PsAcc,Bs++Bs0}|case_opt_lit_1(E, Cs)]; {false,_} -> %% Binary literal and pattern. We are not sure whether %% the pattern will match. throw(impossible) end; -case_opt_lit_2(_, []) -> []. +case_opt_lit_1(_, []) -> []. %% case_opt_data(Expr, Clauses0, LitExpr) -> {ok,Exprs,Clauses} -case_opt_data(E, Cs0, LitExpr) -> +case_opt_data(E, Cs0) -> Es = cerl:data_es(E), - Cs = case_opt_data_1(Cs0, Es, - {cerl:data_type(E),cerl:data_arity(E)}, - LitExpr), - {ok,Es,Cs}. - -case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig, LitExpr) -> - case case_data_pat(P, TypeSig) of - {ok,Ps1,Bs1} -> - [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}| - case_opt_data_1(Cs, Es, TypeSig,LitExpr)]; - error -> - case LitExpr of - false -> add_warning(C, nomatch_clause_type); - true -> ok - end, - case_opt_data_1(Cs, Es, TypeSig, LitExpr) - end; -case_opt_data_1([], _, _, _) -> []. + TypeSig = {cerl:data_type(E),cerl:data_arity(E)}, + try case_opt_data_1(Cs0, Es, TypeSig) of + Cs -> + {ok,Es,Cs} + catch + throw:impossible -> + {error,Cs0} + end. + +case_opt_data_1([{[P|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig) -> + {ok,Ps1,Bs1} = case_data_pat(P, TypeSig), + [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}| + case_opt_data_1(Cs, Es, TypeSig)]; +case_opt_data_1([], _, _) -> []. %% case_data_pat(Pattern, Type, Arity) -> {ok,[Pattern],[{AliasVar,Pat}]} | error. @@ -2163,12 +2200,7 @@ case_data_pat(P, TypeSig) -> false -> case_data_pat_var(P, TypeSig); true -> - case {cerl:data_type(P),cerl:data_arity(P)} of - TypeSig -> - {ok,cerl:data_es(P),[]}; - {_,_} -> - error - end + {ok,cerl:data_es(P),[]} end. %% case_data_pat_var(Pattern, {DataType,ArityType}) -> @@ -2188,35 +2220,38 @@ case_data_pat_var(P, {Type,Arity}=TypeSig) -> alias -> V = cerl:alias_var(P), Apat = cerl:alias_pat(P), - case case_data_pat(Apat, TypeSig) of - {ok,Ps,Bs} -> - {ok,Ps,[{V,cerl:ann_make_data(Ann, Type, unalias_pat_list(Ps))}|Bs]}; - error -> - error - end; - _ -> - error + {ok,Ps,Bs} = case_data_pat(Apat, TypeSig), + {ok,Ps,[{V,cerl:ann_make_data(Ann, Type, + pat_to_expr_list(Ps))}|Bs]} end. -%% unalias_pat(Pattern) -> Pattern. -%% Remove all the aliases in a pattern but using the alias variables -%% instead of the values. We KNOW they will be bound. +%% pat_to_expr(Pattern) -> Expression. +%% Convert a pattern to an expression if possible. We KNOW that +%% all variables in the pattern will be bound. +%% +%% Throw an 'impossible' exception if a map or (non-literal) +%% binary is encountered. Trying to use a map pattern as an +%% expression is incorrect, while rebuilding a potentially +%% huge binary in an expression would be wasteful. -unalias_pat(P) -> - case cerl:is_c_alias(P) of - true -> +pat_to_expr(P) -> + case cerl:type(P) of + alias -> cerl:alias_var(P); - false -> + var -> + P; + _ -> case cerl:is_data(P) of false -> - P; + %% Map or binary. + throw(impossible); true -> - Es = unalias_pat_list(cerl:data_es(P)), + Es = pat_to_expr_list(cerl:data_es(P)), cerl:update_data(P, cerl:data_type(P), Es) end end. -unalias_pat_list(Ps) -> [unalias_pat(P) || P <- Ps]. +pat_to_expr_list(Ps) -> [pat_to_expr(P) || P <- Ps]. make_vars(A, Max) -> make_vars(A, 1, Max). diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 83cf76f241..59ec0d4199 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -647,8 +647,8 @@ expr({'fun',L,{clauses,Cs},Id}, St) -> fun_tq(Id, Cs, L, St, unnamed); expr({named_fun,L,'_',Cs,Id}, St) -> fun_tq(Id, Cs, L, St, unnamed); -expr({named_fun,L,Name,Cs,{Index,Uniq,_Fname}}, St) -> - fun_tq({Index,Uniq,Name}, Cs, L, St, {named, Name}); +expr({named_fun,L,Name,Cs,Id}, St) -> + fun_tq(Id, Cs, L, St, {named,Name}); expr({call,L,{remote,_,M,F},As0}, #core{wanted=Wanted}=St0) -> {[M1,F1|As1],Aps,St1} = safe_list([M,F|As0], St0), Lanno = lineno_anno(L, St1), @@ -786,23 +786,42 @@ is_valid_map_src(_) -> false. map_pair_list(Es, St) -> foldr(fun ({map_field_assoc,L,K0,V0}, {Ces,Esp,St0}) -> - {K,Ep0,St1} = safe(K0, St0), - ok = ensure_valid_map_key(K), + {K1,Ep0,St1} = safe(K0, St0), + K = ensure_valid_map_key(K1), {V,Ep1,St2} = safe(V0, St1), A = lineno_anno(L, St2), Pair = #c_map_pair{op=#c_literal{val=assoc},anno=A,key=K,val=V}, {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}; ({map_field_exact,L,K0,V0}, {Ces,Esp,St0}) -> - {K,Ep0,St1} = safe(K0, St0), - ok = ensure_valid_map_key(K), + {K1,Ep0,St1} = safe(K0, St0), + K = ensure_valid_map_key(K1), {V,Ep1,St2} = safe(V0, St1), A = lineno_anno(L, St2), Pair = #c_map_pair{op=#c_literal{val=exact},anno=A,key=K,val=V}, {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2} end, {[],[],St}, Es). -ensure_valid_map_key(#c_literal{}) -> ok; -ensure_valid_map_key(_) -> throw({bad_map,bad_map_key}). +ensure_valid_map_key(K0) -> + case coalesced_map_key(K0) of + {ok,K1} -> K1; + error -> throw({bad_map,bad_map_key}) + end. + +coalesced_map_key(#c_literal{}=K) -> {ok,K}; +%% Dialyzer hack redux +%% DO coalesce tuples and list in maps for dialyzer +%% Dialyzer tries to break this apart, don't let it +coalesced_map_key(#c_tuple{}=K) -> + case core_lib:is_literal(K) of + true -> {ok,cerl:fold_literal(K)}; + false -> error + end; +coalesced_map_key(#c_cons{}=K) -> + case core_lib:is_literal(K) of + true -> {ok,cerl:fold_literal(K)}; + false -> error + end; +coalesced_map_key(_) -> error. %% try_exception([ExcpClause], St) -> {[ExcpVar],Handler,St}. @@ -1606,17 +1625,23 @@ pattern_alias_map_pair_patterns([Cv]) -> Cv; pattern_alias_map_pair_patterns([Cv1,Cv2|Cvs]) -> pattern_alias_map_pair_patterns([pat_alias(Cv1,Cv2)|Cvs]). -pattern_map_pair({map_field_exact,L,K,V}, St) -> +pattern_map_pair({map_field_exact,L,K,V},St) -> + #c_map_pair{anno=lineno_anno(L, St), + op=#c_literal{val=exact}, + key=pattern_map_key(K,St), + val=pattern(V, St)}. + +pattern_map_key(K,St) -> + %% Throws 'nomatch' if the key can't be a literal + %% this will be a cryptic error message but it is better than nothing case expr(K,St) of - {#c_literal{}=Key,_,_} -> - #c_map_pair{anno=lineno_anno(L, St), - op=#c_literal{val=exact}, - key=Key, - val=pattern(V, St)}; - _ -> - %% this will throw a cryptic error message - %% but it is better than nothing - throw(nomatch) + {Key0,[],_} -> + %% Dialyzer hack redux + case coalesced_map_key(Key0) of + {ok,Key1} -> Key1; + error -> throw(nomatch) + end; + _ -> throw(nomatch) end. %% pat_bin([BinElement], State) -> [BinSeg]. diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index 149b9bbb8f..10e3451e8f 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -34,7 +34,7 @@ otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1, match_string/1,zero_width/1,bad_size/1,haystack/1, cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1, - no_partition/1,calling_a_binary/1]). + no_partition/1,calling_a_binary/1,binary_in_map/1]). -export([coverage_id/1,coverage_external_ignore/2]). @@ -59,7 +59,7 @@ groups() -> matching_and_andalso,otp_7188,otp_7233,otp_7240, otp_7498,match_string,zero_width,bad_size,haystack, cover_beam_bool,matched_out_size,follow_fail_branch, - no_partition,calling_a_binary]}]. + no_partition,calling_a_binary,binary_in_map]}]. init_per_suite(Config) -> @@ -1189,6 +1189,26 @@ call_binary(<<>>, Acc) -> call_binary(<<H,T/bits>>, Acc) -> T(<<Acc/binary,H>>). +binary_in_map(Config) when is_list(Config) -> + ok = match_binary_in_map(#{key => <<42:8>>}), + {'EXIT',{{badmatch,#{key := 1}},_}} = + (catch match_binary_in_map(#{key => 1})), + {'EXIT',{{badmatch,#{key := <<1023:16>>}},_}} = + (catch match_binary_in_map(#{key => <<1023:16>>})), + {'EXIT',{{badmatch,#{key := <<1:8>>}},_}} = + (catch match_binary_in_map(#{key => <<1:8>>})), + {'EXIT',{{badmatch,not_a_map},_}} = + (catch match_binary_in_map(not_a_map)), + ok. + +match_binary_in_map(Map) -> + case 8 of + N -> + #{key := <<42:N>>} = Map, + ok + end. + + check(F, R) -> R = F(). diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index 6a7036d728..2de17e7653 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -60,6 +60,12 @@ t_element(Config) when is_list(Config) -> X = make_ref(), ?line X = id(element(1, {X,y,z})), ?line b = id(element(2, {a,b,c,d})), + (fun() -> + case {a,#{k=>X}} of + {a,#{k:=X}}=Tuple -> + #{k:=X} = id(element(2, Tuple)) + end + end)(), %% No optimization, but should work. Tuple = id({x,y,z}), @@ -204,6 +210,16 @@ eq(Config) when is_list(Config) -> ?line ?CMP_DIFF(a, [a]), ?line ?CMP_DIFF(a, {1,2,3}), + ?CMP_SAME(#{a=>1.0,b=>2}, #{b=>2.0,a=>1}), + ?CMP_SAME(#{a=>[1.0],b=>[2]}, #{b=>[2.0],a=>[1]}), + + %% The rule for comparing keys are different in 17.x and 18.x. + %% Just test that the results are consistent. + Bool = id(#{1=>a}) == id(#{1.0=>a}), %Unoptimizable. + Bool = id(#{1=>a}) == #{1.0=>a}, %Optimizable. + Bool = #{1=>a} == #{1.0=>a}, %Optimizable. + io:format("Bool = ~p\n", [Bool]), + ok. %% OTP-7117. diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl index 25b7f677b5..a3e9b7fe4e 100644 --- a/lib/compiler/test/fun_SUITE.erl +++ b/lib/compiler/test/fun_SUITE.erl @@ -21,10 +21,10 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, test1/1,overwritten_fun/1,otp_7202/1,bif_fun/1, - external/1,eep37/1,badarity/1]). + external/1,eep37/1,eep37_dup/1,badarity/1]). -%% Internal export. --export([call_me/1]). +%% Internal exports. +-export([call_me/1,dup1/0,dup2/0]). -include_lib("test_server/include/test_server.hrl"). @@ -32,7 +32,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> test_lib:recompile(?MODULE), - [test1,overwritten_fun,otp_7202,bif_fun,external,eep37,badarity]. + [test1,overwritten_fun,otp_7202,bif_fun,external,eep37,eep37_dup,badarity]. groups() -> []. @@ -206,6 +206,17 @@ eep37(Config) when is_list(Config) -> 50 = UnusedName(8), ok. +eep37_dup(Config) when is_list(Config) -> + dup1 = (dup1())(), + dup2 = (dup2())(), + ok. + +dup1() -> + fun _F() -> dup1 end. + +dup2() -> + fun _F() -> dup2 end. + badarity(Config) when is_list(Config) -> {'EXIT',{{badarity,{_,[]}},_}} = (catch (fun badarity/1)()), ok. diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index eb205d09a7..34bfdeb1e5 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -1556,6 +1556,24 @@ bad_constants(Config) when is_list(Config) -> bad_guards(Config) when is_list(Config) -> if erlang:float(self()); true -> ok end, + + fc(catch bad_guards_1(1, [])), + fc(catch bad_guards_1(1, [2])), + fc(catch bad_guards_1(atom, [2])), + + fc(catch bad_guards_2(#{a=>0,b=>0}, [])), + fc(catch bad_guards_2(#{a=>0,b=>0}, [x])), + fc(catch bad_guards_2(not_a_map, [x])), + fc(catch bad_guards_2(42, [x])), + ok. + +%% beam_bool used to produce GC BIF instructions whose +%% Live operands included uninitialized registers. + +bad_guards_1(X, [_]) when {{X}}, -X -> + ok. + +bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) -> ok. %% Call this function to turn off constant propagation. diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl index ae7d764535..1e778dca24 100644 --- a/lib/compiler/test/match_SUITE.erl +++ b/lib/compiler/test/match_SUITE.erl @@ -22,7 +22,7 @@ init_per_group/2,end_per_group/2, pmatch/1,mixed/1,aliases/1,match_in_call/1, untuplify/1,shortcut_boolean/1,letify_guard/1, - selectify/1,underscore/1,coverage/1]). + selectify/1,underscore/1,match_map/1,coverage/1]). -include_lib("test_server/include/test_server.hrl"). @@ -35,7 +35,8 @@ all() -> groups() -> [{p,test_lib:parallel(), [pmatch,mixed,aliases,match_in_call,untuplify, - shortcut_boolean,letify_guard,selectify,underscore,coverage]}]. + shortcut_boolean,letify_guard,selectify, + underscore,match_map,coverage]}]. init_per_suite(Config) -> @@ -400,6 +401,24 @@ underscore(Config) when is_list(Config) -> _ = is_list(Config), ok. +-record(s, {map,t}). + +match_map(Config) when is_list(Config) -> + Map = #{key=>{x,y},ignore=>anything}, + #s{map=Map,t={x,y}} = do_match_map(#s{map=Map}), + {a,#{k:={a,b,c}}} = do_match_map_2(#{k=>{a,b,c}}), + ok. + +do_match_map(#s{map=#{key:=Val}}=S) -> + %% Would crash with a 'badarg' exception. + S#s{t=Val}. + +do_match_map_2(Map) -> + case {a,Map} of + {a,#{k:=_}}=Tuple -> + Tuple + end. + coverage(Config) when is_list(Config) -> %% Cover beam_dead. ok = coverage_1(x, a), diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index d042596557..b1a6c15ac9 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 5.0.2 +COMPILER_VSN = 5.0.3 diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index e7215eeb64..26e2486dc2 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -1644,14 +1644,15 @@ static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM int new_ivlen = 0; ERL_NIF_TERM ret; - if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 16 + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || !(key.size == 16 || key.size == 24 || key.size == 32) || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16 || !enif_inspect_iolist_as_binary(env, argv[2], &text)) { return enif_make_badarg(env); } memcpy(ivec_clone, ivec.data, 16); - AES_set_encrypt_key(key.data, 128, &aes_key); + AES_set_encrypt_key(key.data, key.size * 8, &aes_key); AES_cfb8_encrypt((unsigned char *) text.data, enif_make_new_binary(env, text.size, &ret), text.size, &aes_key, ivec_clone, &new_ivlen, @@ -1670,14 +1671,15 @@ static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE CHECK_OSE_CRYPTO(); - if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 16 + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || !(key.size == 16 || key.size == 24 || key.size == 32) || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16 || !enif_inspect_iolist_as_binary(env, argv[2], &text)) { return enif_make_badarg(env); } memcpy(ivec_clone, ivec.data, 16); - AES_set_encrypt_key(key.data, 128, &aes_key); + AES_set_encrypt_key(key.data, key.size * 8, &aes_key); AES_cfb128_encrypt((unsigned char *) text.data, enif_make_new_binary(env, text.size, &ret), text.size, &aes_key, ivec_clone, &new_ivlen, diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 82b6de9acd..605d61e8e4 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -30,6 +30,31 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 3.4.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add configure option --with-ssl-incl=PATH to support + OpenSSL installations with headers and libraries at + different places.</p> + <p> + Own Id: OTP-12215 Aux Id: seq12700 </p> + </item> + <item> + <p> + Add configure option --with-ssl-rpath to control which + runtime library path to use for dynamic linkage toward + OpenSSL.</p> + <p> + Own Id: OTP-12316 Aux Id: seq12753 </p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 3.4.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 03aa3964a5..53e29af338 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -1185,6 +1185,38 @@ aes_cfb8() -> {aes_cfb8, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), hexstr2bin("26751F67A3CBB140B1808CF187A4F4DF"), + hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}, + {aes_cfb8, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("000102030405060708090a0b0c0d0e0f"), + hexstr2bin("6bc1bee22e409f96e93d7e117393172a")}, + {aes_cfb8, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("cdc80d6fddf18cab34c25909c99a4174"), + hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")}, + {aes_cfb8, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("67ce7f7f81173621961a2b70171d3d7a"), + hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")}, + {aes_cfb8, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("2e1e8a1dd59b88b1c8e60fed1efac4c9"), + hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}, + {aes_cfb8, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("000102030405060708090a0b0c0d0e0f"), + hexstr2bin("6bc1bee22e409f96e93d7e117393172a")}, + {aes_cfb8, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("dc7e84bfda79164b7ecd8486985d3860"), + hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")}, + {aes_cfb8, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("39ffed143b28b1c832113c6331e5407b"), + hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")}, + {aes_cfb8, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("df10132415e54b92a13ed0a8267ae2f9"), hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")} ]. @@ -1204,6 +1236,38 @@ aes_cfb128() -> {aes_cfb128, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), hexstr2bin("26751F67A3CBB140B1808CF187A4F4DF"), + hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}, + {aes_cfb128, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("000102030405060708090a0b0c0d0e0f"), + hexstr2bin("6bc1bee22e409f96e93d7e117393172a")}, + {aes_cfb128, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("cdc80d6fddf18cab34c25909c99a4174"), + hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")}, + {aes_cfb128, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("67ce7f7f81173621961a2b70171d3d7a"), + hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")}, + {aes_cfb128, + hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + hexstr2bin("2e1e8a1dd59b88b1c8e60fed1efac4c9"), + hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}, + {aes_cfb128, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("000102030405060708090a0b0c0d0e0f"), + hexstr2bin("6bc1bee22e409f96e93d7e117393172a")}, + {aes_cfb128, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("dc7e84bfda79164b7ecd8486985d3860"), + hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")}, + {aes_cfb128, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("39ffed143b28b1c832113c6331e5407b"), + hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")}, + {aes_cfb128, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("df10132415e54b92a13ed0a8267ae2f9"), hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")} ]. diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 2a7f3c4558..b87685cb3f 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 3.4.1 +CRYPTO_VSN = 3.4.2 diff --git a/lib/debugger/doc/src/i.xml b/lib/debugger/doc/src/i.xml index fb7641c30e..7564da79b3 100644 --- a/lib/debugger/doc/src/i.xml +++ b/lib/debugger/doc/src/i.xml @@ -211,7 +211,7 @@ the result of calling the shell function <c>pid(X,Y,Z)</c>. An attached process is expected to call the unofficial <c>int:attached(Pid)</c> function and to be able to handle - messages from the interpreter, see <c>dbg_ui_trace.erl</c> for + messages from the interpreter, see <c>dbg_wx_trace.erl</c> for an example.</p> </desc> </func> diff --git a/lib/debugger/doc/src/int.xml b/lib/debugger/doc/src/int.xml index 3a5886ceb9..96d0d7f83d 100644 --- a/lib/debugger/doc/src/int.xml +++ b/lib/debugger/doc/src/int.xml @@ -49,7 +49,7 @@ execution. This is done by sending and receiving information to/from the process via a third process, called the meta process. It is possible to implement your own attached process. See - <c>int.erl</c> for available functions and <c>dbg_ui_trace.erl</c> + <c>int.erl</c> for available functions and <c>dbg_wx_trace.erl</c> for possible messages.</p> <p>The interpreter depends on the Kernel, STDLIB and GS diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index c1ba1eec6b..b4baa2a1cd 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -32,6 +32,29 @@ <p>This document describes the changes made to the Debugger application.</p> +<section><title>Debugger 4.0.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure to install .hrl files when needed</p> + <p> + Own Id: OTP-12197</p> + </item> + <item> + <p> + Invoking debugger functions <c>ia/1</c> and <c>iaa/1</c> + crashed, when it tried to invoke the old and removed gs + based gui functions.</p> + <p> + Own Id: OTP-12357</p> + </item> + </list> + </section> + +</section> + <section><title>Debugger 4.0.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl index b1bf4ebecc..ce12c1beb3 100644 --- a/lib/debugger/src/dbg_icmd.erl +++ b/lib/debugger/src/dbg_icmd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2013. All Rights Reserved. +%% Copyright Ericsson AB 1998-2014. 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 @@ -49,10 +49,6 @@ %% specifies if the process should break. %%-------------------------------------------------------------------- -%% Common Test adaptation -cmd({call_remote,0,ct_line,line,_As}, Bs, _Ieval) -> - Bs; - cmd(Expr, Bs, Ieval) -> cmd(Expr, Bs, get(next_break), Ieval). diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index 77297de0f3..96f9f91808 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2013. All Rights Reserved. +%% Copyright Ericsson AB 1998-2014. 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 @@ -457,11 +457,6 @@ do_eval_function(Mod, Fun, As0, Bs0, _, Ieval0) when is_function(Fun); exception(error, Reason, Bs0, Ieval0) end; -%% Common Test adaptation -do_eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) -> - debugged_cmd({apply,ct_line,line,As}, Bs, Ieval#ieval{level=Le+1}), - {value, ignore, Bs}; - do_eval_function(Mod, Name, As0, Bs0, Called, Ieval0) -> #ieval{level=Le,line=Li,top=Top} = Ieval0, trace(call, {Called, {Le,Li,Mod,Name,As0}}), @@ -896,11 +891,6 @@ expr({make_ext_fun,Line,MFA0}, Bs0, Ieval0) -> exception(error, badarg, Bs, Ieval, true) end; -%% Common test adaptation -expr({call_remote,0,ct_line,line,As0,Lc}, Bs0, Ieval0) -> - {As,_Bs} = eval_list(As0, Bs0, Ieval0), - eval_function(ct_line, line, As, Bs0, extern, Ieval0, Lc); - %% Local function call expr({local_call,Line,F,As0,Lc}, Bs0, #ieval{module=M} = Ieval0) -> Ieval = Ieval0#ieval{line=Line}, diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl index 4ab03985d3..aed86f5232 100644 --- a/lib/debugger/src/dbg_wx_mon.erl +++ b/lib/debugger/src/dbg_wx_mon.erl @@ -414,7 +414,7 @@ gui_cmd({'Trace Window', TraceWin}, State) -> State2 = State#state{tracewin=TraceWin}, case State#state.attach of false -> ignore; - {Flags, {dbg_ui_trace, start, StartFlags}} -> + {Flags, {dbg_wx_trace, start, StartFlags}} -> case trace_function(State2) of {_, _, StartFlags} -> ignore; NewFunction -> % {_, _, NewStartFlags} diff --git a/lib/debugger/src/dbg_wx_settings.erl b/lib/debugger/src/dbg_wx_settings.erl index 20aac74c3d..2c332c0a54 100644 --- a/lib/debugger/src/dbg_wx_settings.erl +++ b/lib/debugger/src/dbg_wx_settings.erl @@ -65,14 +65,8 @@ open_win(Win, Pos, SFile, Str, What) -> {style,What}]), case wxFileDialog:showModal(FD) of ?wxID_OK -> - case wxFileDialog:getPaths(FD) of - [NewFile] -> - wxFileDialog:destroy(FD), - {ok, NewFile}; - _ -> - wxFileDialog:destroy(FD), - cancel - end; + NewFile = wxFileDialog:getPath(FD), + {ok, NewFile}; _ -> wxFileDialog:destroy(FD), cancel diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl index 5805501524..0afb998097 100644 --- a/lib/debugger/src/i.erl +++ b/lib/debugger/src/i.erl @@ -250,7 +250,7 @@ ist(Flag) -> %% ------------------------------------------- iaa(Flag) -> - iaa(Flag,{dbg_ui_trace,start,[]}). + iaa(Flag,{dbg_wx_trace,start,[]}). %% ------------------------------------------- %% Set the automatic attachment flag. @@ -271,7 +271,7 @@ iaa(Flag,Fnk) -> %% ------------------------------------------- ia(Pid) -> - ia(Pid,{dbg_ui_trace,start}). + ia(Pid,{dbg_wx_trace,start}). %% ------------------------------------------- %% Attach to process. diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl index 2755db64b8..908390ce50 100644 --- a/lib/debugger/src/int.erl +++ b/lib/debugger/src/int.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2013. All Rights Reserved. +%% Copyright Ericsson AB 1998-2014. 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 @@ -265,9 +265,6 @@ first_lines(Clauses) -> first_line({clause,_L,_Vars,_,Exprs}) -> first_line(Exprs); -%% Common Test adaptation -first_line([{call_remote,0,ct_line,line,_As}|Exprs]) -> - first_line(Exprs); first_line([Expr|_Exprs]) -> % Expr = {Op, Line, ..varying no of args..} element(2, Expr). diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index 33481a1537..38c19be93e 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 4.0.1 +DEBUGGER_VSN = 4.0.2 diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index d35639aa32..4020165697 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -31,6 +31,44 @@ <p>This document describes the changes made to the Dialyzer application.</p> +<section><title>Dialyzer 2.7.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> When compiling Erlang source, Dialyzer now ignores + the environment variable ERL_COMPILER_OPTIONS as well as + skips the Erlang Compiler option + <c>warnings_as_errors</c>. </p> + <p> + Own Id: OTP-12225</p> + </item> + <item> + <p> Dialyzer did not check the type of record elements + when updating them. The bug, introduced in Erlang/OTP + 17.1, has been corrected. (Thanks to Nicolas Dudebout for + pointing it out.) </p> + <p> + Own Id: OTP-12319</p> + </item> + <item> + <p> + Coalesce map keys in dialyzer mode</p> + <p> + This fixes a regression introduced in commit + 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba The problem + occurred with compounded map keys compiled with dialyzer + option turned on, '+dialyzer'.</p> + <p> + Reported by: Ivan Uemlianin</p> + <p> + Own Id: OTP-12347</p> + </item> + </list> + </section> + +</section> + <section><title>Dialyzer 2.7.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_update b/lib/dialyzer/test/small_SUITE_data/results/record_update new file mode 100644 index 0000000000..ea52057adf --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/record_update @@ -0,0 +1,2 @@ + +record_update.erl:7: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar::atom()},atom()) -> #foo{bar::atom()} diff --git a/lib/dialyzer/test/small_SUITE_data/src/maps1.erl b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl index 06ced5b69e..228ffe2c22 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/maps1.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/maps1.erl @@ -10,6 +10,7 @@ -export([recv/3, decode/1]). +-export([get_my_map/0,is_my_map/1]). %-record(can_pkt, {id, data :: binary(), timestamp}). @@ -39,3 +40,38 @@ t2() -> ok. update(#{ id := Id, val := Val } = M, X) when is_integer(Id) -> M#{ val := [Val,X] }. + +%% key coalescing + +-spec get_my_map() -> map(). + +get_my_map() -> + #{labels => [one, two], + number => 27, + [1,2,3] => wer, + {4,5,6} => sdf, + kvok => #{ + <<"wat">> => v, + a => qwe, + 2 => asd, + [1,2,3] => wer, + {4,5,6} => sdf, + "abc" => zxc + } + }. + +-spec is_my_map(map()) -> 'ok'. + +is_my_map(#{labels := [one, two], + number := 27, + [1,2,3] := wer, + {4,5,6} := sdf, + kvok := #{ + <<"wat">> := v, + a := qwe, + 2 := asd, + [1,2,3] := wer, + {4,5,6} := sdf, + "abc" := zxc + } + }) -> ok. diff --git a/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl b/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl new file mode 100644 index 0000000000..945b2a9144 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/maps_redef2.erl @@ -0,0 +1,23 @@ +%% In 17, the linter says that map(A) redefines 'type map', which is +%% allowed until next release. However, Dialyzer used to replace +%% map(A) with #{}, which resulted in warnings. + +-module(maps_redef2). + +-export([t/0]). + +-type map(_A) :: integer(). + +t() -> + M = new(), + t1(M). + +-spec t1(map(_)) -> map(_). + +t1(A) -> + A + A. + +-spec new() -> map(_). + +new() -> + 3. diff --git a/lib/dialyzer/test/small_SUITE_data/src/record_update.erl b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl new file mode 100644 index 0000000000..bad7a0a929 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl @@ -0,0 +1,10 @@ +-module(record_update). + +-export([quux/2]). + +-record(foo, {bar :: atom()}). + +-spec quux(#foo{}, string()) -> #foo{}. + +quux(Foo, NotBar) -> + Foo#foo{ bar = NotBar }. diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 58cc77c2fa..e7c13f04ad 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 2.7.2 +DIALYZER_VSN = 2.7.3 diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml index ab9ad25a3a..638c1c4c2b 100644 --- a/lib/diameter/doc/src/diameter.xml +++ b/lib/diameter/doc/src/diameter.xml @@ -21,7 +21,7 @@ <copyright> <year>2011</year> -<year>2014</year> +<year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -111,7 +111,7 @@ Defined in &dict_data_types;.</p> <tag><c>application_alias() = term()</c></tag> <item> <p> -A name identifying a Diameter application in +Name identifying a Diameter application in service configuration. Passed to &call; when sending requests defined by the application.</p> @@ -129,7 +129,7 @@ ExtraArgs = list() </pre> <p> -A module implementing the callback interface defined in &man_app;, +Module implementing the callback interface defined in &man_app;, along with any extra arguments to be appended to those documented. Note that extra arguments specific to an outgoing request can be @@ -156,7 +156,7 @@ Has one the following types.</p> <tag><c>{alias, &application_alias;}</c></tag> <item> <p> -A unique identifier for the application in the scope of the +Unique identifier for the application in the scope of the service. Defaults to the value of the <c>dictionary</c> option if unspecified.</p> @@ -165,7 +165,7 @@ unspecified.</p> <tag><c>{dictionary, atom()}</c></tag> <item> <p> -The name of an encode/decode module for the Diameter +Name of an encode/decode module for the Diameter messages defined by the application. These modules are generated from files whose format is documented in &man_dict;.</p> @@ -174,7 +174,7 @@ These modules are generated from files whose format is documented in <tag><c>{module, &application_module;}</c></tag> <item> <p> -The callback module with which messages of the Diameter application are +Callback module in which messages of the Diameter application are handled. See &man_app; for the required interface and semantics.</p> </item> @@ -182,7 +182,7 @@ See &man_app; for the required interface and semantics.</p> <tag><c>{state, term()}</c></tag> <item> <p> -The initial callback state. +Initial callback state. The prevailing state is passed to some &man_app; callbacks, which can then return a new state. @@ -192,7 +192,7 @@ Defaults to the value of the <c>alias</c> option if unspecified.</p> <tag><c>{call_mutates_state, true|false}</c></tag> <item> <p> -Specifies whether or not the &app_pick_peer; +Whether or not the &app_pick_peer; application callback can modify the application state. Defaults to <c>false</c> if unspecified.</p> @@ -209,7 +209,7 @@ probably avoid it.</p> <tag><c>{answer_errors, callback|report|discard}</c></tag> <item> <p> -Determines the manner in which incoming answer messages containing +Manner in which incoming answer messages containing decode errors are handled.</p> <p> @@ -233,7 +233,7 @@ Defaults to <c>discard</c> if unspecified.</p> <tag><c>{request_errors, answer_3xxx|answer|callback}</c></tag> <item> <p> -Determines the manner in which incoming requests are handled when an +Manner in which incoming requests are handled when an error other than 3007 (DIAMETER_APPLICATION_UNSUPPORTED, which cannot be associated with an application callback module), is detected.</p> @@ -293,7 +293,7 @@ Multiple options append to the argument list.</p> <tag><c>{filter, &peer_filter;}</c></tag> <item> <p> -A filter to apply to the list of available peers before passing it to +Filter to apply to the list of available peers before passing it to the &app_pick_peer; callback for the application in question. Multiple options are equivalent a single <c>all</c> filter on the corresponding list of filters. @@ -311,7 +311,7 @@ Defaults to 5000.</p> <tag><c>detach</c></tag> <item> <p> -Causes &call; to return <c>ok</c> as +Cause &call; to return <c>ok</c> as soon as the request in question has been encoded, instead of waiting for and returning the result from a subsequent &app_handle_answer; or @@ -427,7 +427,7 @@ configuration passed to &start_service; or &add_transport;.</p> <tag><c>peer_filter() = term()</c></tag> <item> <p> -A filter passed to &call; in order to select candidate peers for a +Filter passed to &call; in order to select candidate peers for a &app_pick_peer; callback. Has one of the following types.</p> @@ -500,6 +500,18 @@ Matches only those peers matched by each filter in the specified list.</p> <p> Matches only those peers matched by at least one filter in the specified list.</p> + +<p> +The resulting peer list will be in match order, peers matching the +first filter of the list sorting before those matched by the second, +and so on. +For example, the following filter causes peers matching both the host +and realm filters to be presented before those matching only the realm +filter.</p> + +<pre> +{any, [{all, [host, realm]}, realm]} +</pre> </item> </taglist> @@ -1020,7 +1032,7 @@ case the corresponding callbacks are applied until either all return <tag><c>{capx_timeout, &dict_Unsigned32;}</c></tag> <item> <p> -The number of milliseconds after which a transport process having an +Number of milliseconds after which a transport process having an established transport connection will be terminated if the expected capabilities exchange message (CER or CEA) is not received from the peer. For a connecting transport, the timing of connection attempts is @@ -1067,7 +1079,7 @@ transport.</p> <item> <p> -A callback invoked prior to terminating the transport process of a +Callback invoked prior to terminating the transport process of a transport connection having watchdog state <c>OKAY</c>. Applied to <c>application|service|transport</c> and the <c>&transport_ref;</c> and <c>&app_peer;</c> in question: @@ -1083,7 +1095,7 @@ The return value can have one of the following types.</p> <tag><c>{dpr, [option()]}</c></tag> <item> <p> -Causes Disconnect-Peer-Request to be sent to the peer, the transport +Send Disconnect-Peer-Request to the peer, the transport process being terminated following reception of Disconnect-Peer-Answer or timeout. An <c>option()</c> can be one of the following.</p> @@ -1092,7 +1104,7 @@ An <c>option()</c> can be one of the following.</p> <tag><c>{cause, 0|rebooting|1|busy|2|goaway}</c></tag> <item> <p> -The Disconnect-Cause to send, <c>REBOOTING</c>, <c>BUSY</c> and +Disconnect-Cause to send, <c>REBOOTING</c>, <c>BUSY</c> and <c>DO_NOT_WANT_TO_TALK_TO_YOU</c> respectively. Defaults to <c>rebooting</c> for <c>Reason=service|application</c> and <c>goaway</c> for <c>Reason=transport</c>.</p> @@ -1101,7 +1113,7 @@ Defaults to <c>rebooting</c> for <c>Reason=service|application</c> and <tag><c>{timeout, &dict_Unsigned32;}</c></tag> <item> <p> -The number of milliseconds after which the transport process is +Number of milliseconds after which the transport process is terminated if DPA has not been received. Defaults to 1000.</p> </item> @@ -1117,7 +1129,7 @@ Equivalent to <c>{dpr, []}</c>.</p> <tag><c>close</c></tag> <item> <p> -Causes the transport process to be terminated without +Terminate the transport process without Disconnect-Peer-Request being sent to the peer.</p> </item> @@ -1144,7 +1156,7 @@ Defaults to a single callback returning <c>dpr</c>.</p> <tag><c>{length_errors, exit|handle|discard}</c></tag> <item> <p> -Specifies how to deal with errors in the Message Length field of the +How to deal with errors in the Message Length field of the Diameter Header in an incoming message. An error in this context is that the length is not at least 20 bytes (the length of a Header), is not a multiple of 4 (a valid length) or @@ -1176,11 +1188,26 @@ See &man_tcp; for the behaviour of that module.</p> </note> </item> +<tag><c>{pool_size, pos_integer()}</c></tag> +<item> +<p> +Number of transport processes to start. +For a listening transport, determines the size of the pool of +accepting transport processes, a larger number being desirable for +processing multiple concurrent peer connection attempts. +For a connecting transport, determines the number of connections to +the peer in question that will be attempted to be establshed: +the &service_opt;: <c>restrict_connections</c> should also be +configured on the service in question to allow multiple connections to +the same peer.</p> + +</item> + <marker id="spawn_opt"/> <tag><c>{spawn_opt, [term()]}</c></tag> <item> <p> -An options list passed to &spawn_opt; when spawning a process for an +Options list passed to &spawn_opt; when spawning a process for an incoming Diameter request. Options <c>monitor</c> and <c>link</c> are ignored.</p> @@ -1193,7 +1220,7 @@ Defaults to the list configured on the service if not specified.</p> <tag><c>{transport_config, term(), &dict_Unsigned32; | infinity}</c></tag> <item> <p> -A term passed as the third argument to the &transport_start; function of +Term passed as the third argument to the &transport_start; function of the relevant &transport_module; in order to start a transport process. Defaults to the empty list if unspecified.</p> @@ -1221,7 +1248,7 @@ To listen on both SCTP and TCP, define one transport for each.</p> <tag><c>{transport_module, atom()}</c></tag> <item> <p> -A module implementing a transport process as defined in &man_transport;. +Module implementing a transport process as defined in &man_transport;. Defaults to <c>diameter_tcp</c> if unspecified.</p> <p> @@ -1241,7 +1268,7 @@ corresponding timeout (see below) or all fail.</p> <tag><c>{watchdog_config, [{okay|suspect, non_neg_integer()}]}</c></tag> <item> <p> -Specifies configuration that alters the behaviour of the watchdog +Configuration that alters the behaviour of the watchdog state machine. On key <c>okay</c>, the non-negative number of answered DWR messages before transitioning from REOPEN to OKAY. @@ -1296,7 +1323,7 @@ in predicate functions passed to &remove_transport;.</p> <tag><c>transport_ref() = reference()</c></tag> <item> <p> -An reference returned by &add_transport; that +Reference returned by &add_transport; that identifies the configuration.</p> </item> @@ -1725,6 +1752,14 @@ connection might look as follows.</p> The information presented here is as in the <c>connect</c> case except that the client connections are grouped under an <c>accept</c> tuple.</p> +<p> +Whether or not the &transport_opt; <c>pool_size</c> affects the format +of the listing in the case of a connecting transport, since a value +greater than 1 implies multiple transport processes for the same +<c>&transport_ref;</c>, as in the listening case. +The format in this case is similar to the listening case, with a +<c>pool</c> tuple in place of an <c>accept</c> tuple.</p> + </item> <tag><c>connections</c></tag> diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml index 7f69bdbfbf..e6ac332c10 100644 --- a/lib/diameter/doc/src/notes.xml +++ b/lib/diameter/doc/src/notes.xml @@ -42,6 +42,68 @@ first.</p> <!-- ===================================================================== --> +<section><title>diameter 1.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix remote diameter_request table leak.</p> + <p> + An outgoing request whose pick_peer callback selected a + transport on another node resulted in an orphaned table + entry on that node.</p> + <p> + Own Id: OTP-12196</p> + </item> + <item> + <p> + Fix handling of 3xxx Result-Code without E-bit.</p> + <p> + OTP-12233 broke the population of the errors field of the + diameter_packet record when an incoming request with an + E-bit/Result-Code mismatch was detected, causing a + 4-tuple to be inserted as Result-Code in a diameter_avp + record.</p> + <p> + Own Id: OTP-12233</p> + </item> + <item> + <p> + Fix ignored connect timer.</p> + <p> + There are two timers governing the establishment of peer + connections: connect_timer and watchdog_timer. The former + is the RFC 6733 Tc timer, and is used at initial + connection establishment. The latter is RFC 3539 TwInit, + and is used for connection reestablishment. A connecting + transport erroneously used watchdog_timer in both cases.</p> + <p> + Own Id: OTP-12281 Aux Id: seq12728 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Order candidate peers in pick_peer callbacks.</p> + <p> + The order of candidate peers presented to a + diameter_app(3) pick_peer callback has previously not + been documented, but there are use cases that are + simplified by an ordering. The order is now determined by + the filter.</p> + <p> + Own Id: OTP-12308</p> + </item> + </list> + </section> + +</section> + <section><title>diameter 1.7.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/diameter/examples/code/GNUmakefile b/lib/diameter/examples/code/GNUmakefile index 98e36a99e3..81f1da5a39 100644 --- a/lib/diameter/examples/code/GNUmakefile +++ b/lib/diameter/examples/code/GNUmakefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2010-2012. All Rights Reserved. +# Copyright Ericsson AB 2010-2015. 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,7 +20,7 @@ EXAMPLES = client server relay # redirect proxy CALLBACKS = $(EXAMPLES:%=%_cb) -MODULES = peer $(EXAMPLES) $(EXAMPLES:%=%_cb) +MODULES = node $(EXAMPLES) $(EXAMPLES:%=%_cb) BEAM = $(MODULES:%=%.beam) diff --git a/lib/diameter/examples/code/client.erl b/lib/diameter/examples/code/client.erl index 46eb4a55db..be5b4cbba5 100644 --- a/lib/diameter/examples/code/client.erl +++ b/lib/diameter/examples/code/client.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -38,7 +38,7 @@ -module(client). -include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). +-include_lib("diameter/include/diameter_gen_base_rfc6733.hrl"). -export([start/1, %% start a service connect/2, %% add a connecting transport @@ -50,17 +50,14 @@ %% both the record and list encoding here, one detached and one not, %% is just for demonstration purposes. -%% Convenience functions using the default service name, ?SVC_NAME. +%% Convenience functions using the default service name. -export([start/0, connect/1, stop/0, call/0, cast/0]). --define(SVC_NAME, ?MODULE). --define(APP_ALIAS, ?MODULE). --define(CALLBACK_MOD, client_cb). - +-define(DEF_SVC_NAME, ?MODULE). -define(L, atom_to_list). %% The service configuration. As in the server example, a client @@ -70,27 +67,27 @@ {'Origin-Realm', "example.com"}, {'Vendor-Id', 0}, {'Product-Name', "Client"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, - {application, [{alias, ?APP_ALIAS}, - {dictionary, ?DIAMETER_DICT_COMMON}, - {module, ?CALLBACK_MOD}]}]). + {'Auth-Application-Id', [0]}, + {application, [{alias, common}, + {dictionary, diameter_gen_base_rfc6733}, + {module, client_cb}]}]). %% start/1 start(Name) when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). + node:start(Name, ?SERVICE(Name)). start() -> - start(?SVC_NAME). + start(?DEF_SVC_NAME). %% connect/2 connect(Name, T) -> - peer:connect(Name, T). + node:connect(Name, T). connect(T) -> - connect(?SVC_NAME, T). + connect(?DEF_SVC_NAME, T). %% call/1 @@ -99,10 +96,10 @@ call(Name) -> RAR = #diameter_base_RAR{'Session-Id' = SId, 'Auth-Application-Id' = 0, 'Re-Auth-Request-Type' = 0}, - diameter:call(Name, ?APP_ALIAS, RAR, []). + diameter:call(Name, common, RAR, []). call() -> - call(?SVC_NAME). + call(?DEF_SVC_NAME). %% cast/1 @@ -111,15 +108,15 @@ cast(Name) -> RAR = ['RAR', {'Session-Id', SId}, {'Auth-Application-Id', 0}, {'Re-Auth-Request-Type', 1}], - diameter:call(Name, ?APP_ALIAS, RAR, [detach]). + diameter:call(Name, common, RAR, [detach]). cast() -> - cast(?SVC_NAME). + cast(?DEF_SVC_NAME). %% stop/1 stop(Name) -> - peer:stop(Name). + node:stop(Name). stop() -> - stop(?SVC_NAME). + stop(?DEF_SVC_NAME). diff --git a/lib/diameter/examples/code/node.erl b/lib/diameter/examples/code/node.erl new file mode 100644 index 0000000000..4fe9007059 --- /dev/null +++ b/lib/diameter/examples/code/node.erl @@ -0,0 +1,174 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2015. 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% +%% + +%% +%% A library module used by the example Diameter nodes. Does little +%% more than provide an alternate/simplified transport configuration. +%% + +-module(node). + +-export([start/2, + listen/2, + connect/2, + stop/1]). + +-type protocol() + :: tcp | sctp. + +-type ip_address() + :: default + | inet:ip_address(). + +-type server_transport() + :: protocol() + | {protocol(), ip_address(), non_neg_integer()}. + +-type server_opts() + :: server_transport() + | {server_transport(), [diameter:transport_opt()]} + | [diameter:transport_opt()]. + +-type client_transport() + :: protocol() | any + | {protocol() | any, ip_address(), non_neg_integer()} + | {protocol() | any, ip_address(), ip_address(), non_neg_integer()}. + +-type client_opts() + :: client_transport() + | {client_transport(), [diameter:transport_opt()]} + | [diameter:transport_opt()]. + +%% The server_transport() and client_transport() config is just +%% convenience: arbitrary options can be specifed as a +%% [diameter:transport_opt()]. + +-define(DEFAULT_PORT, 3868). + +%% --------------------------------------------------------------------------- +%% Interface functions +%% --------------------------------------------------------------------------- + +%% start/2 + +-spec start(diameter:service_name(), [diameter:service_opt()]) + -> ok + | {error, term()}. + +start(Name, Opts) + when is_atom(Name), is_list(Opts) -> + diameter:start_service(Name, Opts). + +%% connect/2 + +-spec connect(diameter:service_name(), client_opts()) + -> {ok, diameter:transport_ref()} + | {error, term()}. + +connect(Name, Opts) + when is_list(Opts) -> + diameter:add_transport(Name, {connect, Opts}); + +connect(Name, {T, Opts}) -> + connect(Name, Opts ++ client_opts(T)); + +connect(Name, T) -> + connect(Name, [{connect_timer, 5000} | client_opts(T)]). + +%% listen/2 + +-spec listen(diameter:service_name(), server_opts()) + -> {ok, diameter:transport_ref()} + | {error, term()}. + +listen(Name, Opts) + when is_list(Opts) -> + diameter:add_transport(Name, {listen, Opts}); + +listen(Name, {T, Opts}) -> + listen(Name, Opts ++ server_opts(T)); + +listen(Name, T) -> + listen(Name, server_opts(T)). + +%% stop/1 + +-spec stop(diameter:service_name()) + -> ok + | {error, term()}. + +stop(Name) -> + diameter:stop_service(Name). + +%% --------------------------------------------------------------------------- +%% Internal functions +%% --------------------------------------------------------------------------- + +%% server_opts/1 +%% +%% Return transport options for a listening transport. + +server_opts({T, Addr, Port}) -> + [{transport_module, tmod(T)}, + {transport_config, [{reuseaddr, true}, + {ip, addr(Addr)}, + {port, Port}]}]; + +server_opts(T) -> + server_opts({T, loopback, ?DEFAULT_PORT}). + +%% client_opts/1 +%% +%% Return transport options for a connecting transport. + +client_opts({T, LA, RA, RP}) + when T == all; %% backwards compatibility + T == any -> + [[S, {C,Os}], T] = [client_opts({P, LA, RA, RP}) || P <- [sctp,tcp]], + [S, {C,Os,2000} | T]; + +client_opts({T, LA, RA, RP}) -> + [{transport_module, tmod(T)}, + {transport_config, [{raddr, addr(RA)}, + {rport, RP}, + {reuseaddr, true} + | ip(LA)]}]; + +client_opts({T, RA, RP}) -> + client_opts({T, default, RA, RP}); + +client_opts(T) -> + client_opts({T, loopback, loopback, ?DEFAULT_PORT}). + +%% --------------------------------------------------------------------------- + +tmod(tcp) -> diameter_tcp; +tmod(sctp) -> diameter_sctp. + +ip(default) -> + []; +ip(loopback) -> + [{ip, {127,0,0,1}}]; +ip(Addr) -> + [{ip, Addr}]. + +addr(loopback) -> + {127,0,0,1}; +addr(A) -> + A. diff --git a/lib/diameter/examples/code/peer.erl b/lib/diameter/examples/code/peer.erl deleted file mode 100644 index b4ee17e4b7..0000000000 --- a/lib/diameter/examples/code/peer.erl +++ /dev/null @@ -1,150 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2013. 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% -%% - -%% -%% A library module that factors out commonality in the example -%% Diameter peers. -%% - --module(peer). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). - --export([start/2, - listen/2, - connect/2, - stop/1]). - --type service_name() - :: term(). - --type protocol() - :: tcp | sctp. - --type ip_address() - :: default - | inet:ip_address(). - --type server_config() - :: protocol() - | {protocol(), ip_address(), non_neg_integer()}. - --type client_config() - :: protocol() - | {protocol(), ip_address(), non_neg_integer()} - | {protocol(), ip_address(), ip_address(), non_neg_integer()}. - --define(DEFAULT_PORT, 3868). - -%% --------------------------------------------------------------------------- -%% Interface functions -%% --------------------------------------------------------------------------- - -%% start/2 - --spec start(service_name(), list()) - -> ok - | {error, term()}. - -start(Name, Opts) - when is_atom(Name), is_list(Opts) -> - diameter:start_service(Name, Opts). - -%% connect/2 - --spec connect(service_name(), client_config()) - -> {ok, reference()} - | {error, term()}. - -connect(Name, T) -> - diameter:add_transport(Name, {connect, [{reconnect_timer, 5000} - | client(T)]}). - -%% listen/2 - --spec listen(service_name(), server_config()) - -> {ok, reference()} - | {error, term()}. - -listen(Name, T) -> - diameter:add_transport(Name, {listen, server(T)}). - -%% stop/1 - --spec stop(service_name()) - -> ok - | {error, term()}. - -stop(Name) -> - diameter:stop_service(Name). - -%% --------------------------------------------------------------------------- -%% Internal functions -%% --------------------------------------------------------------------------- - -%% server/1 -%% -%% Return config for a listening transport. - -server({T, Addr, Port}) -> - [{transport_module, tmod(T)}, - {transport_config, [{reuseaddr, true}, - {ip, addr(Addr)}, - {port, Port}]}]; - -server(T) -> - server({T, loopback, ?DEFAULT_PORT}). - -%% client/1 -%% -%% Return config for a connecting transport. - -client({all, LA, RA, RP}) -> - [[M,{K,C}], T] - = [client({P, LA, RA, RP}) || P <- [sctp,tcp]], - [M, {K,C,2000} | T]; - -client({T, LA, RA, RP}) -> - [{transport_module, tmod(T)}, - {transport_config, [{raddr, addr(RA)}, - {rport, RP}, - {reuseaddr, true} - | ip(LA)]}]; - -client({T, RA, RP}) -> - client({T, default, RA, RP}); - -client(T) -> - client({T, loopback, loopback, ?DEFAULT_PORT}). - -tmod(tcp) -> diameter_tcp; -tmod(sctp) -> diameter_sctp. - -ip(default) -> - []; -ip(loopback) -> - [{ip, {127,0,0,1}}]; -ip(Addr) -> - [{ip, Addr}]. - -addr(loopback) -> - {127,0,0,1}; -addr(A) -> - A. diff --git a/lib/diameter/examples/code/relay.erl b/lib/diameter/examples/code/relay.erl index d3438f83f3..0aa3cd06d3 100644 --- a/lib/diameter/examples/code/relay.erl +++ b/lib/diameter/examples/code/relay.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -31,9 +31,6 @@ -module(relay). --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). - -export([start/1, listen/2, connect/2, @@ -44,49 +41,47 @@ connect/1, stop/0]). --define(APP_ALIAS, ?MODULE). --define(SVC_NAME, ?MODULE). --define(CALLBACK_MOD, relay_cb). +-define(DEF_SVC_NAME, ?MODULE). %% The service configuration. -define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, {'Origin-Realm', "example.com"}, {'Vendor-Id', 193}, {'Product-Name', "RelayAgent"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]}, - {application, [{alias, ?MODULE}, - {dictionary, ?DIAMETER_DICT_RELAY}, - {module, ?CALLBACK_MOD}]}]). + {'Auth-Application-Id', [16#FFFFFFFF]}, + {application, [{alias, relay}, + {dictionary, diameter_relay}, + {module, relay_cb}]}]). %% start/1 start(Name) when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). + node:start(Name, ?SERVICE(Name)). start() -> - start(?SVC_NAME). + start(?DEF_SVC_NAME). %% listen/2 listen(Name, T) -> - peer:listen(Name, T). + node:listen(Name, T). listen(T) -> - listen(?SVC_NAME, T). + listen(?DEF_SVC_NAME, T). %% connect/2 connect(Name, T) -> - peer:connect(Name, T). + node:connect(Name, T). connect(T) -> - connect(?SVC_NAME, T). + connect(?DEF_SVC_NAME, T). %% stop/1 stop(Name) -> - peer:stop(Name). + node:stop(Name). stop() -> - stop(?SVC_NAME). + stop(?DEF_SVC_NAME). diff --git a/lib/diameter/examples/code/server.erl b/lib/diameter/examples/code/server.erl index 3959461cec..8c91e68895 100644 --- a/lib/diameter/examples/code/server.erl +++ b/lib/diameter/examples/code/server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -34,21 +34,16 @@ -module(server). --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). - -export([start/1, %% start a service listen/2, %% add a listening transport stop/1]). %% stop a service -%% Convenience functions using the default service name, ?SVC_NAME. +%% Convenience functions using the default service name. -export([start/0, listen/1, stop/0]). --define(SVC_NAME, ?MODULE). --define(APP_ALIAS, ?MODULE). --define(CALLBACK_MOD, server_cb). +-define(DEF_SVC_NAME, ?MODULE). %% The service configuration. In a server supporting multiple Diameter %% applications each application may have its own, although they could all @@ -57,32 +52,32 @@ {'Origin-Realm', "example.com"}, {'Vendor-Id', 193}, {'Product-Name', "Server"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, - {application, [{alias, ?APP_ALIAS}, - {dictionary, ?DIAMETER_DICT_COMMON}, - {module, ?CALLBACK_MOD}]}]). + {'Auth-Application-Id', [0]}, + {application, [{alias, common}, + {dictionary, diameter_gen_base_rfc6733}, + {module, server_cb}]}]). %% start/1 start(Name) when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). + node:start(Name, ?SERVICE(Name)). start() -> - start(?SVC_NAME). + start(?DEF_SVC_NAME). %% listen/2 listen(Name, T) -> - peer:listen(Name, T). + node:listen(Name, T). listen(T) -> - listen(?SVC_NAME, T). + listen(?DEF_SVC_NAME, T). %% stop/1 stop(Name) -> - peer:stop(Name). + node:stop(Name). stop() -> - stop(?SVC_NAME). + stop(?DEF_SVC_NAME). diff --git a/lib/diameter/examples/code/server_cb.erl b/lib/diameter/examples/code/server_cb.erl index 9d8d395d06..071e152493 100644 --- a/lib/diameter/examples/code/server_cb.erl +++ b/lib/diameter/examples/code/server_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -24,7 +24,7 @@ -module(server_cb). -include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). +-include_lib("diameter/include/diameter_gen_base_rfc6733.hrl"). %% diameter callbacks -export([peer_up/3, diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl index bc25f7d472..8272904856 100644 --- a/lib/diameter/include/diameter_gen.hrl +++ b/lib/diameter/include/diameter_gen.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -25,6 +25,9 @@ -define(THROW(T), throw({?MODULE, T})). +%% Tag common to generated dictionaries. +-define(TAG, diameter_gen). + %% Key to a value in the process dictionary that determines whether or %% not an unrecognized AVP setting the M-bit should be regarded as an %% error or not. See is_strict/0. @@ -48,13 +51,20 @@ %% dictionary. putr(K,V) -> - put({?MODULE, K}, V). + put({?TAG, K}, V). getr(K) -> - get({?MODULE, K}). + case get({?TAG, K}) of + undefined -> + V = erase({?MODULE, K}), %% written in old code + V == undefined orelse putr(K,V), + V; + V -> + V + end. eraser(K) -> - erase({?MODULE, K}). + erase({?TAG, K}). %% --------------------------------------------------------------------------- %% # encode_avps/2 @@ -313,12 +323,20 @@ d(Name, Avp, Acc) -> %% decode is packed into 'AVP'. Mod = dict(Failed), %% Dictionary to decode in. + %% On decode, a Grouped AVP is represented as a #diameter_avp{} + %% list with AVP as head and component AVPs as tail. On encode, + %% data can be a list of component AVPs. + try Mod:avp(decode, Data, AvpName) of V -> {Avps, T} = Acc, {H, A} = ungroup(V, Avp), {[H | Avps], pack_avp(Name, A, T)} catch + throw: {?TAG, {grouped, RC, ComponentAvps}} -> + {Avps, {Rec, Errors}} = Acc, + A = trim(Avp), + {[[A | trim(ComponentAvps)] | Avps], {Rec, [{RC, A} | Errors]}}; error: Reason -> d(undefined == Failed orelse is_failed(), Reason, @@ -338,6 +356,10 @@ d(Name, Avp, Acc) -> trim(#diameter_avp{data = <<0:1, Bin/binary>>} = Avp) -> Avp#diameter_avp{data = Bin}; +trim(Avps) + when is_list(Avps) -> + lists:map(fun trim/1, Avps); + trim(Avp) -> Avp. @@ -582,22 +604,37 @@ value(_, Avp) -> %% # grouped_avp/3 %% --------------------------------------------------------------------------- --spec grouped_avp(decode, avp_name(), binary()) +-spec grouped_avp(decode, avp_name(), bitstring()) -> {avp_record(), [avp()]}; (encode, avp_name(), avp_record() | avp_values()) -> binary() | no_return(). +%% Length error induced by diameter_codec:collect_avps/1. +grouped_avp(decode, _Name, <<0:1, _/binary>>) -> + throw({?TAG, {grouped, 5014, []}}); + grouped_avp(decode, Name, Data) -> - {Rec, Avps, []} = decode_avps(Name, diameter_codec:collect_avps(Data)), - {Rec, Avps}; -%% A failed match here will result in 5004. Note that this is the only -%% AVP type that doesn't just return the decoded record, also -%% returning the list of component AVP's. + grouped_decode(Name, diameter_codec:collect_avps(Data)); grouped_avp(encode, Name, Data) -> encode_avps(Name, Data). +%% grouped_decode/2 +%% +%% Note that Grouped is the only AVP type that doesn't just return a +%% decoded value, also returning the list of component diameter_avp +%% records. + +grouped_decode(_Name, {Error, Acc}) -> + {RC, Avp} = Error, + throw({?TAG, {grouped, RC, [Avp | Acc]}}); + +grouped_decode(Name, ComponentAvps) -> + {Rec, Avps, Es} = decode_avps(Name, ComponentAvps), + [] == Es orelse throw({?TAG, {grouped, 5004, Avps}}), %% decode failure + {Rec, Avps}. + %% --------------------------------------------------------------------------- %% # empty_group/1 %% --------------------------------------------------------------------------- diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl index d74e091e11..1bbdf6e34d 100644 --- a/lib/diameter/src/base/diameter.erl +++ b/lib/diameter/src/base/diameter.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2014. 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 @@ -337,6 +337,7 @@ call(SvcName, App, Message) -> :: {transport_module, atom()} | {transport_config, any()} | {transport_config, any(), 'Unsigned32'() | infinity} + | {pool_size, pos_integer()} | {applications, [app_alias()]} | {capabilities, [capability()]} | {capabilities_cb, evaluable()} diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl index a2b04bfd63..b4ecb63961 100644 --- a/lib/diameter/src/base/diameter_codec.erl +++ b/lib/diameter/src/base/diameter_codec.erl @@ -390,6 +390,9 @@ sequence_numbers(#diameter_packet{bin = Bin}) sequence_numbers(#diameter_packet{header = #diameter_header{} = H}) -> sequence_numbers(H); +sequence_numbers(#diameter_packet{msg = [#diameter_header{} = H | _]}) -> + sequence_numbers(H); + sequence_numbers(#diameter_header{hop_by_hop_id = H, end_to_end_id = E}) -> {H,E}; @@ -561,14 +564,14 @@ split_data(Bin, Len) -> <<Data:Len/binary, _:Pad/binary, Rest/binary>> -> {Data, Rest}; _ -> - %% Header length points past the end of the message. As - %% stated in the 6733 text above, it's sufficient to - %% return a zero-filled minimal payload if this is a - %% request. Do this (in cases that we know the type) by - %% inducing a decode failure and letting the dictionary's - %% decode (in diameter_gen) deal with it. Here we don't - %% know type. If the type isn't known, then the decode - %% just strips the extra bit. + %% Header length points past the end of the message, or + %% doesn't span the header. As stated in the 6733 text + %% above, it's sufficient to return a zero-filled minimal + %% payload if this is a request. Do this (in cases that we + %% know the type) by inducing a decode failure and letting + %% the dictionary's decode (in diameter_gen) deal with it. + %% Here we don't know type. If the type isn't known, then + %% the decode just strips the extra bit. {<<0:1, Bin/binary>>, <<>>} end. @@ -582,6 +585,8 @@ split_data(Bin, Len) -> %% dictionary doesn't know about specific AVP's. %% Grouped AVP whose components need packing ... +pack_avp([#diameter_avp{} = A | Avps]) -> + pack_avp(A#diameter_avp{data = Avps}); pack_avp(#diameter_avp{data = [#diameter_avp{} | _] = Avps} = A) -> pack_avp(A#diameter_avp{data = encode_avps(Avps)}); diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl index dd1c9b73bb..c0a4f7df69 100644 --- a/lib/diameter/src/base/diameter_config.erl +++ b/lib/diameter/src/base/diameter_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -35,10 +35,11 @@ %% -module(diameter_config). --compile({no_auto_import, [monitor/2]}). - -behaviour(gen_server). +-compile({no_auto_import, [monitor/2, now/0]}). +-import(diameter_lib, [now/0]). + -export([start_service/2, stop_service/1, add_transport/2, @@ -554,6 +555,9 @@ opt({watchdog_config, L}) -> opt({spawn_opt, Opts}) -> is_list(Opts); +opt({pool_size, N}) -> + is_integer(N) andalso 0 < N; + %% Options that we can't validate. opt({K, _}) when K == transport_config; diff --git a/lib/diameter/src/base/diameter_lib.erl b/lib/diameter/src/base/diameter_lib.erl index 5b3a2063f8..d0d730f47c 100644 --- a/lib/diameter/src/base/diameter_lib.erl +++ b/lib/diameter/src/base/diameter_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -18,12 +18,18 @@ %% -module(diameter_lib). +-compile({no_auto_import, [now/0]}). -export([info_report/2, error_report/2, warning_report/2, + now/0, + timestamp/1, now_diff/1, + micro_diff/1, + micro_diff/2, time/1, + seed/0, eval/1, eval_name/1, get_stacktrace/0, @@ -31,6 +37,8 @@ spawn_opts/2, wait/1, fold_tuple/3, + fold_n/3, + for_n/2, log/4]). %% --------------------------------------------------------------------------- @@ -90,13 +98,50 @@ fmt(T) -> end. %% --------------------------------------------------------------------------- +%% # now/0 +%% --------------------------------------------------------------------------- + +-type timestamp() :: {non_neg_integer(), 0..999999, 0..999999}. +-type now() :: integer() %% monotonic time + | timestamp(). + +-spec now() + -> now(). + +%% Use monotonic time if it exists, fall back to erlang:now() +%% otherwise. + +now() -> + try + erlang:monotonic_time() + catch + error: undef -> erlang:now() + end. + +%% --------------------------------------------------------------------------- +%% # timestamp/1 +%% --------------------------------------------------------------------------- + +-spec timestamp(NowT :: now()) + -> timestamp(). + +timestamp({_,_,_} = T) -> %% erlang:now() + T; + +timestamp(MonoT) -> %% monotonic time + MicroSecs = erlang:convert_time_resolution(MonoT + erlang:time_offset(), + erlang:time_resolution(), + 1000000), + Secs = MicroSecs div 1000000, + {Secs div 1000000, Secs rem 1000000, MicroSecs rem 1000000}. + +%% --------------------------------------------------------------------------- %% # now_diff/1 %% --------------------------------------------------------------------------- --spec now_diff(NowT) +-spec now_diff(NowT :: now()) -> {Hours, Mins, Secs, MicroSecs} - when NowT :: {non_neg_integer(), 0..999999, 0..999999}, - Hours :: non_neg_integer(), + when Hours :: non_neg_integer(), Mins :: 0..59, Secs :: 0..59, MicroSecs :: 0..999999. @@ -104,8 +149,41 @@ fmt(T) -> %% Return timer:now_diff(now(), NowT) as an {H, M, S, MicroS} tuple %% instead of as integer microseconds. -now_diff({_,_,_} = Time) -> - time(timer:now_diff(now(), Time)). +now_diff(Time) -> + time(micro_diff(Time)). + +%% --------------------------------------------------------------------------- +%% # micro_diff/1 +%% --------------------------------------------------------------------------- + +-spec micro_diff(NowT :: now()) + -> MicroSecs + when MicroSecs :: non_neg_integer(). + +micro_diff({_,_,_} = T0) -> + timer:now_diff(erlang:now(), T0); + +micro_diff(T0) -> %% monotonic time + erlang:convert_time_resolution(erlang:monotonic_time() - T0, + erlang:time_resolution(), + 1000000). + +%% --------------------------------------------------------------------------- +%% # micro_diff/2 +%% --------------------------------------------------------------------------- + +-spec micro_diff(T1 :: now(), T0 :: now()) + -> MicroSecs + when MicroSecs :: non_neg_integer(). + +micro_diff(T1, T0) + when is_integer(T1), is_integer(T0) -> %% monotonic time + erlang:convert_time_resolution(T1 - T0, + erlang:time_resolution(), + 1000000); + +micro_diff(T1, T0) -> %% at least one erlang:now() + timer:now_diff(timestamp(T1), timestamp(T0)). %% --------------------------------------------------------------------------- %% # time/1 @@ -115,7 +193,7 @@ now_diff({_,_,_} = Time) -> -spec time(NowT | Diff) -> {Hours, Mins, Secs, MicroSecs} - when NowT :: {non_neg_integer(), 0..999999, 0..999999}, + when NowT :: timestamp(), Diff :: non_neg_integer(), Hours :: non_neg_integer(), Mins :: 0..59, @@ -134,6 +212,27 @@ time(Micro) -> %% elapsed time {H, M, S, Micro rem 1000000}. %% --------------------------------------------------------------------------- +%% # seed/0 +%% --------------------------------------------------------------------------- + +-spec seed() + -> {timestamp(), {integer(), integer(), integer()}}. + +%% Return an argument for random:seed/1. + +seed() -> + T = now(), + {timestamp(T), seed(T)}. + +%% seed/1 + +seed({_,_,_} = T) -> + T; + +seed(T) -> %% monotonic time + {erlang:phash2(node()), T, erlang:unique_integer()}. + +%% --------------------------------------------------------------------------- %% # eval/1 %% %% Evaluate a function in various forms. @@ -247,17 +346,19 @@ opts(HeapSize, Opts) -> %% # wait/1 %% --------------------------------------------------------------------------- --spec wait([pid()]) +-spec wait([pid() | reference()]) -> ok. wait(L) -> - down([erlang:monitor(process, P) || P <- L]). + lists:foreach(fun down/1, L). -down([]) -> - ok; -down([MRef|T]) -> - receive {'DOWN', MRef, process, _, _} -> ok end, - down(T). +down(Pid) + when is_pid(Pid) -> + down(monitor(process, Pid)); + +down(MRef) + when is_reference(MRef) -> + receive {'DOWN', MRef, process, _, _} = T -> T end. %% --------------------------------------------------------------------------- %% # fold_tuple/3 @@ -290,6 +391,35 @@ ft(Value, {Idx, T}) -> setelement(Idx, T, Value). %% --------------------------------------------------------------------------- +%% # fold_n/3 +%% --------------------------------------------------------------------------- + +-spec fold_n(F, Acc0, N) + -> term() + when F :: fun((non_neg_integer(), term()) -> term()), + Acc0 :: term(), + N :: non_neg_integer(). + +fold_n(F, Acc, N) + when is_integer(N), 0 < N -> + fold_n(F, F(N, Acc), N-1); + +fold_n(_, Acc, _) -> + Acc. + +%% --------------------------------------------------------------------------- +%% # for_n/2 +%% --------------------------------------------------------------------------- + +-spec for_n(F, N) + -> non_neg_integer() + when F :: fun((non_neg_integer()) -> term()), + N :: non_neg_integer(). + +for_n(F, N) -> + fold_n(fun(M,A) -> F(M), A+1 end, 0, N). + +%% --------------------------------------------------------------------------- %% # log/4 %% %% Called to have something to trace on for happenings of interest. diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl index e5d4b28766..ea326dd03e 100644 --- a/lib/diameter/src/base/diameter_peer.erl +++ b/lib/diameter/src/base/diameter_peer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -18,9 +18,11 @@ %% -module(diameter_peer). - -behaviour(gen_server). +-compile({no_auto_import, [now/0]}). +-import(diameter_lib, [now/0]). + %% Interface towards transport modules ... -export([recv/2, up/1, diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl index 86fc43cdc5..ee6e7dd89e 100644 --- a/lib/diameter/src/base/diameter_peer_fsm.erl +++ b/lib/diameter/src/base/diameter_peer_fsm.erl @@ -225,8 +225,8 @@ start_transport(Addrs0, T) -> erlang:monitor(process, TPid), q_next(TPid, Addrs0, Tmo, Data), {TPid, Addrs}; - No -> - exit({shutdown, No}) + {error, No} -> + exit({shutdown, {no_connection, No}}) end. svc(#diameter_service{capabilities = LCaps0} = Svc, Addrs) -> @@ -368,11 +368,8 @@ transition({diameter, {TPid, connected}}, %% message. This may be followed by an incoming message which arrived %% before the transport was killed and this can't be distinguished %% from one from the transport that's been started to replace it. -transition({diameter, {_, connected}}, _) -> - {stop, connection_timeout}; -transition({diameter, {_, connected, _}}, _) -> - {stop, connection_timeout}; -transition({diameter, {_, connected, _, _}}, _) -> +transition({diameter, T}, _) + when tuple_size(T) < 5, connected == element(2,T) -> {stop, connection_timeout}; %% Connection has timed out: start an alternate. diff --git a/lib/diameter/src/base/diameter_reg.erl b/lib/diameter/src/base/diameter_reg.erl index 3197c1aee1..f785777874 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-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -22,10 +22,11 @@ %% -module(diameter_reg). --compile({no_auto_import, [monitor/2]}). - -behaviour(gen_server). +-compile({no_auto_import, [monitor/2, now/0]}). +-import(diameter_lib, [now/0]). + -export([add/1, add_new/1, del/1, diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index ab56ca9cef..04401a3d87 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -24,6 +24,9 @@ -module(diameter_service). -behaviour(gen_server). +-compile({no_auto_import, [now/0]}). +-import(diameter_lib, [now/0]). + %% towards diameter_service_sup -export([start_link/1]). @@ -610,8 +613,9 @@ st(#watchdog{ref = Ref, pid = Pid}, Refs) -> %% st/3 st(#watchdog{pid = Pid}, Reason, Acc) -> + MRef = monitor(process, Pid), Pid ! {shutdown, self(), Reason}, - [Pid | Acc]. + [MRef | Acc]. %% --------------------------------------------------------------------------- %% # call_service/2 @@ -765,8 +769,9 @@ reason(failure) -> start(Ref, {T, Opts}, S) when T == connect; T == listen -> + N = proplists:get_value(pool_size, Opts, 1), try - {ok, start(Ref, type(T), Opts, S)} + {ok, start(Ref, type(T), Opts, N, S)} catch ?FAILURE(Reason) -> {error, Reason} @@ -784,11 +789,16 @@ type(connect = T) -> T. %% start/4 -start(Ref, Type, Opts, #state{watchdogT = WatchdogT, - peerT = PeerT, - options = SvcOpts, - service_name = SvcName, - service = Svc0}) +start(Ref, Type, Opts, State) -> + start(Ref, Type, Opts, 1, State). + +%% start/5 + +start(Ref, Type, Opts, N, #state{watchdogT = WatchdogT, + peerT = PeerT, + options = SvcOpts, + service_name = SvcName, + service = Svc0}) when Type == connect; Type == accept -> #diameter_service{applications = Apps} @@ -796,14 +806,19 @@ start(Ref, Type, Opts, #state{watchdogT = WatchdogT, = merge_service(Opts, Svc0), {_,_} = Mask = proplists:get_value(sequence, SvcOpts), RecvData = diameter_traffic:make_recvdata([SvcName, PeerT, Apps, Mask]), - Pid = s(Type, Ref, {{spawn_opts([Opts, SvcOpts]), RecvData}, - Opts, - SvcOpts, - Svc}), - insert(WatchdogT, #watchdog{pid = Pid, - type = Type, - ref = Ref, - options = Opts}), + T = {{spawn_opts([Opts, SvcOpts]), RecvData}, Opts, SvcOpts, Svc}, + Rec = #watchdog{type = Type, + ref = Ref, + options = Opts}, + diameter_lib:fold_n(fun(_,A) -> + [wd(Type, Ref, T, WatchdogT, Rec) | A] + end, + [], + N). + +wd(Type, Ref, T, WatchdogT, Rec) -> + Pid = wd(Type, Ref, T), + insert(WatchdogT, Rec#watchdog{pid = Pid}), Pid. %% Note that the service record passed into the watchdog is the merged @@ -816,7 +831,7 @@ spawn_opts(Optss) -> T /= link, T /= monitor]. -s(Type, Ref, T) -> +wd(Type, Ref, T) -> {_MRef, Pid} = diameter_watchdog:start({Type, Ref}, T), Pid. @@ -1185,7 +1200,7 @@ connect_timer(Opts, Def0) -> %% 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, + orelse diameter_lib:micro_diff(Time) > 1000*?RESTART_TC, Tc, ?RESTART_TC). @@ -1460,42 +1475,52 @@ pick_peer(Local, peers(Alias, RH, Filter, Peers) -> case ?Dict:find(Alias, Peers) of {ok, L} -> - ps(L, RH, Filter, {[],[]}); + filter(L, RH, Filter); error -> [] end. -%% Place a peer whose Destination-Host/Realm matches those of the -%% request at the front of the result list. Could add some sort of -%% 'sort' option to allow more control. - -ps([], _, _, {Ys, Ns}) -> - lists:reverse(Ys, Ns); -ps([{_TPid, #diameter_caps{} = Caps} = TC | Rest], RH, Filter, Acc) -> - ps(Rest, RH, Filter, pacc(caps_filter(Caps, RH, Filter), - caps_filter(Caps, RH, {all, [host, realm]}), - TC, - Acc)). - -pacc(true, true, Peer, {Ts, Fs}) -> - {[Peer|Ts], Fs}; -pacc(true, false, Peer, {Ts, Fs}) -> - {Ts, [Peer|Fs]}; -pacc(_, _, _, Acc) -> - Acc. +%% filter/3 +%% +%% Return peers in match order. -%% caps_filter/3 +filter(Peers, RH, Filter) -> + {Ts, _} = fltr(Peers, RH, Filter), + Ts. -caps_filter(C, RH, {neg, F}) -> - not caps_filter(C, RH, F); +%% fltr/4 -caps_filter(C, RH, {all, L}) +fltr(Peers, _, none) -> + {Peers, []}; + +fltr(Peers, RH, {neg, F}) -> + {Ts, Fs} = fltr(Peers, RH, F), + {Fs, Ts}; + +fltr(Peers, RH, {all, L}) when is_list(L) -> - lists:all(fun(F) -> caps_filter(C, RH, F) end, L); + lists:foldl(fun(F,A) -> fltr_all(F, A, RH) end, + {Peers, []}, + L); -caps_filter(C, RH, {any, L}) +fltr(Peers, RH, {any, L}) when is_list(L) -> - lists:any(fun(F) -> caps_filter(C, RH, F) end, L); + lists:foldl(fun(F,A) -> fltr_any(F, A, RH) end, + {[], Peers}, + L); + +fltr(Peers, RH, F) -> + lists:partition(fun({_,C}) -> caps_filter(C, RH, F) end, Peers). + +fltr_all(F, {Ts0, Fs0}, RH) -> + {Ts1, Fs1} = fltr(Ts0, RH, F), + {Ts1, Fs0 ++ Fs1}. + +fltr_any(F, {Ts0, Fs0}, RH) -> + {Ts1, Fs1} = fltr(Fs0, RH, F), + {Ts0 ++ Ts1, Fs1}. + +%% caps_filter/3 caps_filter(#diameter_caps{origin_host = {_,OH}}, [_,DH], host) -> eq(undefined, DH, OH); @@ -1508,9 +1533,6 @@ caps_filter(C, _, Filter) -> %% caps_filter/2 -caps_filter(_, none) -> - true; - caps_filter(#diameter_caps{origin_host = {_,OH}}, {host, H}) -> eq(any, H, OH); @@ -1711,31 +1733,43 @@ info_transport(S) -> [], PeerD). -%% Only a config entry for a listening transport: use it. -transport([[{type, listen}, _] = L]) -> - L ++ [{accept, []}]; - -%% Only one config or peer entry for a connecting transport: use it. -transport([[{type, connect} | _] = L]) -> - L; +%% Single config entry. Distinguish between pool_size config or not on +%% a connecting transport for backwards compatibility: with the option +%% the form is similar to the listening case, with connections grouped +%% in a pool tuple (for lack of a better name), without as before. +transport([[{type, Type}, {options, Opts}] = L]) + when Type == listen; + Type == connect -> + L ++ [{K, []} || [{_,K}] <- [keys(Type, Opts)]]; %% Peer entries: discard config. Note that the peer entries have %% length at least 3. transport([[_,_] | L]) -> transport(L); -%% Possibly many peer entries for a listening transport. Note that all -%% have the same options by construction, which is not terribly space -%% efficient. -transport([[{type, accept}, {options, Opts} | _] | _] = Ls) -> - [{type, listen}, +%% Multiple tranports. Note that all have the same options by +%% construction, which is not terribly space efficient. +transport([[{type, Type}, {options, Opts} | _] | _] = Ls) -> + transport(keys(Type, Opts), Ls). + +%% Group transports in an accept or pool tuple ... +transport([{Type, Key}], [[{type, _}, {options, Opts} | _] | _] = Ls) -> + [{type, Type}, {options, Opts}, - {accept, [lists:nthtail(2,L) || L <- Ls]}]. + {Key, [tl(tl(L)) || L <- Ls]}]; + +%% ... or not: there can only be one. +transport([], [L]) -> + L. + +keys(connect = T, Opts) -> + [{T, pool} || lists:keymember(pool_size, 1, Opts)]; +keys(_, _) -> + [{listen, accept}]. peer_dict(#state{watchdogT = WatchdogT, peerT = PeerT}, Dict0) -> try ets:tab2list(WatchdogT) of - L -> - lists:foldl(fun(T,A) -> peer_acc(PeerT, A, T) end, Dict0, L) + L -> lists:foldl(fun(T,A) -> peer_acc(PeerT, A, T) end, Dict0, L) catch error: badarg -> Dict0 %% service has gone down end. diff --git a/lib/diameter/src/base/diameter_service_sup.erl b/lib/diameter/src/base/diameter_service_sup.erl index 153fff902f..e3177f0083 100644 --- a/lib/diameter/src/base/diameter_service_sup.erl +++ b/lib/diameter/src/base/diameter_service_sup.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -58,7 +58,7 @@ init([]) -> ChildSpec = {Mod, {Mod, start_link, []}, temporary, - 1000, + 5000, worker, [Mod]}, {ok, {Flags, [ChildSpec]}}. diff --git a/lib/diameter/src/base/diameter_session.erl b/lib/diameter/src/base/diameter_session.erl index 3b236f109a..c5ea0428b5 100644 --- a/lib/diameter/src/base/diameter_session.erl +++ b/lib/diameter/src/base/diameter_session.erl @@ -157,8 +157,8 @@ session_id(Host) -> %% --------------------------------------------------------------------------- init() -> - Now = now(), - random:seed(Now), + {Now, Seed} = diameter_lib:seed(), + random:seed(Seed), Time = time32(Now), Seq = (?INT32 band (Time bsl 20)) bor (random:uniform(1 bsl 20) - 1), ets:insert(diameter_sequence, [{origin_state_id, Time}, diff --git a/lib/diameter/src/base/diameter_stats.erl b/lib/diameter/src/base/diameter_stats.erl index 8353613d32..64ea082be0 100644 --- a/lib/diameter/src/base/diameter_stats.erl +++ b/lib/diameter/src/base/diameter_stats.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -22,9 +22,11 @@ %% -module(diameter_stats). - -behaviour(gen_server). +-compile({no_auto_import, [now/0]}). +-import(diameter_lib, [now/0]). + -export([reg/2, reg/1, incr/3, incr/1, read/1, diff --git a/lib/diameter/src/base/diameter_sup.erl b/lib/diameter/src/base/diameter_sup.erl index e5afd23dcd..4ede4086d8 100644 --- a/lib/diameter/src/base/diameter_sup.erl +++ b/lib/diameter/src/base/diameter_sup.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -64,7 +64,7 @@ spec(Mod) -> {Mod, {Mod, start_link, []}, permanent, - 1000, + infinity, supervisor, [Mod]}. diff --git a/lib/diameter/src/base/diameter_sync.erl b/lib/diameter/src/base/diameter_sync.erl index ce2db4b3a2..90eabece3d 100644 --- a/lib/diameter/src/base/diameter_sync.erl +++ b/lib/diameter/src/base/diameter_sync.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -27,6 +27,9 @@ -module(diameter_sync). -behaviour(gen_server). +-compile({no_auto_import, [now/0]}). +-import(diameter_lib, [now/0]). + -export([call/4, call/5, cast/4, cast/5, carp/1, carp/2]). diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index 280d09d7e8..0b503338a6 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -162,24 +162,28 @@ incr_error(Dir, Id, TPid) -> %% incr_rc/4 %% --------------------------------------------------------------------------- --spec incr_rc(send|recv, Pkt, TPid, Dict0) +-spec incr_rc(send|recv, Pkt, TPid, DictT) -> {Counter, non_neg_integer()} | Reason when Pkt :: #diameter_packet{}, TPid :: pid(), - Dict0 :: module(), + DictT :: module() | {module(), module(), module()}, Counter :: {'Result-Code', integer()} | {'Experimental-Result', integer(), integer()}, Reason :: atom(). -incr_rc(Dir, Pkt, TPid, Dict0) -> +incr_rc(Dir, Pkt, TPid, {Dict, _, _} = DictT) -> try - incr_result(Dir, Pkt, TPid, {Dict0, Dict0, Dict0}) + incr_result(Dir, Pkt, TPid, DictT) catch exit: {E,_} when E == no_result_code; E == invalid_error_bit -> + incr(TPid, {msg_id(Pkt#diameter_packet.header, Dict), Dir, E}), E - end. + end; + +incr_rc(Dir, Pkt, TPid, Dict0) -> + incr_rc(Dir, Pkt, TPid, {Dict0, Dict0, Dict0}). %% --------------------------------------------------------------------------- %% pending/1 @@ -678,7 +682,7 @@ local(Msg, TPid, {Dict, AppDict, Dict0} = DictT, Fs, ReqPkt) -> reset(make_answer_packet(Msg, ReqPkt), Dict, Dict0), Fs), incr(send, Pkt, TPid, AppDict), - incr_result(send, Pkt, TPid, DictT), %% count outgoing + incr_rc(send, Pkt, TPid, DictT), %% count outgoing send(TPid, Pkt). %% reset/3 @@ -1388,6 +1392,21 @@ make_request_packet(#diameter_packet{header = Hdr} = Pkt, make_request_packet(Msg, Pkt) -> Pkt#diameter_packet{msg = Msg}. +%% make_retransmit_packet/2 + +make_retransmit_packet(#diameter_packet{msg = [#diameter_header{} = Hdr + | Avps]} + = Pkt) -> + Pkt#diameter_packet{msg = [make_retransmit_header(Hdr) | Avps]}; + +make_retransmit_packet(#diameter_packet{header = Hdr} = Pkt) -> + Pkt#diameter_packet{header = make_retransmit_header(Hdr)}. + +%% make_retransmit_header/1 + +make_retransmit_header(Hdr) -> + Hdr#diameter_header{is_retransmitted = true}. + %% fold_record/2 fold_record(undefined, R) -> @@ -1484,7 +1503,7 @@ handle_A(Pkt, SvcName, Dict, Dict0, App, #request{transport = TPid} = Req) -> %% a missing AVP. If both are optional in the dictionary %% then this isn't a decode error: just continue on. answer(Pkt, SvcName, App, Req); - exit: {invalid_error_bit, RC} -> + exit: {invalid_error_bit, {_, _, _, RC}} -> #diameter_packet{errors = Es} = Pkt, E = {5004, #diameter_avp{name = 'Result-Code', value = RC}}, @@ -1632,12 +1651,23 @@ send_request(TPid, #diameter_packet{} = Pkt, Req, SvcName, Timeout) -> %% send/1 -send({TPid, Pkt, #request{handler = Pid} = Req, SvcName, Timeout, TRef}) -> - Ref = send_request(TPid, - Pkt, - Req#request{handler = self()}, - SvcName, - Timeout), +send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) -> + Seqs = diameter_codec:sequence_numbers(Pkt), + Req = Req0#request{handler = self()}, + Ref = send_request(TPid, Pkt, Req, SvcName, Timeout), + + try + recv(TPid, Pid, TRef, Ref) + after + %% Remove only the entry for this specific send since a resend + %% from the originating node can pick another transport on + %% this one. + ets:delete_object(?REQUEST_TABLE, {Seqs, Req, Ref}) + end. + +%% recv/4 + +recv(TPid, Pid, TRef, Ref) -> receive {answer, _, _, _, _} = A -> Pid ! A; @@ -1663,9 +1693,7 @@ retransmit({TPid, Caps, App} have_request(Pkt0, TPid) %% Don't failover to a peer we've andalso ?THROW(timeout), %% already sent to. - #diameter_packet{header = Hdr0} = Pkt0, - Hdr = Hdr0#diameter_header{is_retransmitted = true}, - Pkt = Pkt0#diameter_packet{header = Hdr}, + Pkt = make_retransmit_packet(Pkt0), retransmit(cb(App, prepare_retransmit, [Pkt, SvcName, {TPid, Caps}]), Transport, diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl index ca3338be5f..442d90c98b 100644 --- a/lib/diameter/src/base/diameter_types.erl +++ b/lib/diameter/src/base/diameter_types.erl @@ -75,7 +75,7 @@ %% message indicating this error MUST include the offending AVPs %% within a Failed-AVP AVP. %% --define(INVALID_LENGTH(Bin), erlang:error({'DIAMETER', 5014, Bin})). +-define(INVALID_LENGTH(Bitstr), erlang:error({'DIAMETER', 5014, Bitstr})). %% ------------------------------------------------------------------------- %% 3588, 4.2. Basic AVP Data Formats diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl index eff5096745..67715906e8 100644 --- a/lib/diameter/src/base/diameter_watchdog.erl +++ b/lib/diameter/src/base/diameter_watchdog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -122,7 +122,8 @@ i({Ack, T, Pid, {RecvData, = Svc}}) -> erlang:monitor(process, Pid), wait(Ack, Pid), - random:seed(now()), + {_, Seed} = diameter_lib:seed(), + random:seed(Seed), putr(restart, {T, Opts, Svc}), %% save seeing it in trace putr(dwr, dwr(Caps)), %% {_,_} = Mask = proplists:get_value(sequence, SvcOpts), @@ -255,11 +256,15 @@ close({'DOWN', _, process, TPid, {shutdown, Reason}}, close(_, _) -> ok. -event(_, #watchdog{status = T}, #watchdog{status = T}) -> - ok; - -event(_, #watchdog{transport = undefined}, #watchdog{transport = undefined}) -> +event(_, + #watchdog{status = From, transport = F}, + #watchdog{status = To, transport = T}) + when F == undefined, T == undefined; %% transport not started + From == initial, To == down; %% never really left INITIAL + From == To -> %% no state transition ok; +%% Note that there is no INITIAL -> DOWN transition in RFC 3539: ours +%% is just a consequence of stop. event(Msg, #watchdog{status = From, transport = F, parent = Pid}, @@ -411,7 +416,7 @@ transition({'DOWN', _, process, TPid, _Reason}, stop; %% ... or not. -transition({'DOWN', _, process, TPid, _Reason}, +transition({'DOWN', _, process, TPid, _Reason} = D, #watchdog{transport = TPid, status = T, restrict = {_,R}} @@ -422,20 +427,14 @@ transition({'DOWN', _, process, TPid, _Reason}, %% Close an accepting watchdog immediately if there's no %% restriction on the number of connections to the same peer: the - %% state machine never enters state REOPEN in this case. The - %% 'close' message (instead of stop) is so as not to bypass the - %% sending of messages to the service process in handle_info/2. - - if T /= initial, M == accept, not R -> - send(self(), close), - S#watchdog{status = down}; - T /= initial -> - set_watchdog(S#watchdog{status = down}); - M == connect -> - set_watchdog(S); - M == accept -> - send(self(), close), - S + %% state machine never enters state REOPEN in this case. + + if T == initial; + M == accept, not R -> + close(D, S0), + stop; + true -> + set_watchdog(S#watchdog{status = down}) end; %% Incoming message. diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src index 40580e3ce6..881d25b5fb 100644 --- a/lib/diameter/src/diameter.appup.src +++ b/lib/diameter/src/diameter.appup.src @@ -55,7 +55,11 @@ {load_module, diameter_gen_base_accounting}, {load_module, diameter_gen_relay}, {load_module, diameter_traffic}, - {load_module, diameter_peer_fsm}]} + {load_module, diameter_peer_fsm}]}, + {"1.7.1", [{load_module, diameter_traffic}, %% 17.3 + {load_module, diameter_watchdog}, + {load_module, diameter_peer_fsm}, + {load_module, diameter_service}]} ], [ {"0.9", [{restart_application, diameter}]}, @@ -93,6 +97,10 @@ {load_module, diameter_gen_acct_rfc6733}, {load_module, diameter_gen_base_rfc6733}, {load_module, diameter_codec}, - {load_module, diameter_service}]} + {load_module, diameter_service}]}, + {"1.7.1", [{load_module, diameter_service}, + {load_module, diameter_peer_fsm}, + {load_module, diameter_watchdog}, + {load_module, diameter_traffic}]} ] }. diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk index a2a7a51892..c9dd4e683a 100644 --- a/lib/diameter/src/modules.mk +++ b/lib/diameter/src/modules.mk @@ -1,7 +1,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2010-2014. All Rights Reserved. +# Copyright Ericsson AB 2010-2015. 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 @@ -94,7 +94,7 @@ BINS = \ # Released files relative to ../examples. EXAMPLES = \ code/GNUmakefile \ - code/peer.erl \ + code/node.erl \ code/client.erl \ code/client_cb.erl \ code/server.erl \ diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl index 32e7aaca39..2c8d6f0a14 100644 --- a/lib/diameter/src/transport/diameter_sctp.erl +++ b/lib/diameter/src/transport/diameter_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -18,9 +18,11 @@ %% -module(diameter_sctp). - -behaviour(gen_server). +-compile({no_auto_import, [now/0]}). +-import(diameter_lib, [now/0]). + %% interface -export([start/3]). @@ -37,7 +39,8 @@ code_change/3, terminate/2]). --export([info/1]). %% service_info callback +-export([listener/1,%% diameter_sync callback + info/1]). %% service_info callback -export([ports/0, ports/1]). @@ -99,22 +102,31 @@ -record(listener, {ref :: reference(), socket :: gen_sctp:sctp_socket(), - count = 0 :: uint(), + count = 0 :: uint(), %% attached transport processes tmap = ets:new(?MODULE, []) :: ets:tid(), %% {MRef, Pid|AssocId}, {AssocId, Pid} pending = {0, ets:new(?MODULE, [ordered_set])}, tref :: reference(), accept :: [match()]}). %% Field tmap is used to map an incoming message or event to the -%% relevent transport process. Field pending implements a queue of -%% transport processes to which an association has been assigned (at -%% comm_up and written into tmap) but for which diameter hasn't yet -%% spawned a transport process: a short-lived state of affairs as a -%% new transport is spawned as a consequence of a peer being taken up, -%% transport processes being spawned by the listener on demand. In -%% case diameter starts a transport before comm_up on a new -%% association, pending is set to an improper list with the spawned -%% transport as head and the queue as tail. +%% relevant transport process. Field pending implements two queues: +%% the first of transport-to-be processes to which an association has +%% been assigned (at comm_up and written into tmap) but for which +%% diameter hasn't yet spawned a transport process, a short-lived +%% state of affairs as a new transport is spawned as a consequence of +%% a peer being taken up, transport processes being spawned by the +%% listener on demand; the second of started transport processes that +%% have not yet been assigned an association. +%% +%% When diameter calls start/3, the transport process is either taken +%% from the first queue or spawned and placed in the second queue +%% until an association is established. When an association is +%% established, a controlling process is either taken from the second +%% queue or spawned and placed in the first queue. Thus, there are +%% only elements in one queue at a time, so share an ets table queue +%% and tag it with a positive length if it contains the first queue, a +%% negative length if it contains the second queue. The case -1 is +%% handled differently for backwards compatibility reasons. %% --------------------------------------------------------------------------- %% # start/3 @@ -139,9 +151,9 @@ ip(T) -> T. %% A listener spawns transports either as a consequence of this call -%% when there is not yet an association to associate with it, or at -%% comm_up on a new association in which case the call retrieves a -%% transport from the pending queue. +%% when there is not yet an association to assign it, or at comm_up on +%% a new association in which case the call retrieves a transport from +%% the pending queue. s({accept, Ref} = A, Addrs, Opts) -> {LPid, LAs} = listener(Ref, {Opts, Addrs}), try gen_server:call(LPid, {A, self()}, infinity) of @@ -226,7 +238,7 @@ i({connect, Pid, Opts, Addrs, Ref}) -> {LAs, Sock} = open(Addrs, Rest, 0), putr(?REF_KEY, Ref), proc_lib:init_ack({ok, self(), LAs}), - erlang:monitor(process, Pid), + monitor(process, Pid), #transport{parent = Pid, mode = {connect, connect(Sock, RAs, RP, [])}, socket = Sock}; @@ -236,8 +248,8 @@ i({accept, Pid, LPid, Sock, Ref}) when is_pid(Pid) -> putr(?REF_KEY, Ref), proc_lib:init_ack({ok, self()}), - erlang:monitor(process, Pid), - erlang:monitor(process, LPid), + monitor(process, Pid), + monitor(process, LPid), #transport{parent = Pid, mode = {accept, LPid}, socket = Sock}; @@ -246,7 +258,7 @@ i({accept, Pid, LPid, Sock, Ref}) i({accept, Ref, LPid, Sock, Id}) -> putr(?REF_KEY, Ref), proc_lib:init_ack({ok, self()}), - MRef = erlang:monitor(process, LPid), + MRef = monitor(process, LPid), %% Wait for a signal that the transport has been started before %% processing other messages. receive @@ -270,15 +282,23 @@ close(Sock, Id) -> %% listener/2 +%% Accepting processes can be started concurrently: ensure only one +%% listener is started. listener(LRef, T) -> + diameter_sync:call({?MODULE, listener, LRef}, + {?MODULE, listener, [{LRef, T}]}, + infinity, + infinity). + +listener({LRef, T}) -> l(diameter_reg:match({?MODULE, listener, {LRef, '_'}}), LRef, T). -%% Existing process with the listening socket ... +%% Existing listening process ... l([{{?MODULE, listener, {_, AS}}, LPid}], _, _) -> - {LAs, _Sock} = AS, - {LPid, LAs}; - -%% ... or not: start one. + {LAs, _Sock} = AS, + {LPid, LAs}; + +%% ... or not. l([], LRef, T) -> {ok, LPid, LAs} = diameter_sctp_sup:start_child({listen, LRef, T}), {LPid, LAs}. @@ -347,11 +367,17 @@ type(T) -> %% # handle_call/3 %% --------------------------------------------------------------------------- +handle_call(T, From, #listener{pending = L} = S) + when is_list(L) -> + handle_call(T, From, upgrade(S)); + handle_call({{accept, Ref}, Pid}, _, #listener{ref = Ref, - count = N} + pending = {N,Q}, + count = K} = S) -> - {TPid, NewS} = accept(Ref, Pid, S), - {reply, {ok, TPid}, NewS#listener{count = N+1}}; + TPid = accept(Ref, Pid, S), + {reply, {ok, TPid}, downgrade(S#listener{pending = {N-1,Q}, + count = K+1})}; handle_call(_, _, State) -> {reply, nok, State}. @@ -370,8 +396,46 @@ handle_cast(_, State) -> handle_info(T, #transport{} = S) -> {noreply, #transport{} = t(T,S)}; +handle_info(T, #listener{pending = L} = S) + when is_list(L) -> + handle_info(T, upgrade(S)); + handle_info(T, #listener{} = S) -> - {noreply, #listener{} = l(T,S)}. + {noreply, downgrade(#listener{} = l(T,S))}. + +%% upgrade/1 + +upgrade(#listener{pending = [TPid | {0,Q}]} = S) -> + ets:insert(Q, {TPid, now()}), + S#listener{pending = {-1,Q}}. +%% Prior to the possiblity of setting pool_size on in transport +%% configuration, a new accepting transport was only started following +%% the death of a predecessor, so that there was only at most one +%% previously started transport process waiting for an association. +%% This assumption no longer holds with pool_size > 1, in which case +%% several accepting transports are started concurrently. Deal with +%% this by placing the started transports in a new queue of transport +%% processes waiting for an association. +%% +%% Since only one of this queue and the existing queue of controlling +%% processes waiting for a transport to be started can be non-empty at +%% any given time, implement both queues in the same ets table. The +%% absolute value of the first element of the 2-tuple is the queue +%% length, the sign says which queue it is. + +%% downgrade/1 +%% +%% Revert to the pre-pool_size representation when possible, for +%% backwards compatibility in the case that the pool_size option +%% hasn't been used. + +downgrade(#listener{pending = {-1,Q}} = S) -> + TPid = ets:first(Q), + ets:delete(Q, TPid), + S#listener{pending = [TPid | {0,Q}]}; + +downgrade(S) -> + S. %% --------------------------------------------------------------------------- %% # code_change/3 @@ -436,54 +500,46 @@ l({sctp, Sock, _RA, _RP, Data} = Msg, #listener{socket = Sock} = S) -> setopts(Sock) end; -%% Transport is asking message to be sent. See send/3 for why the send -%% isn't directly from the transport. -l({send, AssocId, StreamId, Bin}, #listener{socket = Sock} = S) -> - send(Sock, AssocId, StreamId, Bin), - S; +l({'DOWN', MRef, process, TPid, _}, #listener{pending = {_,Q}} = S) -> + down(ets:member(Q, TPid), MRef, TPid, S); + +%% Timeout after the last accepting process has died. +l({timeout, TRef, close = T}, #listener{tref = TRef, + count = 0}) -> + x(T); +l({timeout, _, close}, #listener{} = S) -> + S. + +%% down/4 %% Accepting transport has died. One that's awaiting an association ... -l({'DOWN', MRef, process, TPid, _}, #listener{pending = [TPid | Q], - tmap = T, - count = N} - = S) -> +down(true, MRef, TPid, #listener{pending = {N,Q}, + tmap = T, + count = K} + = S) + when N < 0 -> + ets:delete(Q, TPid), ets:delete(T, MRef), ets:delete(T, TPid), - start_timer(S#listener{count = N-1, - pending = Q}); - -%% ... ditto and a new transport has already been started ... -l({'DOWN', _, process, _, _} = T, #listener{pending = [TPid | Q]} - = S) -> - #listener{pending = NQ} - = NewS - = l(T, S#listener{pending = Q}), - NewS#listener{pending = [TPid | NQ]}; - -%% ... or not. -l({'DOWN', MRef, process, TPid, _}, #listener{socket = Sock, - tmap = T, - count = N, - pending = {P,Q}} - = S) -> + start_timer(S#listener{count = K-1, + pending = {N+1,Q}}); + +%% ... or one that already has one. +down(B, MRef, TPid, #listener{socket = Sock, + tmap = T, + count = K, + pending = {N,Q}} + = S) -> [{MRef, Id}] = ets:lookup(T, MRef), %% Id = TPid | AssocId ets:delete(T, MRef), ets:delete(T, Id), Id == TPid orelse close(Sock, Id), - case ets:lookup(Q, TPid) of - [{TPid, _}] -> %% transport in the pending queue ... + if B -> %% Waiting for attachment in the pending queue ... ets:delete(Q, TPid), - S#listener{pending = {P-1, Q}}; - [] -> %% ... or not - start_timer(S#listener{count = N-1}) - end; - -%% Timeout after the last accepting process has died. -l({timeout, TRef, close = T}, #listener{tref = TRef, - count = 0}) -> - x(T); -l({timeout, _, close}, #listener{} = S) -> - S. + S#listener{pending = {N-1,Q}}; + true -> %% ... or already attached + start_timer(S#listener{count = K-1}) + end. %% t/2 %% @@ -582,29 +638,24 @@ accept(Opts) -> %% No pending associations: spawn a new transport. accept(Ref, Pid, #listener{socket = Sock, tmap = T, - pending = {0,_} = Q} - = S) -> + pending = {N,Q}}) + when N =< 0 -> Arg = {accept, Pid, self(), Sock, Ref}, {ok, TPid} = diameter_sctp_sup:start_child(Arg), - MRef = erlang:monitor(process, TPid), + MRef = monitor(process, TPid), ets:insert(T, [{MRef, TPid}, {TPid, MRef}]), - {TPid, S#listener{pending = [TPid | Q]}}; -%% Placing the transport in the pending field makes it available to -%% the next association. The stack starts a new accepting transport -%% only after this one brings the connection up (or dies). - -%% Accepting transport has died. This can happen if a new transport is -%% started before the DOWN has arrived. -accept(Ref, Pid, #listener{pending = [TPid | {0,_} = Q]} = S) -> - false = is_process_alive(TPid), %% assert - accept(Ref, Pid, S#listener{pending = Q}); + ets:insert(Q, {TPid, now()}), + TPid; +%% Placing the transport in the second pending table makes it +%% available to the next association. %% Pending associations: attach to the first in the queue. -accept(_, Pid, #listener{ref = Ref, pending = {N,Q}} = S) -> +accept(_, Pid, #listener{ref = Ref, + pending = {_,Q}}) -> TPid = ets:first(Q), TPid ! {Ref, Pid}, ets:delete(Q, TPid), - {TPid, S#listener{pending = {N-1, Q}}}. + TPid. %% send/2 @@ -718,34 +769,12 @@ up(#transport{parent = Pid, find(Id, Data, #listener{tmap = T} = S) -> f(ets:lookup(T, Id), Data, S). -%% New association and a transport waiting for one: use it. -f([], - {_, #sctp_assoc_change{state = comm_up, - assoc_id = Id}}, - #listener{tmap = T, - pending = [TPid | {_,_} = Q]} - = S) -> - [{TPid, MRef}] = ets:lookup(T, TPid), - ets:insert(T, [{MRef, Id}, {Id, TPid}]), - ets:delete(T, TPid), - {TPid, S#listener{pending = Q}}; - -%% New association and no transport start yet: spawn one and place it -%% in the queue. +%% New association ... f([], - {_, #sctp_assoc_change{state = comm_up, - assoc_id = Id}}, - #listener{ref = Ref, - socket = Sock, - tmap = T, - pending = {N,Q}} + {_, #sctp_assoc_change{state = comm_up, assoc_id = Id}}, + #listener{pending = {N,Q}} = S) -> - Arg = {accept, Ref, self(), Sock, Id}, - {ok, TPid} = diameter_sctp_sup:start_child(Arg), - MRef = erlang:monitor(process, TPid), - ets:insert(T, [{MRef, Id}, {Id, TPid}]), - ets:insert(Q, {TPid, now()}), - {TPid, S#listener{pending = {N+1, Q}}}; + {find(Id, S), S#listener{pending = {N+1,Q}}}; %% Known association ... f([{_, TPid}], _, S) -> @@ -755,6 +784,31 @@ f([{_, TPid}], _, S) -> f([], _, _) -> false. +%% find/2 + +%% Transport waiting for an association: use it. +find(Id, #listener{tmap = T, + pending = {N,Q}}) + when N < 0 -> + TPid = ets:first(Q), + [{TPid, MRef}] = ets:lookup(T, TPid), + ets:insert(T, [{MRef, Id}, {Id, TPid}]), + ets:delete(T, TPid), + ets:delete(Q, TPid), + TPid; + +%% No transport start yet: spawn one and queue. +find(Id, #listener{ref = Ref, + socket = Sock, + tmap = T, + pending = {_,Q}}) -> + Arg = {accept, Ref, self(), Sock, Id}, + {ok, TPid} = diameter_sctp_sup:start_child(Arg), + MRef = monitor(process, TPid), + ets:insert(T, [{MRef, Id}, {Id, TPid}]), + ets:insert(Q, {TPid, now()}), + TPid. + %% assoc_id/1 assoc_id({[#sctp_sndrcvinfo{assoc_id = Id}], _}) -> diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl index 4d1b8bec51..0b26f429fb 100644 --- a/lib/diameter/src/transport/diameter_tcp.erl +++ b/lib/diameter/src/transport/diameter_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -37,7 +37,8 @@ code_change/3, terminate/2]). --export([info/1]). %% service_info callback +-export([listener/1,%% diameter_sync callback + info/1]). %% service_info callback -export([ports/0, ports/1]). @@ -191,7 +192,7 @@ init(T) -> i({T, Ref, Mod, Pid, Opts, Addrs}) when T == accept; T == connect -> - erlang:monitor(process, Pid), + monitor(process, Pid), %% Since accept/connect might block indefinitely, spawn a process %% that does nothing but kill us with the parent until call %% returns. @@ -218,8 +219,8 @@ i({T, Ref, Mod, Pid, Opts, Addrs}) %% A monitor process to kill the transport if the parent dies. i(#monitor{parent = Pid, transport = TPid} = S) -> proc_lib:init_ack({ok, self()}), - erlang:monitor(process, Pid), - erlang:monitor(process, TPid), + monitor(process, Pid), + monitor(process, TPid), S; %% In principle a link between the transport and killer processes %% could do the same thing: have the accepting/connecting process be @@ -235,7 +236,7 @@ i({listen, LRef, APid, {Mod, Opts, Addrs}}) -> LAddr = laddr(LAddrOpt, Mod, LSock), true = diameter_reg:add_new({?MODULE, listener, {LRef, {LAddr, LSock}}}), proc_lib:init_ack({ok, self(), {LAddr, LSock}}), - erlang:monitor(process, APid), + monitor(process, APid), start_timer(#listener{socket = LSock}). laddr([], Mod, Sock) -> @@ -336,17 +337,25 @@ accept(Opts) -> %% listener/2 +%% Accepting processes can be started concurrently: ensure only one +%% listener is started. listener(LRef, T) -> - l(diameter_reg:match({?MODULE, listener, {LRef, '_'}}), LRef, T). + diameter_sync:call({?MODULE, listener, LRef}, + {?MODULE, listener, [{LRef, T, self()}]}, + infinity, + infinity). -%% Existing process with the listening socket ... -l([{{?MODULE, listener, {_, AS}}, LPid}], _, _) -> - LPid ! {accept, self()}, +listener({LRef, T, TPid}) -> + l(diameter_reg:match({?MODULE, listener, {LRef, '_'}}), LRef, T, TPid). + +%% Existing listening process ... +l([{{?MODULE, listener, {_, AS}}, LPid}], _, _, TPid) -> + LPid ! {accept, TPid}, AS; -%% ... or not: start one. -l([], LRef, T) -> - {ok, _, AS} = diameter_tcp_sup:start_child({listen, LRef, self(), T}), +%% ... or not. +l([], LRef, T, TPid) -> + {ok, _, AS} = diameter_tcp_sup:start_child({listen, LRef, TPid, T}), AS. %% get_addr/1 @@ -502,7 +511,7 @@ m({'DOWN', _, process, Pid, _}, #monitor{parent = Pid, %% Another accept transport is attaching. l({accept, TPid}, #listener{count = N} = S) -> - erlang:monitor(process, TPid), + monitor(process, TPid), S#listener{count = N+1}; %% Accepting process has died. diff --git a/lib/diameter/src/transport/diameter_transport_sup.erl b/lib/diameter/src/transport/diameter_transport_sup.erl index 6457ab78b0..284a41a752 100644 --- a/lib/diameter/src/transport/diameter_transport_sup.erl +++ b/lib/diameter/src/transport/diameter_transport_sup.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -54,7 +54,7 @@ start_child(Name, Module) -> Spec = {Name, {Module, start_link, [Name]}, permanent, - 1000, + infinity, supervisor, [Module]}, supervisor:start_child(?MODULE, Spec). diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl index f68a18b5c2..cf34c762e1 100644 --- a/lib/diameter/test/diameter_app_SUITE.erl +++ b/lib/diameter/test/diameter_app_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -187,15 +187,14 @@ xref(Config) -> xref:stop(XRef), + Rel = release(), %% otp_release-ish + %% Only care about calls from our own application. - [] = lists:filter(fun({{F,_,_},{T,_,_}}) -> + [] = lists:filter(fun({{F,_,_} = From, {_,_,_} = To}) -> lists:member(F, Mods) - andalso {F,T} /= {diameter_tcp, ssl} + andalso not ignored(From, To, Rel) end, Undefs), - %% diameter_tcp does call ssl despite the latter not being listed - %% as a dependency in the app file since ssl is only required for - %% TLS security: it's up to a client who wants TLS to start ssl. %% Ensure that only runtime or info modules call runtime modules. %% It's not strictly necessary that diameter compiler modules not @@ -214,6 +213,38 @@ xref(Config) -> [] = lists:filter(fun(M) -> not lists:member(app(M), Deps) end, RTdeps -- Mods). +ignored({FromMod,_,_}, {ToMod,_,_} = To, Rel)-> + %% diameter_tcp does call ssl despite the latter not being listed + %% as a dependency in the app file since ssl is only required for + %% TLS security: it's up to a client who wants TLS to start ssl. + %% The OTP 18 time api is also called if it exists, so that the + %% same code can be run on older releases. + {FromMod, ToMod} == {diameter_tcp, ssl} + orelse (FromMod == diameter_lib + andalso Rel < 18 + andalso lists:member(To, time_api())). + +%% New time api in OTP 18. +time_api() -> + [{erlang, F, A} || {F,A} <- [{convert_time_resolution,3}, + {monotonic_time,0}, + {monotonic_time,1}, + {time_offset,0}, + {time_offset,1}, + {time_resolution,0}, + {timestamp,0}, + {unique_integer,0}, + {unique_integer,1}]]. + +release() -> + Rel = erlang:system_info(otp_release), + try list_to_integer(Rel) of + N -> N + catch + error:_ -> + 0 %% aka < 17 + end. + unversion(App) -> T = lists:dropwhile(fun is_vsn_ch/1, lists:reverse(App)), lists:reverse(case T of [$-|TT] -> TT; _ -> T end). diff --git a/lib/diameter/test/diameter_capx_SUITE.erl b/lib/diameter/test/diameter_capx_SUITE.erl index deabdd720b..02501ce779 100644 --- a/lib/diameter/test/diameter_capx_SUITE.erl +++ b/lib/diameter/test/diameter_capx_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -144,8 +144,8 @@ end_per_suite(_Config) -> %% Generate a unique hostname for each testcase so that watchdogs %% don't prevent a connection from being brought up immediately. init_per_testcase(Name, Config) -> - Uniq = ["." ++ integer_to_list(N) || N <- tuple_to_list(now())], - [{host, lists:flatten([?L(Name) | Uniq])} | Config]. + [{host, ?L(Name) ++ "." ++ diameter_util:unique_string()} + | Config]. init_per_group(Name, Config) -> [{rfc, Name} | Config]. diff --git a/lib/diameter/test/diameter_codec_SUITE.erl b/lib/diameter/test/diameter_codec_SUITE.erl index cd8ca41f66..64ea90554d 100644 --- a/lib/diameter/test/diameter_codec_SUITE.erl +++ b/lib/diameter/test/diameter_codec_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -29,6 +29,9 @@ -export([suite/0, all/0, + groups/0, + init_per_group/2, + end_per_group/2, init_per_testcase/2, end_per_testcase/2]). @@ -36,9 +39,13 @@ -export([base/1, gen/1, lib/1, - unknown/1]). + unknown/1, + success/1, + grouped_error/1, + failed_error/1]). -include("diameter_ct.hrl"). +-include("diameter.hrl"). -define(L, atom_to_list). @@ -48,7 +55,19 @@ suite() -> [{timetrap, {seconds, 10}}]. all() -> - [base, gen, lib, unknown]. + [base, gen, lib, unknown, {group, recode}]. + +groups() -> + [{recode, [], [success, + grouped_error, + failed_error]}]. + +init_per_group(recode, Config) -> + ok = diameter:start(), + Config. + +end_per_group(_, _) -> + ok = diameter:stop(). init_per_testcase(gen, Config) -> [{application, ?APP, App}] = diameter_util:consult(?APP, app), @@ -98,3 +117,166 @@ compile(File) -> compile(File, Opts) -> compile:file(File, [return | Opts]). + +%% =========================================================================== + +%% Ensure a Grouped AVP is represented by a list in the avps field. +success(_) -> + Avps = [{295, <<1:32>>}, %% Termination-Cause + {284, [{280, "Proxy-Host"}, %% Proxy-Info + {33, "Proxy-State"}, %% + {295, <<2:32>>}]}], %% Termination-Cause + #diameter_packet{avps = [#diameter_avp{code = 295, + value = 1, + data = <<1:32>>}, + [#diameter_avp{code = 284}, + #diameter_avp{code = 280}, + #diameter_avp{code = 33}, + #diameter_avp{code = 295, + value = 2, + data = <<2:32>>}]], + errors = []} + = str(recode(str(Avps))). + +%% =========================================================================== + +%% Ensure a Grouped AVP is represented by a list in the avps field +%% even in the case of a decode error on a component AVP. +grouped_error(_) -> + Avps = [{295, <<1:32>>}, %% Termination-Cause + {284, [{295, <<0:32>>}, %% Proxy-Info, Termination-Cause + {280, "Proxy-Host"}, + {33, "Proxy-State"}]}], + #diameter_packet{avps = [#diameter_avp{code = 295, + value = 1, + data = <<1:32>>}, + [#diameter_avp{code = 284}, + #diameter_avp{code = 295, + value = undefined, + data = <<0:32>>}, + #diameter_avp{code = 280}, + #diameter_avp{code = 33}]], + errors = [{5004, #diameter_avp{code = 284}}]} + = str(recode(str(Avps))). + +%% =========================================================================== + +%% Ensure that a failed decode in Failed-AVP is acceptable, and that +%% the component AVPs are decoded if possible. +failed_error(_) -> + Avps = [{279, [{295, <<0:32>>}, %% Failed-AVP, Termination-Cause + {258, <<1:32>>}, %% Auth-Application-Id + {284, [{280, "Proxy-Host"}, %% Proxy-Info + {33, "Proxy-State"}, + {295, <<0:32>>}, %% Termination-Cause, invalid + {258, <<2:32>>}]}]}], %% Auth-Application-Id + #diameter_packet{avps = [[#diameter_avp{code = 279}, + #diameter_avp{code = 295, + value = undefined, + data = <<0:32>>}, + #diameter_avp{code = 258, + value = 1, + data = <<1:32>>}, + [#diameter_avp{code = 284}, + #diameter_avp{code = 280}, + #diameter_avp{code = 33}, + #diameter_avp{code = 295, + value = undefined}, + #diameter_avp{code = 258, + value = 2, + data = <<2:32>>}]]], + errors = []} + = sta(recode(sta(Avps))). + +%% =========================================================================== + +%% str/1 + +str(#diameter_packet{avps = [#diameter_avp{code = 263}, + #diameter_avp{code = 264}, + #diameter_avp{code = 296}, + #diameter_avp{code = 283}, + #diameter_avp{code = 258, + value = 0} + | T]} + = Pkt) -> + Pkt#diameter_packet{avps = T}; + +str(Avps) -> + OH = "diameter.erlang.org", + OR = "erlang.org", + DR = "example.com", + Sid = "diameter.erlang.org;123;456", + + [#diameter_header{version = 1, + cmd_code = 275, %% STR + is_request = true, + application_id = 0, + hop_by_hop_id = 17, + end_to_end_id = 42, + is_proxiable = false, + is_error = false, + is_retransmitted = false} + | avp([{263, Sid}, %% Session-Id + {264, OH}, %% Origin-Host + {296, OR}, %% Origin-Realm + {283, DR}, %% Destination-Realm + {258, <<0:32>>}] %% Auth-Application-Id + ++ Avps)]. + +%% sta/1 + +sta(#diameter_packet{avps = [#diameter_avp{code = 263}, + #diameter_avp{code = 268}, + #diameter_avp{code = 264}, + #diameter_avp{code = 296}, + #diameter_avp{code = 278, + value = 4} + | T]} + = Pkt) -> + Pkt#diameter_packet{avps = T}; + +sta(Avps) -> + OH = "diameter.erlang.org", + OR = "erlang.org", + Sid = "diameter.erlang.org;123;456", + + [#diameter_header{version = 1, + cmd_code = 275, %% STA + is_request = false, + application_id = 0, + hop_by_hop_id = 17, + end_to_end_id = 42, + is_proxiable = false, + is_error = false, + is_retransmitted = false} + | avp([{263, Sid}, %% Session-Id + {268, <<2002:32>>}, %% Result-Code + {264, OH}, %% Origin-Host + {296, OR}, %% Origin-Realm + {278, <<4:32>>}] %% Origin-State-Id + ++ Avps)]. + +avp({Code, Data}) -> + #diameter_avp{code = Code, + data = avp(Data)}; + +avp(#diameter_avp{} = A) -> + A; + +avp([{_,_} | _] = Avps) -> + lists:map(fun avp/1, Avps); + +avp(V) -> + V. + +%% recode/1 + +recode(Msg) -> + recode(Msg, diameter_gen_base_rfc6733). + +recode(#diameter_packet{} = Pkt, Dict) -> + diameter_codec:decode(Dict, diameter_codec:encode(Dict, Pkt)); + +recode(Msg, Dict) -> + recode(#diameter_packet{msg = Msg}, Dict). diff --git a/lib/diameter/test/diameter_codec_test.erl b/lib/diameter/test/diameter_codec_test.erl index 90536dcf2b..472755c62a 100644 --- a/lib/diameter/test/diameter_codec_test.erl +++ b/lib/diameter/test/diameter_codec_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -229,8 +229,7 @@ v(Max, Ord, E) when Ord =< Max -> diameter_enum:to_list(E); v(Max, Ord, E) -> - {M,S,U} = now(), - random:seed(M,S,U), + random:seed(diameter_util:seed()), v(Max, Ord, E, []). v(0, _, _, Acc) -> @@ -512,7 +511,7 @@ random(Mn,Mx) -> seed(undefined) -> put({?MODULE, seed}, true), - random:seed(now()); + random:seed(diameter_util:seed()); seed(true) -> ok. diff --git a/lib/diameter/test/diameter_config_SUITE.erl b/lib/diameter/test/diameter_config_SUITE.erl index d10ee83ba4..ad5b3f9420 100644 --- a/lib/diameter/test/diameter_config_SUITE.erl +++ b/lib/diameter/test/diameter_config_SUITE.erl @@ -157,7 +157,7 @@ {length_errors, [[exit], [handle], [discard]], [[x]]}, - {reconnect_timer, + {connect_timer, [[3000]], [[infinity]]}, {watchdog_timer, diff --git a/lib/diameter/test/diameter_ct.erl b/lib/diameter/test/diameter_ct.erl index ed2f884681..85c502ea7f 100644 --- a/lib/diameter/test/diameter_ct.erl +++ b/lib/diameter/test/diameter_ct.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -43,7 +43,7 @@ ct_run(Opts) -> info(Start , info()). info() -> - [{time, now()}, + [{time, diameter_lib:now()}, {process_count, erlang:system_info(process_count)} | erlang:memory()]. @@ -56,6 +56,6 @@ info(L0, L1) -> io:format("INFO: ~p~n", [Diff]). diff(time, T0, T1) -> - timer:now_diff(T1, T0); + diameter_lib:micro_diff(T1, T0); diff(_, N0, N1) -> N1 - N0. diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl index 94b4967921..bfe160203c 100644 --- a/lib/diameter/test/diameter_event_SUITE.erl +++ b/lib/diameter/test/diameter_event_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2013-15. 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 @@ -107,29 +107,38 @@ start_server(Config) -> %% Connect with matching capabilities and expect the connection to %% come up. up(Config) -> - {Svc, Ref} = connect(Config, []), + {Svc, Ref} = connect(Config, [{connect_timer, 5000}, + {watchdog_timer, 15000}]), start = event(Svc), - {up, Ref, {_,_Caps}, _Config, #diameter_packet{}} = event(Svc), - {watchdog, Ref, _, {initial, okay}, _} = event(Svc). + {up, Ref, {TPid, Caps}, Cfg, #diameter_packet{}} = event(Svc), + {watchdog, Ref, _, {initial, okay}, _} = event(Svc), + %% Kill the transport process and see that the connection is + %% reestablished after a watchdog timeout, not after connect_timer + %% expiry. + exit(TPid, kill), + {down, Ref, {TPid, Caps}, Cfg} = event(Svc), + {watchdog, Ref, _, {okay, down}, _} = event(Svc), + {reconnect, Ref, _} = event(Svc, 10000, 20000). %% Connect with non-matching capabilities and expect CEA from the peer %% to indicate as much and then for the transport to be restarted -%% (after reconnect_timer). +%% (after connect_timer). down(Config) -> {Svc, Ref} = connect(Config, [{capabilities, [{'Acct-Application-Id', [?DICT_ACCT:id()]}]}, {applications, [?DICT_ACCT]}, - {reconnect_timer, 5000}]), + {connect_timer, 5000}, + {watchdog_timer, 20000}]), start = event(Svc), {closed, Ref, {'CEA', ?NO_COMMON_APP, _, #diameter_packet{}}, _} = event(Svc), - {reconnect, Ref, _} = event(Svc). + {reconnect, Ref, _} = event(Svc, 4000, 10000). %% Connect with matching capabilities but have the server delay its %% CEA and cause the client to timeout. cea_timeout(Config) -> {Svc, Ref} = connect(Config, [{capx_timeout, ?SERVER_CAPX_TMO div 2}, - {reconnect_timer, 2*?SERVER_CAPX_TMO}]), + {connect_timer, 2*?SERVER_CAPX_TMO}]), start = event(Svc), {closed, Ref, {'CEA', timeout}, _} = event(Svc). @@ -159,12 +168,18 @@ connect(Config, Opts) -> {Name, Ref}. uniq() -> - {MS,S,US} = now(), - lists:flatten(io_lib:format("-~p-~p-~p-", [MS,S,US])). + "-" ++ diameter_util:unique_string(). event(Name) -> receive #diameter_event{service = Name, info = T} -> T end. +event(Name, TL, TH) -> + T0 = diameter_lib:now(), + Event = event(Name), + DT = diameter_lib:micro_diff(T0) div 1000, + {true, true, DT, Event} = {TL < DT, DT < TH, DT, Event}, + Event. + start_service(Name, Opts) -> diameter:start_service(Name, [{monitor, self()} | Opts]). diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl index aef4bc35ef..ef8e459175 100644 --- a/lib/diameter/test/diameter_examples_SUITE.erl +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2015. 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 @@ -295,15 +295,15 @@ slave() -> [{timetrap, {minutes, 10}}]. slave(_) -> - T0 = now(), + T0 = diameter_lib:now(), {ok, Node} = ct_slave:start(?MODULE, ?TIMEOUTS), - T1 = now(), + T1 = diameter_lib:now(), T2 = rpc:call(Node, erlang, now, []), {ok, Node} = ct_slave:stop(?MODULE), - now_diff([T0, T1, T2, now()]). + now_diff([T0, T1, T2, diameter_lib:now()]). now_diff([T1,T2|_] = Ts) -> - [timer:now_diff(T2,T1) | now_diff(tl(Ts))]; + [diameter_lib:micro_diff(T2,T1) | now_diff(tl(Ts))]; now_diff(_) -> []. @@ -397,4 +397,4 @@ stop(Name) stop(Config) -> Prot = proplists:get_value(group, Config), - [] = [RC || N <- ?NODES, RC <- [stop(concat(Prot, N))], RC /= ok]. + [] = [RC || N <- ?NODES, RC <- [catch stop(concat(Prot, N))], RC /= ok]. diff --git a/lib/diameter/test/diameter_gen_sctp_SUITE.erl b/lib/diameter/test/diameter_gen_sctp_SUITE.erl index 51ccb1e6ec..4ea5e80095 100644 --- a/lib/diameter/test/diameter_gen_sctp_SUITE.erl +++ b/lib/diameter/test/diameter_gen_sctp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -119,10 +119,10 @@ send_not_from_controlling_process(_) -> send_not_from_controlling_process() -> FPid = self(), - {L, MRef} = spawn_monitor(fun() -> listen(FPid) end),%% listening process + {L, MRef} = spawn_monitor(fun() -> listen(FPid) end), receive {?MODULE, C, S} -> - erlang:demonitor(MRef, [flush]), + demonitor(MRef, [flush]), [L,C,S]; {'DOWN', MRef, process, _, _} = T -> error(T) @@ -137,13 +137,7 @@ listen(FPid) -> LPid = self(), spawn(fun() -> connect1(PortNr, FPid, LPid) end), %% connecting process Id = assoc(Sock), - ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], _Bin}) - = recv(). %% Waits with this as current_function. - -%% recv/0 - -recv() -> - receive T -> T end. + recv(Sock, Id). %% connect1/3 @@ -154,7 +148,7 @@ connect1(PortNr, FPid, LPid) -> FPid ! {?MODULE, self(), spawn(fun() -> send(Sock, Id) end)}, %% sending process - MRef = erlang:monitor(process, LPid), + MRef = monitor(process, LPid), down(MRef). %% Waits with this as current_function. %% down/1 @@ -277,7 +271,8 @@ acc(N, Acc) -> loop(Sock, MRef, Bin) -> receive - ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], B}) -> + ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], B}) + when is_binary(B) -> Sz = size(Bin), {Sz, Bin} = {size(B), B}, %% assert ok = send(Sock, Id, mark(Bin)), @@ -291,7 +286,7 @@ loop(Sock, MRef, Bin) -> %% connect2/3 connect2(Pid, PortNr, Bin) -> - erlang:monitor(process, Pid), + monitor(process, Pid), {ok, Sock} = open(), ok = gen_sctp:connect_init(Sock, ?ADDR, PortNr, []), @@ -301,19 +296,25 @@ connect2(Pid, PortNr, Bin) -> %% T2 = time after listening process received our message %% T3 = time after reply is received - T1 = now(), + T1 = diameter_util:timestamp(), ok = send(Sock, Id, Bin), T2 = unmark(recv(Sock, Id)), - T3 = now(), - {timer:now_diff(T2, T1), timer:now_diff(T3, T2)}. %% {Outbound, Inbound} + T3 = diameter_util:timestamp(), + {diameter_lib:micro_diff(T2, T1), %% Outbound + diameter_lib:micro_diff(T3, T2)}. %% Inbound %% recv/2 recv(Sock, Id) -> receive - ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin}) -> + ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = I}], Bin}) + when is_binary(Bin) -> + Id = I, %% assert Bin; - T -> %% eg. 'DOWN' + ?SCTP(S, _) -> + Sock = S, %% assert + recv(Sock, Id); + T -> exit(T) end. @@ -325,7 +326,7 @@ send(Sock, Id, Bin) -> %% mark/1 mark(Bin) -> - Info = term_to_binary(now()), + Info = term_to_binary(diameter_util:timestamp()), <<Info/binary, Bin/binary>>. %% unmark/1 diff --git a/lib/diameter/test/diameter_gen_tcp_SUITE.erl b/lib/diameter/test/diameter_gen_tcp_SUITE.erl index 7e232edb44..4b542e0156 100644 --- a/lib/diameter/test/diameter_gen_tcp_SUITE.erl +++ b/lib/diameter/test/diameter_gen_tcp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013. All Rights Reserved. +%% Copyright Ericsson AB 2014-2015. 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 @@ -18,10 +18,10 @@ %% %% -%% Some gen_sctp-specific tests demonstrating problems that were +%% Some gen_tcp-specific tests demonstrating problems that were %% encountered during diameter development but have nothing -%% specifically to do with diameter. At least one of them can cause -%% diameter_traffic_SUITE testcases to fail. +%% specifically to do with diameter. These can cause testcases in +%% other suites to fail. %% -module(diameter_gen_tcp_SUITE). @@ -30,7 +30,8 @@ all/0]). %% testcases --export([send_long/1]). +-export([send_long/1, + connect/1]). -define(LOOPBACK, {127,0,0,1}). -define(GEN_OPTS, [binary, {active, true}, {ip, ?LOOPBACK}]). @@ -41,7 +42,8 @@ suite() -> [{timetrap, {minutes, 2}}]. all() -> - [send_long]. + [connect, %% Appears to fail only when run first. + send_long]. %% =========================================================================== @@ -87,15 +89,6 @@ connect(PortNr, LPid) -> LPid ! {self(), fun(B) -> send(Sock, B) end}, down(LPid). -%% down/1 - -down(Pid) - when is_pid(Pid) -> - down(erlang:monitor(process, Pid)); - -down(MRef) -> - receive {'DOWN', MRef, process, _, Reason} -> Reason end. - %% send/2 %% %% Send from a spawned process just to avoid sending from the @@ -104,3 +97,47 @@ down(MRef) -> send(Sock, Bin) -> {_, MRef} = spawn_monitor(fun() -> exit(gen_tcp:send(Sock, Bin)) end), down(MRef). + +%% =========================================================================== + +%% connect/1 +%% +%% Test that simultaneous connections succeed. This fails sporadically +%% on OS X at the time of writing, when gen_tcp:connect/2 returns +%% {error, econnreset}. + +connect(_) -> + {ok, LSock} = gen_tcp:listen(0, ?GEN_OPTS), + {ok, {_,PortNr}} = inet:sockname(LSock), + Count = lists:seq(1,8), %% 8 simultaneous connects + As = [gen_accept(LSock) || _ <- Count], + %% Wait for spawned processes to have called gen_tcp:accept/1 + %% (presumably). + receive after 2000 -> ok end, + Cs = [gen_connect(PortNr) || _ <- Count], + [] = failures(Cs), + [] = failures(As). + +failures(Monitors) -> + [RC || {_, MRef} <- Monitors, RC <- [down(MRef)], ok /= element(1, RC)]. + +gen_accept(LSock) -> + spawn_monitor(fun() -> + exit(gen_tcp:accept(LSock)) + end). + +gen_connect(PortNr) -> + spawn_monitor(fun() -> + exit(gen_tcp:connect(?LOOPBACK, PortNr, ?GEN_OPTS)) + end). + +%% =========================================================================== + +%% down/1 + +down(Pid) + when is_pid(Pid) -> + down(monitor(process, Pid)); + +down(MRef) -> + receive {'DOWN', MRef, process, _, Reason} -> Reason end. diff --git a/lib/diameter/test/diameter_pool_SUITE.erl b/lib/diameter/test/diameter_pool_SUITE.erl new file mode 100644 index 0000000000..a59cd66a2e --- /dev/null +++ b/lib/diameter/test/diameter_pool_SUITE.erl @@ -0,0 +1,133 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2015. 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% +%% + +%% +%% Test of the pool_size option in connecting nodes with multiple +%% connections. +%% + +-module(diameter_pool_SUITE). + +-export([suite/0, + all/0, + init_per_testcase/2, + end_per_testcase/2, + init_per_suite/1, + end_per_suite/1]). + +%% testcases +-export([tcp_connect/1, + sctp_connect/1, + any_connect/1]). + +%% =========================================================================== + +-define(util, diameter_util). + +%% Config for diameter:start_service/2. +-define(SERVICE(Host), + [{'Origin-Host', Host ++ ".ericsson.com"}, + {'Origin-Realm', "ericsson.com"}, + {'Host-IP-Address', [{127,0,0,1}]}, + {'Vendor-Id', 12345}, + {'Product-Name', "OTP/diameter"}, + {'Auth-Application-Id', [0]}, %% common + {'Acct-Application-Id', [3]}, %% accounting + {restrict_connections, false}, + {application, [{alias, common}, + {dictionary, diameter_gen_base_rfc6733}, + {module, diameter_callback}]}, + {application, [{alias, accounting}, + {dictionary, diameter_gen_acct_rfc6733}, + {module, diameter_callback}]}]). + +%% =========================================================================== + +suite() -> + [{timetrap, {seconds, 30}}]. + +all() -> + [tcp_connect, + sctp_connect, + any_connect]. + +init_per_testcase(_Name, Config) -> + Config. + +end_per_testcase(_Name, _Config) -> + diameter:stop(). + +init_per_suite(Config) -> + [{sctp, ?util:have_sctp()} | Config]. + +end_per_suite(_Config) -> + ok. + +%% =========================================================================== + +tcp_connect(_Config) -> + connect(tcp, tcp). + +sctp_connect(Config) -> + case lists:member({sctp, true}, Config) of + true -> connect(sctp, sctp); + false -> {skip, no_sctp} + end. + +any_connect(_Config) -> + connect(any, tcp). + +%% connect/2 + +%% Establish multiple connections between a client and server. +connect(ClientProt, ServerProt) -> + ok = diameter:start(), + [] = [{S,T} || S <- ["server", "client"], + T <- [diameter:start_service(S, ?SERVICE(S))], + T /= ok], + %% Listen with a single transport with pool_size = 4. Ensure the + %% expected number of transport processes are started. + LRef = ?util:listen("server", ServerProt, [{pool_size, 4}]), + {4,0} = count("server", LRef, accept), %% 4 transports, no connections + %% Establish 5 connections. + Ref = ?util:connect("client", ClientProt, LRef, [{pool_size, 5}]), + {5,5} = count("client", Ref, pool), %% 5 connections + %% Ensure the server has started replacement transports within a + %% reasonable time. Sleepsince there's no guarantee the + %% replacements have been started before the client has received + %% 'up' events. (Although it's likely.) + sleep(), + {9,5} = count("server", LRef, accept), %% 5 connections + 4 accepting + %% Ensure ther are still the expected number of accepting transports + %% after stopping the client service. + ok = diameter:stop_service("client"), + sleep(), + {4,0} = count("server", LRef, accept), %% 4 transports, no connections + %% Done. + ok = diameter:stop_service("server"). + +count(Name, Ref, Key) -> + [{transport, [[{ref, Ref} | T]]}, + {connections, Cs}] + = diameter:service_info(Name, [transport, connections]), + {Key, Ps} = lists:keyfind(Key, 1, T), + {length(Ps), length(Cs)}. %% number of processes, connections + +sleep() -> + receive after 1000 -> ok end. diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl index 4b67372016..9822b95301 100644 --- a/lib/diameter/test/diameter_traffic_SUITE.erl +++ b/lib/diameter/test/diameter_traffic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -414,12 +414,13 @@ send_eval(Config) -> = call(Config, Req). %% Send an accounting ACR that the server tries to answer with an -%% inappropriate header, resulting in no answer being sent and the -%% request timing out. +%% inappropriate header. That the error is detected is coded in +%% handle_answer. send_bad_answer(Config) -> Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD}, {'Accounting-Record-Number', 2}], - {timeout, _} = call(Config, Req). + ?answer_message(?SUCCESS) + = call(Config, Req). %% Send an ACR that the server callback answers explicitly with a %% protocol error. @@ -759,7 +760,7 @@ call(Config, Req, Opts) -> diameter:call(?CLIENT, dict(Req, Dict0), msg(Req, ReqEncoding, Dict0), - [{extra, [{Name, Group}, now()]} | Opts]). + [{extra, [{Name, Group}, diameter_lib:now()]} | Opts]). origin({A,C}) -> 2*codec(A) + container(C); @@ -1057,15 +1058,12 @@ answer(Pkt, Req, _Peer, Name, #group{client_dict0 = Dict0}) -> [R | Vs] = Dict:'#get-'(answer(Ans, Es, Name)), [Dict:rec2msg(R) | Vs]. -answer(Rec, [_|_], N) - when N == send_long_avp_length; - N == send_short_avp_length; - N == send_zero_avp_length; - N == send_invalid_avp_length; - N == send_invalid_reject; - N == send_unknown_short_mandatory; - N == send_unexpected_mandatory_decode -> +%% An inappropriate E-bit results in a decode error ... +answer(Rec, Es, send_bad_answer) -> + [{5004, #diameter_avp{name = 'Result-Code'}} | _] = Es, Rec; + +%% ... while other errors are reflected in Failed-AVP. answer(Rec, [], _) -> Rec. @@ -1078,8 +1076,10 @@ app(Req, _, Dict0) -> %% handle_error/6 handle_error(timeout = Reason, _Req, ?CLIENT, _Peer, _, Time) -> - Now = now(), - {Reason, {Time, Now, timer:now_diff(Now, Time)}}; + Now = diameter_lib:now(), + {Reason, {diameter_lib:timestamp(Time), + diameter_lib:timestamp(Now), + diameter_lib:micro_diff(Now, Time)}}; handle_error(Reason, _Req, ?CLIENT, _Peer, _, _Time) -> {error, Reason}. diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl index 9408fae62c..f098851bea 100644 --- a/lib/diameter/test/diameter_transport_SUITE.erl +++ b/lib/diameter/test/diameter_transport_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -53,7 +53,7 @@ %% Receive a message. -define(RECV(Pat, Ret), receive Pat -> Ret end). --define(RECV(Pat), ?RECV(Pat, now())). +-define(RECV(Pat), ?RECV(Pat, diameter_util:timestamp())). %% Sockets are opened on the loopback address. -define(ADDR, {127,0,0,1}). @@ -104,7 +104,7 @@ tc() -> reconnect]. init_per_suite(Config) -> - [{sctp, have_sctp()} | Config]. + [{sctp, ?util:have_sctp()} | Config]. end_per_suite(_Config) -> ok. @@ -127,7 +127,10 @@ tcp_accept(_) -> accept(tcp). sctp_accept(Config) -> - if_sctp(fun accept/1, Config). + case lists:member({sctp, true}, Config) of + true -> accept(sctp); + false -> {skip, no_sctp} + end. %% Start multiple accepting transport processes that are connected to %% with an equal number of connecting processes using gen_tcp/sctp @@ -157,7 +160,10 @@ tcp_connect(_) -> connect(tcp). sctp_connect(Config) -> - if_sctp(fun connect/1, Config). + case lists:member({sctp, true}, Config) of + true -> connect(sctp); + false -> {skip, no_sctp} + end. connect(Prot) -> T = {Prot, make_ref()}, @@ -194,7 +200,7 @@ reconnect({connect, Ref}) -> true = diameter:subscribe(SvcName), ok = start_service(SvcName), [{{_, _, LRef}, Pid}] = diameter_reg:wait({?MODULE, Ref, '_'}), - CRef = ?util:connect(SvcName, tcp, LRef, [{reconnect_timer, 2000}, + CRef = ?util:connect(SvcName, tcp, LRef, [{connect_timer, 2000}, {watchdog_timer, 6000}]), %% Tell partner to kill transport after seeing that there are no @@ -219,7 +225,7 @@ reconnect(_) -> || T <- [listen, connect]]). start_service(SvcName) -> - OH = io_lib:format("~p-~p-~p", tuple_to_list(now())), + OH = diameter_util:unique_string(), Opts = [{application, [{dictionary, diameter_gen_base_rfc6733}, {module, diameter_callback}]}, {'Origin-Host', OH}, @@ -251,28 +257,6 @@ abort(SvcName, LRef, Ref) %% =========================================================================== %% =========================================================================== -%% have_sctp/0 - -have_sctp() -> - case gen_sctp:open() of - {ok, Sock} -> - gen_sctp:close(Sock), - true; - {error, E} when E == eprotonosupport; - E == esocktnosupport -> %% fail on any other reason - false - end. - -%% if_sctp/2 - -if_sctp(F, Config) -> - case proplists:get_value(sctp, Config) of - true -> - F(sctp); - false -> - {skip, no_sctp} - end. - %% init/2 init(accept, {Prot, Ref}) -> @@ -351,7 +335,7 @@ make_msg() -> %% crypto:rand_bytes/1 isn't available on all platforms (since openssl %% isn't) so roll our own. rand_bytes(N) -> - random:seed(now()), + random:seed(diameter_util:seed()), rand_bytes(N, <<>>). rand_bytes(0, Bin) -> @@ -381,37 +365,14 @@ start_connect(tcp, T, Svc, Opts) -> diameter_tcp:start(T, Svc, Opts). %% start_accept/2 -%% -%% Start transports sequentially by having each wait for a message -%% from a job in a queue before commencing. Only one transport with a -%% pending accept is started at a time since diameter_{tcp,sctp} -%% currently assume (and diameter currently implements) this. start_accept(Prot, Ref) -> - Pid = sync(accept, Ref), {Mod, Opts} = tmod(Prot), - - try - {ok, TPid, [?ADDR]} = Mod:start({accept, Ref}, - ?SVC([?ADDR]), - [{port, 0} | Opts]), - ?RECV(?TMSG({TPid, connected})), - TPid - after - Pid ! Ref - end. - -sync(What, Ref) -> - ok = diameter_sync:cast({?MODULE, What, Ref}, - [fun lock/2, Ref, self()], - infinity, - infinity), - receive {start, Ref, Pid} -> Pid end. - -lock(Ref, Pid) -> - Pid ! {start, Ref, self()}, - erlang:monitor(process, Pid), - Ref = receive T -> T end. + {ok, TPid, [?ADDR]} = Mod:start({accept, Ref}, + ?SVC([?ADDR]), + [{port, 0} | Opts]), + ?RECV(?TMSG({TPid, connected})), + TPid. tmod(sctp) -> {diameter_sctp, [{sctp_initmsg, ?SCTP_INIT}]}; @@ -454,7 +415,7 @@ gen_accept(tcp, LSock) -> gen_send(sctp, Sock, Bin) -> {OS, _IS, Id} = getr(assoc), - {_, _, Us} = now(), + {_, _, Us} = diameter_util:timestamp(), gen_sctp:send(Sock, Id, Us rem OS, Bin); gen_send(tcp, Sock, Bin) -> gen_tcp:send(Sock, Bin). @@ -463,7 +424,11 @@ gen_send(tcp, Sock, Bin) -> gen_recv(sctp, Sock) -> {_OS, _IS, Id} = getr(assoc), - ?RECV(?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin}), Bin); + receive + ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin}) + when is_binary(Bin) -> + Bin + end; gen_recv(tcp, Sock) -> tcp_recv(Sock, <<>>). diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index 92c72c84e7..c496876ee1 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -29,7 +29,11 @@ run/1, fold/3, foldl/3, - scramble/1]). + scramble/1, + timestamp/0, + seed/0, + unique_string/0, + have_sctp/0]). %% diameter-specific -export([lport/2, @@ -174,7 +178,7 @@ scramble(L) -> [[fun s/1, L]]). s(L) -> - random:seed(now()), + random:seed(seed()), s([], L). s(Acc, []) -> @@ -184,6 +188,44 @@ s(Acc, L) -> s([T|Acc], H ++ Rest). %% --------------------------------------------------------------------------- +%% timestamp/0 + +timestamp() -> + diameter_lib:timestamp(diameter_lib:now()). + +%% --------------------------------------------------------------------------- +%% seed/0 + +seed() -> + {_,T} = diameter_lib:seed(), + T. + +%% --------------------------------------------------------------------------- +%% unique_string/0 + +unique_string() -> + us(diameter_lib:now()). + +us({M,S,U}) -> + tl(lists:append(["-" ++ integer_to_list(N) || N <- [M,S,U]])); + +us(MonoT) -> + integer_to_list(MonoT). + +%% --------------------------------------------------------------------------- +%% have_sctp/0 + +have_sctp() -> + case gen_sctp:open() of + {ok, Sock} -> + gen_sctp:close(Sock), + true; + {error, E} when E == eprotonosupport; + E == esocktnosupport -> %% fail on any other reason + false + end. + +%% --------------------------------------------------------------------------- %% eval/1 %% %% Evaluate a function in one of a number of forms. @@ -254,13 +296,12 @@ path(Config, Name) -> %% %% Lookup the port number of a tcp/sctp listening transport. -lport(M, {Node, Ref}) -> - rpc:call(Node, ?MODULE, lport, [M, Ref]); +lport(Prot, {Node, Ref}) -> + rpc:call(Node, ?MODULE, lport, [Prot, Ref]); lport(Prot, Ref) -> - Mod = tmod(Prot), [_] = diameter_reg:wait({'_', listener, {Ref, '_'}}), - [N || {listen, N, _} <- Mod:ports(Ref)]. + [N || M <- tmod(Prot), {listen, N, _} <- M:ports(Ref)]. %% --------------------------------------------------------------------------- %% listen/2-3 @@ -292,13 +333,17 @@ connect(Client, Prot, LRef, Opts) -> Ref = add_transport(Client, {connect, opts(Prot, PortNr) ++ Opts}), true = transport(Client, Ref), %% assert - ok = receive - {diameter_event, Client, {up, Ref, _, _, _}} -> ok - after 10000 -> - {Client, Prot, PortNr, process_info(self(), messages)} - end, + diameter_lib:for_n(fun(_) -> ok = up(Client, Ref, Prot, PortNr) end, + proplists:get_value(pool_size, Opts, 1)), Ref. +up(Client, Ref, Prot, PortNr) -> + receive + {diameter_event, Client, {up, Ref, _, _, _}} -> ok + after 10000 -> + {Client, Prot, PortNr, process_info(self(), messages)} + end. + transport(SvcName, Ref) -> [Ref] == [R || [{ref, R} | _] <- diameter:service_info(SvcName, transport), R == Ref]. @@ -327,13 +372,15 @@ add_transport(SvcName, T) -> Ref. tmod(tcp) -> - diameter_tcp; + [diameter_tcp]; tmod(sctp) -> - diameter_sctp. + [diameter_sctp]; +tmod(any) -> + [diameter_sctp, diameter_tcp]. opts(Prot, T) -> - [{transport_module, tmod(Prot)}, - {transport_config, [{ip, ?ADDR}, {port, 0} | opts(T)]}]. + [{transport_module, M} || M <- tmod(Prot)] + ++ [{transport_config, [{ip, ?ADDR}, {port, 0} | opts(T)]}]. opts(listen) -> [{accept, M} || M <- [{256,0,0,1}, ["256.0.0.1", ["^.+$"]]]]; diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl index b6e8730ec2..5a3ff2c92f 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-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2015. 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 @@ -420,6 +420,7 @@ suspect(TRef, false, SvcName, N) -> %% abuse/1 abuse(F) -> + [] = run([[abuse, F, T] || T <- [listen, connect]]). abuse(F, [_,_,_|_] = Args) -> @@ -672,7 +673,8 @@ jitter(T,D) -> %% Generate a unique hostname for the faked peer. hostname() -> - lists:flatten(io_lib:format("~p-~p-~p", tuple_to_list(now()))). + {M,S,U} = diameter_util:timestamp(), + lists:flatten(io_lib:format("~p-~p-~p", [M,S,U])). putr(Key, Val) -> put({?MODULE, Key}, Val). diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk index 4fea62461c..6da96bd676 100644 --- a/lib/diameter/test/modules.mk +++ b/lib/diameter/test/modules.mk @@ -1,8 +1,7 @@ -#-*-makefile-*- ; force emacs to enter makefile-mode # %CopyrightBegin% # -# Copyright Ericsson AB 2010-2013. All Rights Reserved. +# Copyright Ericsson AB 2010-2015. 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 @@ -40,6 +39,7 @@ MODULES = \ diameter_gen_sctp_SUITE \ diameter_gen_tcp_SUITE \ diameter_length_SUITE \ + diameter_pool_SUITE \ diameter_reg_SUITE \ diameter_relay_SUITE \ diameter_stats_SUITE \ diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk index 4e54e4eafc..587ae08b3d 100644 --- a/lib/diameter/vsn.mk +++ b/lib/diameter/vsn.mk @@ -18,5 +18,5 @@ # %CopyrightEnd% APPLICATION = diameter -DIAMETER_VSN = 1.7.1 +DIAMETER_VSN = 1.8 APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN) diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml index 52b7529f70..e350adb540 100644 --- a/lib/edoc/doc/src/notes.xml +++ b/lib/edoc/doc/src/notes.xml @@ -31,6 +31,22 @@ <p>This document describes the changes made to the EDoc application.</p> +<section><title>Edoc 0.7.16</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Maps: Properly align union typed assoc values in + documentation</p> + <p> + Own Id: OTP-12190</p> + </item> + </list> + </section> + +</section> + <section><title>Edoc 0.7.15</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk index b1cf115b29..24cfbf16d5 100644 --- a/lib/edoc/vsn.mk +++ b/lib/edoc/vsn.mk @@ -1 +1 @@ -EDOC_VSN = 0.7.15 +EDOC_VSN = 0.7.16 diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml index dbd478fb17..c4b1ac36ca 100644 --- a/lib/eldap/doc/src/eldap.xml +++ b/lib/eldap/doc/src/eldap.xml @@ -48,7 +48,7 @@ scope() See baseObject/0, singleLevel/0, wholeSubtree/0 dereference() See neverDerefAliases/0, derefInSearching/0, derefFindingBaseObj/0, derefAlways/0 filter() See present/1, substrings/2, equalityMatch/2, greaterOrEqual/2, lessOrEqual/2, - approxMatch/2, + approxMatch/2, extensibleMatch/2, 'and'/1, 'or'/1, 'not'/1. </pre> <p></p> @@ -107,19 +107,23 @@ filter() See present/1, substrings/2, </type> <desc> <p>Upgrade the connection associated with <c>Handle</c> to a tls connection if possible.</p> - <p>The upgrade is done in two phases: first the server is asked for permission to upgrade. Second, if the request is acknowledged, the upgrade is performed.</p> - <p>Error responese from phase one will not affect the current encryption state of the connection. Those responses are:</p> + <p>The upgrade is done in two phases: first the server is asked for permission to upgrade. Second, if the request is acknowledged, the upgrade to tls is performed.</p> + <p>Error responses from phase one will not affect the current encryption state of the connection. Those responses are:</p> <taglist> <tag><c>tls_already_started</c></tag> <item>The connection is already encrypted. The connection is not affected.</item> <tag><c>{response,ResponseFromServer}</c></tag> <item>The upgrade was refused by the LDAP server. The <c>ResponseFromServer</c> is an atom delivered byt the LDAP server explained in section 2.3 of rfc 2830. The connection is not affected, so it is still un-encrypted.</item> </taglist> - <p>Errors in the seconde phase will however end the connection:</p> + <p>Errors in the second phase will however end the connection:</p> <taglist> <tag><c>Error</c></tag> <item>Any error responded from ssl:connect/3</item> </taglist> + <p>The <c>Timeout</c> parameter is for the actual tls upgrade (phase 2) while the timeout in + <seealso marker="#open/2">erl_tar:open/2</seealso> is used for the initial negotiation about + upgrade (phase 1). + </p> </desc> </func> <func> @@ -224,9 +228,9 @@ filter() See present/1, substrings/2, </type> <desc> <p> Modify the DN of an entry. <c>DeleteOldRDN</c> indicates - whether the current RDN should be removed after operation. - <c>NewSupDN</c> should be "" if the RDN should not be moved or the new parent which - the RDN will be moved to.</p> + whether the current RDN should be removed from the attribute list after the after operation. + <c>NewSupDN</c> is the new parent that the RDN shall be moved to. If the old parent should + remain as parent, <c>NewSupDN</c> shall be "".</p> <pre> modify_dn(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com ", "cn=Bill Jr Valentine", true, "") @@ -253,6 +257,10 @@ filter() See present/1, substrings/2, Filter = eldap:substrings("cn", [{any,"V"}]), search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]), </pre> + <p>The <c>timeout</c> option in the <c>SearchOptions</c> is for the ldap server, while + the timeout in <seealso marker="#open/2">erl_tar:open/2</seealso> is used for each + individual request in the search operation. + </p> </desc> </func> @@ -348,6 +356,16 @@ filter() See present/1, substrings/2, <desc> <p>Create a approximation match filter.</p> </desc> </func> <func> + <name>extensibleMatch(MatchValue, OptionalAttrs) -> filter()</name> + <fsummary>Create search filter option.</fsummary> + <type> + <v>MatchValue = string()</v> + <v>OptionalAttrs = [Attr]</v> + <v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v> + </type> + <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc> + </func> + <func> <name>'and'([Filter]) -> filter()</name> <fsummary>Create search filter option.</fsummary> <type> diff --git a/lib/eldap/doc/src/notes.xml b/lib/eldap/doc/src/notes.xml index f92d100757..e5cbcb26ff 100644 --- a/lib/eldap/doc/src/notes.xml +++ b/lib/eldap/doc/src/notes.xml @@ -30,6 +30,35 @@ </header> <p>This document describes the changes made to the Eldap application.</p> +<section><title>Eldap 1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed that eldap:open did not use the Timeout parameter + when calling ssl:connect. (Thanks Wiesław Bieniek for + reporting)</p> + <p> + Own Id: OTP-12311</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added the LDAP filter <c>extensibleMatch</c>.</p> + <p> + Own Id: OTP-12174</p> + </item> + </list> + </section> + +</section> + <section><title>Eldap 1.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl index 416334e365..80718bc106 100644 --- a/lib/eldap/src/eldap.erl +++ b/lib/eldap/src/eldap.erl @@ -15,6 +15,7 @@ getopts/2, baseObject/0,singleLevel/0,wholeSubtree/0,close/1, equalityMatch/2,greaterOrEqual/2,lessOrEqual/2, + extensibleMatch/2, approxMatch/2,search/2,substrings/2,present/1, 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2, mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1, @@ -106,7 +107,8 @@ getopts(Handle, OptNames) when is_pid(Handle), is_list(OptNames) -> %%% -------------------------------------------------------------------- close(Handle) when is_pid(Handle) -> - send(Handle, close). + send(Handle, close), + ok. %%% -------------------------------------------------------------------- %%% Set who we should link ourselves to @@ -350,6 +352,27 @@ substrings(Type, SubStr) when is_list(Type), is_list(SubStr) -> {substrings,#'SubstringFilter'{type = Type, substrings = Ss}}. +%%% +%%% Filter for extensibleMatch +%%% +extensibleMatch(MatchValue, OptArgs) -> + MatchingRuleAssertion = + mra(OptArgs, #'MatchingRuleAssertion'{matchValue = MatchValue}), + {extensibleMatch, MatchingRuleAssertion}. + +mra([{matchingRule,Val}|T], Ack) when is_list(Val) -> + mra(T, Ack#'MatchingRuleAssertion'{matchingRule=Val}); +mra([{type,Val}|T], Ack) when is_list(Val) -> + mra(T, Ack#'MatchingRuleAssertion'{type=Val}); +mra([{dnAttributes,true}|T], Ack) -> + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"}); +mra([{dnAttributes,false}|T], Ack) -> + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"}); +mra([H|_], _) -> + throw({error,{extensibleMatch_arg,H}}); +mra([], Ack) -> + Ack. + %%% -------------------------------------------------------------------- %%% Worker process. We keep track of a controlling process to %%% be able to terminate together with it. @@ -372,7 +395,7 @@ parse_args([{port, Port}|T], Cpid, Data) when is_integer(Port) -> parse_args([{timeout, Timeout}|T], Cpid, Data) when is_integer(Timeout),Timeout>0 -> parse_args(T, Cpid, Data#eldap{timeout = Timeout}); parse_args([{anon_auth, true}|T], Cpid, Data) -> - parse_args(T, Cpid, Data#eldap{anon_auth = false}); + parse_args(T, Cpid, Data#eldap{anon_auth = true}); parse_args([{anon_auth, _}|T], Cpid, Data) -> parse_args(T, Cpid, Data); parse_args([{ssl, true}|T], Cpid, Data) -> @@ -437,7 +460,8 @@ do_connect(Host, Data, Opts) when Data#eldap.ldaps == false -> Data#eldap.timeout); do_connect(Host, Data, Opts) when Data#eldap.ldaps == true -> ssl:connect(Host, Data#eldap.port, - Opts ++ Data#eldap.tls_opts ++ Data#eldap.tcp_opts). + Opts ++ Data#eldap.tls_opts ++ Data#eldap.tcp_opts, + Data#eldap.timeout). loop(Cpid, Data) -> receive @@ -862,6 +886,7 @@ v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV}; v_filter({approxMatch,AV}) -> {approxMatch,AV}; v_filter({present,A}) -> {present,A}; v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S}; +v_filter({extensibleMatch,S}) when is_record(S,'MatchingRuleAssertion') -> {extensibleMatch,S}; v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}). v_modifications(Mods) -> diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile index 24e71cebaa..28a7a107e1 100644 --- a/lib/eldap/test/Makefile +++ b/lib/eldap/test/Makefile @@ -28,8 +28,9 @@ INCLUDES= -I. -I ../include # ---------------------------------------------------- MODULES= \ - eldap_connections_SUITE \ - eldap_basic_SUITE + eldap_basic_SUITE \ + make_certs + ERL_FILES= $(MODULES:%=%.erl) diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl index 6c3d303da0..137c61b2d9 100644 --- a/lib/eldap/test/eldap_basic_SUITE.erl +++ b/lib/eldap/test/eldap_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2013. All Rights Reserved. +%% Copyright Ericsson AB 2012-2014. 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 @@ -24,297 +24,919 @@ %%-include_lib("common_test/include/ct.hrl"). -include_lib("test_server/include/test_server.hrl"). -include_lib("eldap/include/eldap.hrl"). +-include_lib("eldap/ebin/ELDAPv3.hrl"). + -define(TIMEOUT, 120000). % 2 min +all() -> + [app, + appup, + {group, encode_decode}, + {group, return_values}, + {group, v4_connections}, + {group, v6_connections}, + {group, plain_api}, + {group, ssl_api}, + {group, start_tls_api} + ]. + +groups() -> + [{encode_decode, [], [encode, + decode + ]}, + {plain_api, [], [{group,api}]}, + {ssl_api, [], [{group,api}, start_tls_on_ssl_should_fail]}, + {start_tls_api, [], [{group,api}, start_tls_twice_should_fail]}, + + {api, [], [{group,api_not_bound}, + {group,api_bound}]}, + + {api_not_bound, [], [elementary_search, search_non_existant, + add_when_not_bound, + bind]}, + {api_bound, [], [add_when_bound, + add_already_exists, + more_add, + search_filter_equalityMatch, + search_filter_substring_any, + search_filter_initial, + search_filter_final, + search_filter_and, + search_filter_or, + search_filter_and_not, + search_two_hits, + modify, + delete, + modify_dn_delete_old, + modify_dn_keep_old]}, + {v4_connections, [], connection_tests()}, + {v6_connections, [], connection_tests()}, + {return_values, [], [open_ret_val_success, + open_ret_val_error, + close_ret_val]} + ]. + +connection_tests() -> + [tcp_connection, + tcp_connection_option, + ssl_connection, + client_side_start_tls_timeout, + client_side_bind_timeout, + client_side_add_timeout, + client_side_search_timeout + ]. + + + init_per_suite(Config) -> - StartSsl = try ssl:start() - catch - Error:Reason -> - {skip, lists:flatten(io_lib:format("eldap init_per_suite failed to start ssl Error=~p Reason=~p", [Error, Reason]))} - end, - case StartSsl of - ok -> - chk_config(ldap_server, {"localhost",9876}, - chk_config(ldaps_server, {"localhost",9877}, - Config)); - _ -> - StartSsl - end. + SSL_available = init_ssl_certs_et_al(Config), + LDAP_server = find_first_server(false, [{config,eldap_server}, {config,ldap_server}, {"localhost",9876}]), + LDAPS_server = + case SSL_available of + true -> + find_first_server(true, [{config,ldaps_server}, {"localhost",9877}]); + false -> + undefined + end, + [{ssl_available, SSL_available}, + {ldap_server, LDAP_server}, + {ldaps_server, LDAPS_server} | Config]. end_per_suite(_Config) -> - ok. - -init_per_testcase(_TestCase, Config0) -> - {EldapHost,Port} = proplists:get_value(ldap_server,Config0), - try - {ok, Handle} = eldap:open([EldapHost], [{port,Port}]), - ok = eldap:simple_bind(Handle, "cn=Manager,dc=ericsson,dc=se", "hejsan"), - {ok, MyHost} = inet:gethostname(), - Path = "dc="++MyHost++",dc=ericsson,dc=se", - eldap:add(Handle,"dc=ericsson,dc=se", - [{"objectclass", ["dcObject", "organization"]}, - {"dc", ["ericsson"]}, {"o", ["Testing"]}]), - eldap:add(Handle,Path, - [{"objectclass", ["dcObject", "organization"]}, - {"dc", [MyHost]}, {"o", ["Test machine"]}]), - [{eldap_path,Path}|Config0] - catch error:{badmatch,Error} -> - io:format("Eldap init error ~p~n ~p~n",[Error, erlang:get_stacktrace()]), - {skip, lists:flatten(io_lib:format("Ldap init failed with host ~p:~p. Error=~p", [EldapHost,Port,Error]))} + ssl:stop(). + + +init_per_group(return_values, Config) -> + case ?config(ldap_server,Config) of + undefined -> + {skip, "LDAP server not availble"}; + {Host,Port} -> + ct:comment("ldap://~s:~p",[Host,Port]), + Config + end; +init_per_group(plain_api, Config0) -> + case ?config(ldap_server,Config0) of + undefined -> + {skip, "LDAP server not availble"}; + Server = {Host,Port} -> + ct:comment("ldap://~s:~p",[Host,Port]), + initialize_db([{server,Server}, {ssl_flag,false}, {start_tls,false} | Config0]) + end; +init_per_group(ssl_api, Config0) -> + case ?config(ldaps_server,Config0) of + undefined -> + {skip, "LDAPS server not availble"}; + Server = {Host,Port} -> + ct:comment("ldaps://~s:~p",[Host,Port]), + initialize_db([{server,Server}, {ssl_flag,true}, {start_tls,false} | Config0]) + end; +init_per_group(start_tls_api, Config0) -> + case {?config(ldap_server,Config0), ?config(ssl_available,Config0)} of + {undefined,true} -> + {skip, "LDAP server not availble"}; + {_,false} -> + {skip, "TLS not availble"}; + {Server={Host,Port}, true} -> + ct:comment("ldap://~s:~p + start_tls",[Host,Port]), + Config = [{server,Server}, {ssl_flag,false} | Config0], + case supported_extension("1.3.6.1.4.1.1466.20037", Config) of + true -> initialize_db([{start_tls,true} | Config]); + false -> {skip, "start_tls not supported according to the server"} + end + end; +init_per_group(v4_connections, Config) -> + [{tcp_listen_opts, [{reuseaddr, true}]}, + {listen_host, "localhost"}, + {tcp_connect_opts, []} + | Config]; +init_per_group(v6_connections, Config) -> + {ok, Hostname} = inet:gethostname(), + case lists:member(list_to_atom(Hostname), ct:get_config(ipv6_hosts,[])) of + true -> + [{tcp_listen_opts, [inet6,{reuseaddr, true}]}, + {listen_host, "::"}, + {tcp_connect_opts, [{tcpopts,[inet6]}]} + | Config]; + false -> + {skip, io_lib:format("~p is not an ipv6_host",[Hostname])} + end; +init_per_group(_, Config) -> + Config. + +end_per_group(plain_api, Config) -> clear_db(Config); +end_per_group(ssl_api, Config) -> clear_db(Config); +end_per_group(start_tls_api, Config) -> clear_db(Config); +end_per_group(_Group, Config) -> Config. + + +init_per_testcase(ssl_connection, Config) -> + case ?config(ssl_available,Config) of + true -> + SSL_Port = 9999, + CertFile = filename:join(?config(data_dir,Config), "certs/server/cert.pem"), + KeyFile = filename:join(?config(data_dir,Config), "certs/server/key.pem"), + + Parent = self(), + Listener = spawn_link( + fun() -> + case ssl:listen(SSL_Port, [{certfile, CertFile}, + {keyfile, KeyFile} + | ?config(tcp_listen_opts,Config) + ]) of + {ok,SSL_LSock} -> + Parent ! {ok,self()}, + (fun L() -> + ct:log("ssl server waiting for connections...",[]), + {ok, S} = ssl:transport_accept(SSL_LSock), + ct:log("ssl:transport_accept/1 ok",[]), + ok = ssl:ssl_accept(S), + ct:log("ssl:ssl_accept/1 ok",[]), + L() + end)(); + Other -> + Parent ! {not_ok,Other,self()} + end + end), + receive + {ok,Listener} -> + ct:log("SSL listening to port ~p (process ~p)",[SSL_Port, Listener]), + [{ssl_listener,Listener}, + {ssl_listen_port,SSL_Port}, + {ssl_connect_opts,[]} + | Config]; + {no_ok,SSL_Other,Listener} -> + ct:log("ssl:listen on port ~p failed: ~p",[SSL_Port,SSL_Other]), + {fail, "ssl:listen/2 failed"} + after 5000 -> + {fail, "Waiting for ssl:listen timeout"} + end; + false -> + {skip, "ssl not available"} + end; + +init_per_testcase(TC, Config) -> + case lists:member(TC,connection_tests()) of + true -> + case gen_tcp:listen(0, proplists:get_value(tcp_listen_opts,Config)) of + {ok,LSock} -> + {ok,{_,Port}} = inet:sockname(LSock), + [{listen_socket,LSock}, + {listen_port,Port} + | Config]; + Other -> + {fail, Other} + end; + + false -> + case proplists:get_value(name,?config(tc_group_properties, Config)) of + api_not_bound -> + {ok,H} = open(Config), + [{handle,H} | Config]; + api_bound -> + {ok,H} = open(Config), + ok = eldap:simple_bind(H, + "cn=Manager,dc=ericsson,dc=se", + "hejsan"), + [{handle,H} | Config]; + _Name -> + Config + end end. -end_per_testcase(_TestCase, Config) -> - {EHost, Port} = proplists:get_value(ldap_server, Config), - Path = proplists:get_value(eldap_path, Config), - {ok, H} = eldap:open([EHost], [{port, Port}]), - ok = eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"), - case eldap:search(H, [{base, Path}, - {filter, eldap:present("objectclass")}, - {scope, eldap:wholeSubtree()}]) - of - {ok, {eldap_search_result, Entries, _}} -> - [ok = eldap:delete(H, Entry) || {eldap_entry, Entry, _} <- Entries]; - _ -> ignore - end, +end_per_testcase(_, Config) -> + catch gen_tcp:close( proplists:get_value(listen_socket, Config) ), + catch eldap:close( proplists:get_value(handle,Config) ). - ok. -%% suite() -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% +%%% Test cases +%%% -all() -> - [app, - appup, - api, - ssl_api, - start_tls, - tls_operations, - start_tls_twice, - start_tls_on_ssl - ]. - -app(doc) -> "Test that the eldap app file is ok"; -app(suite) -> []; +%%%---------------------------------------------------------------- +%%% Test that the eldap app file is ok app(Config) when is_list(Config) -> ok = test_server:app_test(eldap). -%% Test that the eldap appup file is ok +%%%---------------------------------------------------------------- +%%% Test that the eldap appup file is ok appup(Config) when is_list(Config) -> ok = test_server:appup_test(eldap). -api(doc) -> "Basic test that all api functions works as expected"; -api(suite) -> []; -api(Config) -> - {Host,Port} = proplists:get_value(ldap_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}]), - %% {ok, H} = eldap:open([Host], [{port,Port+1}, {ssl, true}]), - do_api_checks(H, Config), - eldap:close(H), - ok. +%%%---------------------------------------------------------------- +open_ret_val_success(Config) -> + {Host,Port} = ?config(ldap_server,Config), + {ok,H} = eldap:open([Host], [{port,Port}]), + catch eldap:close(H). + +%%%---------------------------------------------------------------- +open_ret_val_error(_Config) -> + {error,_} = eldap:open(["nohost.example.com"], [{port,65535}]). + +%%%---------------------------------------------------------------- +close_ret_val(Config) -> + {Host,Port} = ?config(ldap_server,Config), + {ok,H} = eldap:open([Host], [{port,Port}]), + ok = eldap:close(H). + +%%%---------------------------------------------------------------- +tcp_connection(Config) -> + Host = proplists:get_value(listen_host, Config), + Port = proplists:get_value(listen_port, Config), + Opts = proplists:get_value(tcp_connect_opts, Config), + case eldap:open([Host], [{port,Port}|Opts]) of + {ok,_H} -> + Sl = proplists:get_value(listen_socket, Config), + case gen_tcp:accept(Sl,1000) of + {ok,_S} -> ok; + {error,timeout} -> ct:fail("server side accept timeout",[]); + Other -> ct:fail("gen_tdp:accept failed: ~p",[Other]) + end; + Other -> ct:fail("eldap:open failed: ~p",[Other]) + end. +%%%---------------------------------------------------------------- +ssl_connection(Config) -> + Host = proplists:get_value(listen_host, Config), + Port = proplists:get_value(ssl_listen_port, Config), + Opts = proplists:get_value(tcp_connect_opts, Config), + SSLOpts = proplists:get_value(ssl_connect_opts, Config), + case eldap:open([Host], [{port,Port}, + {ssl,true}, + {timeout,5000}, + {sslopts,SSLOpts}|Opts]) of + {ok,_H} -> ok; + Other -> ct:fail("eldap:open failed: ~p",[Other]) + end. -ssl_api(doc) -> "Basic test that all api functions works as expected"; -ssl_api(suite) -> []; -ssl_api(Config) -> - {Host,Port} = proplists:get_value(ldaps_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}, {ssl,true}]), - do_api_checks(H, Config), - eldap:close(H), - ok. +%%%---------------------------------------------------------------- +client_side_add_timeout(Config) -> + client_timeout( + fun(H) -> + eldap:add(H, "cn=Foo Bar,dc=host,dc=ericsson,dc=se", + [{"objectclass", ["person"]}, + {"cn", ["Foo Bar"]}, + {"sn", ["Bar"]}, + {"telephoneNumber", ["555-1232", "555-5432"]}]) + end, Config). + +%%%---------------------------------------------------------------- +client_side_bind_timeout(Config) -> + client_timeout( + fun(H) -> + eldap:simple_bind(H, anon, anon) + end, Config). + +%%%---------------------------------------------------------------- +client_side_search_timeout(Config) -> + client_timeout( + fun(H) -> + eldap:search(H, [{base,"dc=host,dc=ericsson,dc=se"}, + {filter, eldap:present("objectclass")}, + {scope, eldap:wholeSubtree()}]) + end, Config). + +%%%---------------------------------------------------------------- +client_side_start_tls_timeout(Config) -> + client_timeout( + fun(H) -> + eldap:start_tls(H, []) + end, Config). + +%%%---------------------------------------------------------------- +tcp_connection_option(Config) -> + Host = proplists:get_value(listen_host, Config), + Port = proplists:get_value(listen_port, Config), + Opts = proplists:get_value(tcp_connect_opts, Config), + Sl = proplists:get_value(listen_socket, Config), + + %% Make an option value to test. The option must be implemented on all + %% platforms that we test on. Must check what the default value is + %% so we don't happen to choose that particular value. + {ok,[{linger,DefaultLinger}]} = inet:getopts(Sl, [linger]), + TestLinger = case DefaultLinger of + {false,_} -> {true,5}; + {true,_} -> {false,0} + end, + + case catch eldap:open([Host], + [{port,Port},{tcpopts,[{linger,TestLinger}]}|Opts]) of + {ok,H} -> + case gen_tcp:accept(Sl,1000) of + {ok,_} -> + case eldap:getopts(H, [{tcpopts,[linger]}]) of + {ok,[{tcpopts,[{linger,ActualLinger}]}]} -> + case ActualLinger of + TestLinger -> + ok; + DefaultLinger -> + ct:fail("eldap:getopts: 'linger' didn't change," + " got ~p (=default) expected ~p", + [ActualLinger,TestLinger]); + _ -> + ct:fail("eldap:getopts: bad 'linger', got ~p expected ~p", + [ActualLinger,TestLinger]) + end; + Other -> + ct:fail("eldap:getopts: bad result ~p",[Other]) + end; + {error,timeout} -> + ct:fail("server side accept timeout",[]) + end; + + Other -> + ct:fail("eldap:open failed: ~p",[Other]) + end. -start_tls(doc) -> "Test that an existing (tcp) connection can be upgraded to tls"; -start_tls(suite) -> []; -start_tls(Config) -> - {Host,Port} = proplists:get_value(ldap_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}]), - ok = eldap:start_tls(H, [ - {keyfile, filename:join([proplists:get_value(data_dir,Config), - "certs/client/key.pem"])} - ]), - eldap:close(H). +%%%---------------------------------------------------------------- +%%% Basic test that all api functions works as expected + +%%%---------------------------------------------------------------- +elementary_search(Config) -> + {ok, #eldap_search_result{entries=[_]}} = + eldap:search(?config(handle,Config), + #eldap_search{base = ?config(eldap_path, Config), + filter= eldap:present("objectclass"), + scope = eldap:wholeSubtree()}). + +%%%---------------------------------------------------------------- +search_non_existant(Config) -> + {error, noSuchObject} = + eldap:search(?config(handle,Config), + #eldap_search{base = "cn=Bar," ++ ?config(eldap_path, Config), + filter= eldap:present("objectclass"), + scope = eldap:wholeSubtree()}). + +%%%---------------------------------------------------------------- +add_when_not_bound(Config) -> + {error, _} = eldap:add(?config(handle,Config), + "cn=Jonas Jonsson," ++ ?config(eldap_path, Config), + [{"objectclass", ["person"]}, + {"cn", ["Jonas Jonsson"]}, + {"sn", ["Jonsson"]}]). + +%%%---------------------------------------------------------------- +bind(Config) -> + ok = eldap:simple_bind(?config(handle,Config), + "cn=Manager,dc=ericsson,dc=se", + "hejsan"). + +%%%---------------------------------------------------------------- +add_when_bound(Config) -> + ok = eldap:add(?config(handle, Config), + "cn=Jonas Jonsson," ++ ?config(eldap_path, Config), + [{"objectclass", ["person"]}, + {"cn", ["Jonas Jonsson"]}, + {"sn", ["Jonsson"]}]). + +%%%---------------------------------------------------------------- +add_already_exists(Config) -> + {error, entryAlreadyExists} = + eldap:add(?config(handle, Config), + "cn=Jonas Jonsson," ++ ?config(eldap_path, Config), + [{"objectclass", ["person"]}, + {"cn", ["Jonas Jonsson"]}, + {"sn", ["Jonsson"]}]). + +%%%---------------------------------------------------------------- +more_add(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + ok = eldap:add(H, "cn=Foo Bar," ++ BasePath, + [{"objectclass", ["person"]}, + {"cn", ["Foo Bar"]}, + {"sn", ["Bar"]}, + {"telephoneNumber", ["555-1232", "555-5432"]}]), + ok = eldap:add(H, "ou=Team," ++ BasePath, + [{"objectclass", ["organizationalUnit"]}, + {"ou", ["Team"]}]). -tls_operations(doc) -> "Test that an upgraded connection is usable for ldap stuff"; -tls_operations(suite) -> []; -tls_operations(Config) -> - {Host,Port} = proplists:get_value(ldap_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}]), - ok = eldap:start_tls(H, [ - {keyfile, filename:join([proplists:get_value(data_dir,Config), - "certs/client/key.pem"])} - ]), - do_api_checks(H, Config), +%%%---------------------------------------------------------------- +search_filter_equalityMatch(Config) -> + BasePath = ?config(eldap_path, Config), + ExpectedDN = "cn=Jonas Jonsson," ++ BasePath, + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} = + eldap:search(?config(handle, Config), + #eldap_search{base = BasePath, + filter = eldap:equalityMatch("sn", "Jonsson"), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_filter_substring_any(Config) -> + BasePath = ?config(eldap_path, Config), + ExpectedDN = "cn=Jonas Jonsson," ++ BasePath, + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} = + eldap:search(?config(handle, Config), + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{any, "ss"}]), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_filter_initial(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + ExpectedDN = "cn=Foo Bar," ++ BasePath, + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{initial, "B"}]), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_filter_final(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + ExpectedDN = "cn=Foo Bar," ++ BasePath, + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{final, "r"}]), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_filter_and(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + ExpectedDN = "cn=Foo Bar," ++ BasePath, + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=ExpectedDN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:'and'([eldap:substrings("sn", [{any, "a"}]), + eldap:equalityMatch("cn","Foo Bar")]), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_filter_or(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + ExpectedDNs = lists:sort(["cn=Foo Bar," ++ BasePath, + "ou=Team," ++ BasePath]), + {ok, #eldap_search_result{entries=Es}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:'or'([eldap:substrings("sn", [{any, "a"}]), + eldap:equalityMatch("ou","Team")]), + scope=eldap:singleLevel()}), + ExpectedDNs = lists:sort([DN || #eldap_entry{object_name=DN} <- Es]). + +%%%---------------------------------------------------------------- +search_filter_and_not(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + {ok, #eldap_search_result{entries=[]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:'and'([eldap:substrings("sn", [{any, "a"}]), + eldap:'not'( + eldap:equalityMatch("cn","Foo Bar") + )]), + scope=eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +search_two_hits(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + DN1 = "cn=Santa Claus," ++ BasePath, + DN2 = "cn=Jultomten," ++ BasePath, + %% Add two objects: + ok = eldap:add(H, DN1, + [{"objectclass", ["person"]}, + {"cn", ["Santa Claus"]}, + {"sn", ["Santa"]}, + {"description", ["USA"]}]), + ok = eldap:add(H, DN2, + [{"objectclass", ["person"]}, + {"cn", ["Jultomten"]}, + {"sn", ["Tomten"]}, + {"description", ["Sweden"]}]), + + %% Search for them: + {ok, #eldap_search_result{entries=Es}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:present("description"), + scope=eldap:singleLevel()}), + + %% And check that they are the expected ones: + ExpectedDNs = lists:sort([DN1, DN2]), + ExpectedDNs = lists:sort([D || #eldap_entry{object_name=D} <- Es]), + + %% Restore the database: + [ok=eldap:delete(H,DN) || DN <- ExpectedDNs]. + +%%%---------------------------------------------------------------- +modify(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + %% The object to modify + DN = "cn=Foo Bar," ++ BasePath, + + %% Save a copy to restore later: + {ok,OriginalAttrs} = attributes(H, DN), + + %% Do a change + Mod = [eldap:mod_replace("telephoneNumber", ["555-12345"]), + eldap:mod_add("description", ["Nice guy"])], + ok = eldap:modify(H, DN, Mod), + + %% Check that the object was changed + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:equalityMatch("telephoneNumber", "555-12345"), + scope=eldap:singleLevel()}), + + %% Do another type of change + ok = eldap:modify(H, DN, [eldap:mod_delete("telephoneNumber", [])]), + %% and check that it worked by repeating the test above + {ok, #eldap_search_result{entries=[]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:equalityMatch("telephoneNumber", "555-12345"), + scope=eldap:singleLevel()}), + %% restore the orignal version: + restore_original_object(H, DN, OriginalAttrs). + +%%%---------------------------------------------------------------- +delete(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + %% The element to play with: + DN = "cn=Jonas Jonsson," ++ BasePath, + + %% Prove that the element is present before deletion + {ok,OriginalAttrs} = attributes(H, DN), + + %% Do what the test has to do: + ok = eldap:delete(H, DN), + %% check that it really was deleted: + {error, noSuchObject} = eldap:delete(H, DN), + + %% And restore the object for subsequent tests + restore_original_object(H, DN, OriginalAttrs). + +%%%---------------------------------------------------------------- +modify_dn_delete_old(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + OrigCN = "Foo Bar", + OriginalRDN = "cn="++OrigCN, + DN = OriginalRDN ++ "," ++ BasePath, + NewCN = "Niclas Andre", + NewRDN = "cn="++NewCN, + NewDN = NewRDN ++ "," ++BasePath, + + %% Check that the object to modify_dn of exists: + {ok,OriginalAttrs} = attributes(H, DN), + CN_orig = lists:sort(proplists:get_value("cn",OriginalAttrs)), + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{any, "a"}]), + scope = eldap:singleLevel()}), + + %% Modify and delete the old one: + ok = eldap:modify_dn(H, DN, NewRDN, true, ""), + + %% Check that DN was modified and the old one was deleted: + {ok,NewAttrs} = attributes(H, NewDN), + CN_new = lists:sort(proplists:get_value("cn",NewAttrs)), + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=NewDN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{any, "a"}]), + scope = eldap:singleLevel()}), + %% What we expect: + CN_new = lists:sort([NewCN | CN_orig -- [OrigCN]]), + + %% Change back: + ok = eldap:modify_dn(H, NewDN, OriginalRDN, true, ""), + + %% Check that DN was modified and the new one was deleted: + {ok,SameAsOriginalAttrs} = attributes(H, DN), + CN_orig = lists:sort(proplists:get_value("cn",SameAsOriginalAttrs)), + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{any, "a"}]), + scope = eldap:singleLevel()}). + +%%%---------------------------------------------------------------- +modify_dn_keep_old(Config) -> + H = ?config(handle, Config), + BasePath = ?config(eldap_path, Config), + OriginalRDN = "cn=Foo Bar", + DN = OriginalRDN ++ "," ++ BasePath, + NewCN = "Niclas Andre", + NewRDN = "cn="++NewCN, + NewDN = NewRDN ++ "," ++BasePath, + + %% Check that the object to modify_dn of exists but the new one does not: + {ok,OriginalAttrs} = attributes(H, DN), + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN}]}} = + eldap:search(H, + #eldap_search{base = BasePath, + filter = eldap:substrings("sn", [{any, "a"}]), + scope = eldap:singleLevel()}), + + %% Modify but keep the old "cn" attr: + ok = eldap:modify_dn(H, DN, NewRDN, false, ""), + + %% Check that DN was modified and the old CN entry is not deleted: + {ok,NewAttrs} = attributes(H, NewDN), + CN_orig = proplists:get_value("cn",OriginalAttrs), + CN_new = proplists:get_value("cn",NewAttrs), + Expected = lists:sort([NewCN|CN_orig]), + Expected = lists:sort(CN_new), + + %% Restore db: + ok = eldap:delete(H, NewDN), + restore_original_object(H, DN, OriginalAttrs). + +%%%---------------------------------------------------------------- +%%% Test that start_tls on an already upgraded connection makes no noise +start_tls_twice_should_fail(Config) -> + {ok,H} = open_bind(Config), + {error,tls_already_started} = eldap:start_tls(H, []), eldap:close(H). -start_tls_twice(doc) -> "Test that start_tls on an already upgraded connection fails"; -start_tls_twice(suite) -> []; -start_tls_twice(Config) -> - {Host,Port} = proplists:get_value(ldap_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}]), - ok = eldap:start_tls(H, []), +%%%---------------------------------------------------------------- +%%% Test that start_tls on an ldaps connection fails +start_tls_on_ssl_should_fail(Config) -> + {ok,H} = open_bind(Config), {error,tls_already_started} = eldap:start_tls(H, []), - do_api_checks(H, Config), eldap:close(H). +%%%---------------------------------------------------------------- +encode(_Config) -> + {ok,Bin} = 'ELDAPv3':encode('AddRequest', #'AddRequest'{entry="hejHopp" ,attributes=[]} ), + Expected = <<104,11,4,7,104,101,106,72,111,112,112,48,0>>, + case Bin of + Expected -> ok; + _ -> ct:log("Encoded erroneously to:~n~p~nExpected:~n~p",[Bin,Expected]), + {fail, "Bad encode"} + end. + +%%%---------------------------------------------------------------- +decode(_Config) -> + {ok,Res} = 'ELDAPv3':decode('AddRequest', <<104,11,4,7,104,101,106,72,111,112,112,48,0>>), + ct:log("Res = ~p", [Res]), + Expected = #'AddRequest'{entry = "hejHopp",attributes = []}, + case Res of + Expected -> ok; + #'AddRequest'{entry= <<"hejHopp">>, attributes=[]} -> + {fail, "decoded to (correct) binary!!"}; + _ -> + {fail, "Bad decode"} + end. -start_tls_on_ssl(doc) -> "Test that start_tls on an ldaps connection fails"; -start_tls_on_ssl(suite) -> []; -start_tls_on_ssl(Config) -> - {Host,Port} = proplists:get_value(ldaps_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}, {ssl,true}]), - {error,tls_already_started} = eldap:start_tls(H, []), - do_api_checks(H, Config), - eldap:close(H). -%%%-------------------------------------------------------------------------------- -chk_config(Key, Default, Config) -> - case catch ct:get_config(ldap_server, undefined) of - undefined -> [{Key,Default} | Config ]; - {'EXIT',_} -> [{Key,Default} | Config ]; - Value -> [{Key,Value} | Config] +%%%**************************************************************** +%%% Private + +attributes(H, DN) -> + case eldap:search(H, + #eldap_search{base = DN, + filter= eldap:present("objectclass"), + scope = eldap:wholeSubtree()}) of + {ok, #eldap_search_result{entries=[#eldap_entry{object_name=DN, + attributes=OriginalAttrs}]}} -> + {ok, OriginalAttrs}; + Other -> + Other end. +restore_original_object(H, DN, Attrs) -> + eldap:delete(H, DN), + ok = eldap:add(H, DN, Attrs). + + +find_first_server(UseSSL, [{config,Key}|Ss]) -> + case ct:get_config(Key) of + {Host,Port} -> + ct:log("find_first_server config ~p -> ~p",[Key,{Host,Port}]), + find_first_server(UseSSL, [{Host,Port}|Ss]); + undefined -> + ct:log("find_first_server config ~p is undefined",[Key]), + find_first_server(UseSSL, Ss) + end; +find_first_server(UseSSL, [{Host,Port}|Ss]) -> + case eldap:open([Host],[{port,Port},{ssl,UseSSL}]) of + {ok,H} when UseSSL==false, Ss=/=[] -> + case eldap:start_tls(H,[]) of + ok -> + ct:log("find_first_server ~p UseSSL=~p -> ok",[{Host,Port},UseSSL]), + eldap:close(H), + {Host,Port}; + Res -> + ct:log("find_first_server ~p UseSSL=~p failed with~n~p~nSave as spare host.",[{Host,Port},UseSSL,Res]), + eldap:close(H), + find_first_server(UseSSL, Ss++[{spare_host,Host,Port}]) + end; + {ok,H} -> + ct:log("find_first_server ~p UseSSL=~p -> ok",[{Host,Port},UseSSL]), + eldap:close(H), + {Host,Port}; + Res -> + ct:log("find_first_server ~p UseSSL=~p failed with~n~p",[{Host,Port},UseSSL,Res]), + find_first_server(UseSSL, Ss) + end; +find_first_server(false, [{spare_host,Host,Port}|_]) -> + ct:log("find_first_server can't find start_tls host, use the spare non-start_tls host for plain ldap: ~p",[{Host,Port}]), + {Host,Port}; +find_first_server(_, []) -> + ct:log("find_first_server, nothing left to try",[]), + undefined. + +initialize_db(Config) -> + case {open_bind(Config), inet:gethostname()} of + {{ok,H}, {ok,MyHost}} -> + Path = "dc="++MyHost++",dc=ericsson,dc=se", + delete_old_contents(H, Path), + add_new_contents(H, Path, MyHost), + eldap:close(H), + [{eldap_path,Path}|Config]; + Other -> + ct:fail("initialize_db failed: ~p",[Other]) + end. +clear_db(Config) -> + {ok,H} = open_bind(Config), + Path = ?config(eldap_path, Config), + delete_old_contents(H, Path), + eldap:close(H), + Config. -do_api_checks(H, Config) -> - BasePath = proplists:get_value(eldap_path, Config), +delete_old_contents(H, Path) -> + case eldap:search(H, [{base, Path}, + {filter, eldap:present("objectclass")}, + {scope, eldap:wholeSubtree()}]) + of + {ok, #eldap_search_result{entries=Entries}} -> + [ok = eldap:delete(H,DN) || #eldap_entry{object_name=DN} <- Entries]; + _Res -> + ignore + end. - All = fun(Where) -> - eldap:search(H, #eldap_search{base=Where, - filter=eldap:present("objectclass"), - scope= eldap:wholeSubtree()}) - end, - {ok, #eldap_search_result{entries=[_XYZ]}} = All(BasePath), -%% ct:log("XYZ=~p",[_XYZ]), - {error, noSuchObject} = All("cn=Bar,"++BasePath), +add_new_contents(H, Path, MyHost) -> + ok(eldap:add(H,"dc=ericsson,dc=se", + [{"objectclass", ["dcObject", "organization"]}, + {"dc", ["ericsson"]}, + {"o", ["Testing"]}])), + ok(eldap:add(H,Path, + [{"objectclass", ["dcObject", "organization"]}, + {"dc", [MyHost]}, + {"o", ["Test machine"]}])). - {error, _} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath, - [{"objectclass", ["person"]}, - {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]), - eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"), - chk_add(H, BasePath), - {ok,FB} = chk_search(H, BasePath), - chk_modify(H, FB), - chk_delete(H, BasePath), - chk_modify_dn(H, FB). +ok({error,entryAlreadyExists}) -> ok; +ok(X) -> ok=X. -chk_add(H, BasePath) -> - ok = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath, - [{"objectclass", ["person"]}, - {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]), - {error, entryAlreadyExists} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath, - [{"objectclass", ["person"]}, - {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]), - ok = eldap:add(H, "cn=Foo Bar," ++ BasePath, - [{"objectclass", ["person"]}, - {"cn", ["Foo Bar"]}, {"sn", ["Bar"]}, {"telephoneNumber", ["555-1232", "555-5432"]}]), - ok = eldap:add(H, "ou=Team," ++ BasePath, - [{"objectclass", ["organizationalUnit"]}, - {"ou", ["Team"]}]). -chk_search(H, BasePath) -> - Search = fun(Filter) -> - eldap:search(H, #eldap_search{base=BasePath, - filter=Filter, - scope=eldap:singleLevel()}) - end, - JJSR = {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:equalityMatch("sn", "Jonsson")), - JJSR = Search(eldap:substrings("sn", [{any, "ss"}])), - FBSR = {ok, #eldap_search_result{entries=[#eldap_entry{object_name=FB}]}} = - Search(eldap:substrings("sn", [{any, "a"}])), - FBSR = Search(eldap:substrings("sn", [{initial, "B"}])), - FBSR = Search(eldap:substrings("sn", [{final, "r"}])), - F_AND = eldap:'and'([eldap:present("objectclass"), eldap:present("ou")]), - {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(F_AND), - F_NOT = eldap:'and'([eldap:present("objectclass"), eldap:'not'(eldap:present("ou"))]), - {ok, #eldap_search_result{entries=[#eldap_entry{}, #eldap_entry{}]}} = Search(F_NOT), - {ok,FB}. %% FIXME - -chk_modify(H, FB) -> - Mod = [eldap:mod_replace("telephoneNumber", ["555-12345"]), - eldap:mod_add("description", ["Nice guy"])], - %% io:format("MOD ~p ~p ~n",[FB, Mod]), - ok = eldap:modify(H, FB, Mod), - %% DELETE ATTR - ok = eldap:modify(H, FB, [eldap:mod_delete("telephoneNumber", [])]). - - -chk_delete(H, BasePath) -> - {error, entryAlreadyExists} = eldap:add(H, "cn=Jonas Jonsson," ++ BasePath, - [{"objectclass", ["person"]}, - {"cn", ["Jonas Jonsson"]}, {"sn", ["Jonsson"]}]), - ok = eldap:delete(H, "cn=Jonas Jonsson," ++ BasePath), - {error, noSuchObject} = eldap:delete(H, "cn=Jonas Jonsson," ++ BasePath). - -chk_modify_dn(H, FB) -> - ok = eldap:modify_dn(H, FB, "cn=Niclas Andre", true, ""). - %%io:format("Res ~p~n ~p~n",[R, All(BasePath)]). - - -%%%---------------- -add(H, Attr, Value, Path0, Attrs, Class) -> - Path = case Path0 of - [] -> Attr ++ "=" ++ Value; - _ -> Attr ++ "=" ++ Value ++ "," ++ Path0 - end, - case eldap:add(H, Path, [{"objectclass", Class}, {Attr, [Value]}] ++ Attrs) - of - ok -> {ok, Path}; - {error, E = entryAlreadyExists} -> {E, Path}; - R = {error, Reason} -> - io:format("~p:~p: ~s,~s =>~n ~p~n", - [?MODULE,?LINE, Attr, Value, R]), - exit({ldap, add, Reason}) +cond_start_tls(H, Config) -> + case ?config(start_tls,Config) of + true -> start_tls(H,Config); + _ -> Config end. +start_tls(H, Config) -> + KeyFile = filename:join([?config(data_dir,Config), + "certs/client/key.pem" + ]), + case eldap:start_tls(H, [{keyfile, KeyFile}]) of + ok -> + [{start_tls_success,true} | Config]; + Error -> + ct:log("Start_tls on ~p failed: ~p",[?config(url,Config) ,Error]), + ct:fail("start_tls failed") + end. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Develop -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -test() -> - run(). - -run() -> - Cases = all(), - run(Cases). - -run(Case) when is_atom(Case) -> - run([Case]); -run(Cases) when is_list(Cases) -> - Run = fun(Test, Config0) -> - Config = init_per_testcase(Test, Config0), - try - io:format("~nTest ~p ... ",[Test]), - ?MODULE:Test(Config), - end_per_testcase(Test, Config), - io:format("ok~n",[]) - catch _:Reason -> - io:format("~n FAIL (~p): ~p~n ~p~n", - [Test, Reason, erlang:get_stacktrace()]) - end - end, - process_flag(trap_exit, true), - Pid = spawn_link(fun() -> - case init_per_suite([]) of - {skip, Reason} -> io:format("Skip ~s~n",[Reason]); - Config -> - try - [Run(Test, Config) || Test <- Cases] - catch _:Err -> - io:format("Error ~p in ~p~n",[Err, erlang:get_stacktrace()]) - end, - end_per_suite(Config) - end - end), - receive - {'EXIT', Pid, normal} -> ok; - Msg -> io:format("Received ~p (~p)~n",[Msg, Pid]) - after 100 -> ok end, - process_flag(trap_exit, false), - ok. +%%%---------------------------------------------------------------- +open_bind(Config) -> + {ok,H} = open(Config), + ok = eldap:simple_bind(H, "cn=Manager,dc=ericsson,dc=se", "hejsan"), + {ok,H}. + +open(Config) -> + {Host,Port} = ?config(server,Config), + SSLflag = ?config(ssl_flag,Config), + {ok,H} = eldap:open([Host], [{port,Port},{ssl,SSLflag}]), + cond_start_tls(H, Config), + {ok,H}. + +%%%---------------------------------------------------------------- +supported_extension(OID, Config) -> + {ok,H} = open_bind(Config), + case eldap:search(H, [{scope, eldap:baseObject()}, + {filter, eldap:present("objectclass")}, + {deref, eldap:neverDerefAliases()}, + {attributes, ["+"]}]) of + {ok,R=#eldap_search_result{}} -> + eldap:close(H), + lists:member(OID, + [SE || EE <- R#eldap_search_result.entries, + {"supportedExtension",SEs} <- EE#eldap_entry.attributes, + SE<-SEs]); + _ -> + eldap:close(H), + false + end. + +%%%---------------------------------------------------------------- +client_timeout(Fun, Config) -> + Host = proplists:get_value(listen_host, Config), + Port = proplists:get_value(listen_port, Config), + Opts = proplists:get_value(tcp_connect_opts, Config), + T = 1000, + case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of + {ok,H} -> + T0 = now(), + {error,{gen_tcp_error,timeout}} = Fun(H), + T_op = diff(T0,now()), + ct:log("Time = ~p, Timeout spec = ~p",[T_op,T]), + if + T_op < T -> + {fail, "Timeout too early"}; + true -> + ok + end; + + Other -> ct:fail("eldap:open failed: ~p",[Other]) + end. + +diff({M1,S1,U1},{M2,S2,U2}) -> + ( ((M2-M1)*1000 + (S2-S1))*1000 + (U2-U1) ). + +%%%---------------------------------------------------------------- +init_ssl_certs_et_al(Config) -> + try ssl:start() + of + R when R==ok ; R=={error,{already_started,ssl}} -> + try make_certs:all("/dev/null", + filename:join(?config(data_dir,Config), "certs")) + of + {ok,_} -> true; + Other -> + ct:comment("make_certs failed"), + ct:log("make_certs failed ~p", [Other]), + false + catch + C:E -> + ct:comment("make_certs crashed"), + ct:log("make_certs failed ~p:~p", [C,E]), + false + end; + _ -> + false + catch + Error:Reason -> + ct:comment("ssl failed to start"), + ct:log("init_per_suite failed to start ssl Error=~p Reason=~p", [Error, Reason]), + false + end. diff --git a/lib/eldap/test/eldap_basic_SUITE_data/RAND b/lib/eldap/test/eldap_basic_SUITE_data/RAND Binary files differnew file mode 100644 index 0000000000..70997bd01f --- /dev/null +++ b/lib/eldap/test/eldap_basic_SUITE_data/RAND diff --git a/lib/eldap/test/eldap_connections_SUITE.erl b/lib/eldap/test/eldap_connections_SUITE.erl deleted file mode 100644 index c5460fef09..0000000000 --- a/lib/eldap/test/eldap_connections_SUITE.erl +++ /dev/null @@ -1,147 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2012-2014. 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% -%% - --module(eldap_connections_SUITE). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). -%-include_lib("eldap/include/eldap.hrl"). - - -all() -> - [ - {group, v4}, - {group, v6} - ]. - - -init_per_group(v4, Config) -> - [{listen_opts, []}, - {listen_host, "localhost"}, - {connect_opts, []} - | Config]; -init_per_group(v6, Config) -> - {ok, Hostname} = inet:gethostname(), - case lists:member(list_to_atom(Hostname), ct:get_config(ipv6_hosts,[])) of - true -> - [{listen_opts, [inet6]}, - {listen_host, "::"}, - {connect_opts, [{tcpopts,[inet6]}]} - | Config]; - false -> - {skip, io_lib:format("~p is not an ipv6_host",[Hostname])} - end. - - -end_per_group(_GroupName, Config) -> - Config. - - -groups() -> - [{v4, [], [tcp_connection, tcp_connection_option]}, - {v6, [], [tcp_connection, tcp_connection_option]} - ]. - - -init_per_suite(Config) -> Config. - - -end_per_suite(_Config) -> ok. - - -init_per_testcase(_TestCase, Config) -> - case gen_tcp:listen(0, proplists:get_value(listen_opts,Config)) of - {ok,LSock} -> - {ok,{_,Port}} = inet:sockname(LSock), - [{listen_socket,LSock}, - {listen_port,Port} - | Config]; - Other -> - {fail, Other} - end. - - -end_per_testcase(_TestCase, Config) -> - catch gen_tcp:close( proplists:get_value(listen_socket, Config) ). - -%%%================================================================ -%%% -%%% Test cases -%%% -%%%---------------------------------------------------------------- -tcp_connection(Config) -> - Host = proplists:get_value(listen_host, Config), - Port = proplists:get_value(listen_port, Config), - Opts = proplists:get_value(connect_opts, Config), - case eldap:open([Host], [{port,Port}|Opts]) of - {ok,_H} -> - Sl = proplists:get_value(listen_socket, Config), - case gen_tcp:accept(Sl,1000) of - {ok,_S} -> ok; - {error,timeout} -> ct:fail("server side accept timeout",[]) - end; - Other -> ct:fail("eldap:open failed: ~p",[Other]) - end. - - -%%%---------------------------------------------------------------- -tcp_connection_option(Config) -> - Host = proplists:get_value(listen_host, Config), - Port = proplists:get_value(listen_port, Config), - Opts = proplists:get_value(connect_opts, Config), - Sl = proplists:get_value(listen_socket, Config), - - %% Make an option value to test. The option must be implemented on all - %% platforms that we test on. Must check what the default value is - %% so we don't happen to choose that particular value. - {ok,[{linger,DefaultLinger}]} = inet:getopts(Sl, [linger]), - TestLinger = case DefaultLinger of - {false,_} -> {true,5}; - {true,_} -> {false,0} - end, - - case catch eldap:open([Host], - [{port,Port},{tcpopts,[{linger,TestLinger}]}|Opts]) of - {ok,H} -> - case gen_tcp:accept(Sl,1000) of - {ok,_} -> - case eldap:getopts(H, [{tcpopts,[linger]}]) of - {ok,[{tcpopts,[{linger,ActualLinger}]}]} -> - case ActualLinger of - TestLinger -> - ok; - DefaultLinger -> - ct:fail("eldap:getopts: 'linger' didn't change," - " got ~p (=default) expected ~p", - [ActualLinger,TestLinger]); - _ -> - ct:fail("eldap:getopts: bad 'linger', got ~p expected ~p", - [ActualLinger,TestLinger]) - end; - Other -> - ct:fail("eldap:getopts: bad result ~p",[Other]) - end; - {error,timeout} -> - ct:fail("server side accept timeout",[]) - end; - - Other -> - ct:fail("eldap:open failed: ~p",[Other]) - end. diff --git a/lib/eldap/test/eldap_misc_SUITE.erl b/lib/eldap/test/eldap_misc_SUITE.erl deleted file mode 100644 index ca810ee33c..0000000000 --- a/lib/eldap/test/eldap_misc_SUITE.erl +++ /dev/null @@ -1,51 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2012-2014. 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% -%% - --module(eldap_misc_SUITE). - --compile(export_all). %% Use this only in test suites... - --include_lib("common_test/include/ct.hrl"). --include_lib("eldap/include/eldap.hrl"). --include_lib("eldap/ebin/ELDAPv3.hrl"). - -all() -> - [ - encode, - decode - ]. - - -encode(_Config) -> - {ok,Bin} = 'ELDAPv3':encode('AddRequest', #'AddRequest'{entry="hejHopp" ,attributes=[]} ), - Expected = <<104,11,4,7,104,101,106,72,111,112,112,48,0>>, - Expected = Bin. - -decode(_Config) -> - {ok,Res} = 'ELDAPv3':decode('AddRequest', <<104,11,4,7,104,101,106,72,111,112,112,48,0>>), - ct:log("Res = ~p", [Res]), - Expected = #'AddRequest'{entry = "hejHopp",attributes = []}, - case Res of - Expected -> ok; - #'AddRequest'{entry= <<"hejHopp">>, attributes=[]} -> - {fail, "decoded to (correct) binary!!"}; - _ -> - {fail, "Bad decode"} - end. - diff --git a/lib/eldap/test/make_certs.erl b/lib/eldap/test/make_certs.erl index f963af180d..15a7e118ff 100644 --- a/lib/eldap/test/make_certs.erl +++ b/lib/eldap/test/make_certs.erl @@ -1,41 +1,89 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2007-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% %% -module(make_certs). +-compile([export_all]). --export([all/2]). +%-export([all/1, all/2, rootCA/2, intermediateCA/3, endusers/3, enduser/3, revoke/3, gencrl/2, verify/3]). --record(dn, {commonName, +-record(config, {commonName, organizationalUnitName = "Erlang OTP", organizationName = "Ericsson AB", localityName = "Stockholm", countryName = "SE", - emailAddress = "[email protected]"}). + emailAddress = "[email protected]", + default_bits = 2048, + v2_crls = true, + ecc_certs = false, + issuing_distribution_point = false, + crl_port = 8000, + openssl_cmd = "openssl"}). + + +default_config() -> + #config{}. + +make_config(Args) -> + make_config(Args, #config{}). + +make_config([], C) -> + C; +make_config([{organizationalUnitName, Name}|T], C) when is_list(Name) -> + make_config(T, C#config{organizationalUnitName = Name}); +make_config([{organizationName, Name}|T], C) when is_list(Name) -> + make_config(T, C#config{organizationName = Name}); +make_config([{localityName, Name}|T], C) when is_list(Name) -> + make_config(T, C#config{localityName = Name}); +make_config([{countryName, Name}|T], C) when is_list(Name) -> + make_config(T, C#config{countryName = Name}); +make_config([{emailAddress, Name}|T], C) when is_list(Name) -> + make_config(T, C#config{emailAddress = Name}); +make_config([{default_bits, Bits}|T], C) when is_integer(Bits) -> + make_config(T, C#config{default_bits = Bits}); +make_config([{v2_crls, Bool}|T], C) when is_boolean(Bool) -> + make_config(T, C#config{v2_crls = Bool}); +make_config([{crl_port, Port}|T], C) when is_integer(Port) -> + make_config(T, C#config{crl_port = Port}); +make_config([{ecc_certs, Bool}|T], C) when is_boolean(Bool) -> + make_config(T, C#config{ecc_certs = Bool}); +make_config([{issuing_distribution_point, Bool}|T], C) when is_boolean(Bool) -> + make_config(T, C#config{issuing_distribution_point = Bool}); +make_config([{openssl_cmd, Cmd}|T], C) when is_list(Cmd) -> + make_config(T, C#config{openssl_cmd = Cmd}). + + +all([DataDir, PrivDir]) -> + all(DataDir, PrivDir). all(DataDir, PrivDir) -> - OpenSSLCmd = "openssl", + all(DataDir, PrivDir, #config{}). + +all(DataDir, PrivDir, C) when is_list(C) -> + all(DataDir, PrivDir, make_config(C)); +all(DataDir, PrivDir, C = #config{}) -> + ok = filelib:ensure_dir(filename:join(PrivDir, "erlangCA")), create_rnd(DataDir, PrivDir), % For all requests - rootCA(PrivDir, OpenSSLCmd, "erlangCA"), - intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"), - endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]), - collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]), - %% Create keycert files + rootCA(PrivDir, "erlangCA", C), + intermediateCA(PrivDir, "otpCA", "erlangCA", C), + endusers(PrivDir, "otpCA", ["client", "server", "revoked"], C), + endusers(PrivDir, "erlangCA", ["localhost"], C), + %% Create keycert files SDir = filename:join([PrivDir, "server"]), SC = filename:join([SDir, "cert.pem"]), SK = filename:join([SDir, "key.pem"]), @@ -46,7 +94,14 @@ all(DataDir, PrivDir) -> CK = filename:join([CDir, "key.pem"]), CKC = filename:join([CDir, "keycert.pem"]), append_files([CK, CC], CKC), - remove_rnd(PrivDir). + RDir = filename:join([PrivDir, "revoked"]), + RC = filename:join([RDir, "cert.pem"]), + RK = filename:join([RDir, "key.pem"]), + RKC = filename:join([RDir, "keycert.pem"]), + revoke(PrivDir, "otpCA", "revoked", C), + append_files([RK, RC], RKC), + remove_rnd(PrivDir), + {ok, C}. append_files(FileNames, ResultFileName) -> {ok, ResultFile} = file:open(ResultFileName, [write]), @@ -59,117 +114,182 @@ do_append_files([F|Fs], RF) -> ok = file:write(RF, Data), do_append_files(Fs, RF). -rootCA(Root, OpenSSLCmd, Name) -> - create_ca_dir(Root, Name, ca_cnf(Name)), - DN = #dn{commonName = Name}, - create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)), - ok. +rootCA(Root, Name, C) -> + create_ca_dir(Root, Name, ca_cnf(C#config{commonName = Name})), + create_self_signed_cert(Root, Name, req_cnf(C#config{commonName = Name}), C), + file:copy(filename:join([Root, Name, "cert.pem"]), filename:join([Root, Name, "cacerts.pem"])), + gencrl(Root, Name, C). -intermediateCA(Root, OpenSSLCmd, CA, ParentCA) -> - CA = "otpCA", - create_ca_dir(Root, CA, ca_cnf(CA)), +intermediateCA(Root, CA, ParentCA, C) -> + create_ca_dir(Root, CA, ca_cnf(C#config{commonName = CA})), CARoot = filename:join([Root, CA]), - DN = #dn{commonName = CA}, CnfFile = filename:join([CARoot, "req.cnf"]), - file:write_file(CnfFile, req_cnf(DN)), - KeyFile = filename:join([CARoot, "private", "key.pem"]), - ReqFile = filename:join([CARoot, "req.pem"]), - create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile), + file:write_file(CnfFile, req_cnf(C#config{commonName = CA})), + KeyFile = filename:join([CARoot, "private", "key.pem"]), + ReqFile = filename:join([CARoot, "req.pem"]), + create_req(Root, CnfFile, KeyFile, ReqFile, C), CertFile = filename:join([CARoot, "cert.pem"]), - sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile). - -endusers(Root, OpenSSLCmd, CA, Users) -> - lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users). - -enduser(Root, OpenSSLCmd, CA, User) -> + sign_req(Root, ParentCA, "ca_cert", ReqFile, CertFile, C), + CACertsFile = filename:join(CARoot, "cacerts.pem"), + file:copy(filename:join([Root, ParentCA, "cacerts.pem"]), CACertsFile), + %% append this CA's cert to the cacerts file + {ok, Bin} = file:read_file(CertFile), + {ok, FD} = file:open(CACertsFile, [append]), + file:write(FD, ["\n", Bin]), + file:close(FD), + gencrl(Root, CA, C). + +endusers(Root, CA, Users, C) -> + [enduser(Root, CA, User, C) || User <- Users]. + +enduser(Root, CA, User, C) -> UsrRoot = filename:join([Root, User]), file:make_dir(UsrRoot), CnfFile = filename:join([UsrRoot, "req.cnf"]), - DN = #dn{commonName = User}, - file:write_file(CnfFile, req_cnf(DN)), - KeyFile = filename:join([UsrRoot, "key.pem"]), - ReqFile = filename:join([UsrRoot, "req.pem"]), - create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile), + file:write_file(CnfFile, req_cnf(C#config{commonName = User})), + KeyFile = filename:join([UsrRoot, "key.pem"]), + ReqFile = filename:join([UsrRoot, "req.pem"]), + create_req(Root, CnfFile, KeyFile, ReqFile, C), + %create_req(Root, CnfFile, KeyFile, ReqFile), CertFileAllUsage = filename:join([UsrRoot, "cert.pem"]), - sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFileAllUsage), + sign_req(Root, CA, "user_cert", ReqFile, CertFileAllUsage, C), CertFileDigitalSigOnly = filename:join([UsrRoot, "digital_signature_only_cert.pem"]), - sign_req(Root, OpenSSLCmd, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly). - -collect_certs(Root, CAs, Users) -> - Bins = lists:foldr( - fun(CA, Acc) -> - File = filename:join([Root, CA, "cert.pem"]), - {ok, Bin} = file:read_file(File), - [Bin, "\n" | Acc] - end, [], CAs), - lists:foreach( - fun(User) -> - File = filename:join([Root, User, "cacerts.pem"]), - file:write_file(File, Bins) - end, Users). + sign_req(Root, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly, C), + CACertsFile = filename:join(UsrRoot, "cacerts.pem"), + file:copy(filename:join([Root, CA, "cacerts.pem"]), CACertsFile), + ok. -create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) -> +revoke(Root, CA, User, C) -> + UsrCert = filename:join([Root, User, "cert.pem"]), + CACnfFile = filename:join([Root, CA, "ca.cnf"]), + Cmd = [C#config.openssl_cmd, " ca" + " -revoke ", UsrCert, + [" -crl_reason keyCompromise" || C#config.v2_crls ], + " -config ", CACnfFile], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env), + gencrl(Root, CA, C). + +gencrl(Root, CA, C) -> + CACnfFile = filename:join([Root, CA, "ca.cnf"]), + CACRLFile = filename:join([Root, CA, "crl.pem"]), + Cmd = [C#config.openssl_cmd, " ca" + " -gencrl ", + " -crlhours 24", + " -out ", CACRLFile, + " -config ", CACnfFile], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env). + +verify(Root, CA, User, C) -> + CAFile = filename:join([Root, User, "cacerts.pem"]), + CACRLFile = filename:join([Root, CA, "crl.pem"]), + CertFile = filename:join([Root, User, "cert.pem"]), + Cmd = [C#config.openssl_cmd, " verify" + " -CAfile ", CAFile, + " -CRLfile ", CACRLFile, %% this is undocumented, but seems to work + " -crl_check ", + CertFile], + Env = [{"ROOTDIR", filename:absname(Root)}], + try cmd(Cmd, Env) catch + exit:{eval_cmd, _, _} -> + invalid + end. + +create_self_signed_cert(Root, CAName, Cnf, C = #config{ecc_certs = true}) -> CARoot = filename:join([Root, CAName]), CnfFile = filename:join([CARoot, "req.cnf"]), file:write_file(CnfFile, Cnf), - KeyFile = filename:join([CARoot, "private", "key.pem"]), - CertFile = filename:join([CARoot, "cert.pem"]), - Cmd = [OpenSSLCmd, " req" + KeyFile = filename:join([CARoot, "private", "key.pem"]), + CertFile = filename:join([CARoot, "cert.pem"]), + Cmd = [C#config.openssl_cmd, " ecparam" + " -out ", KeyFile, + " -name secp521r1 ", + %" -name sect283k1 ", + " -genkey "], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env), + + Cmd2 = [C#config.openssl_cmd, " req" + " -new" + " -x509" + " -config ", CnfFile, + " -key ", KeyFile, + " -outform PEM ", + " -out ", CertFile], + cmd(Cmd2, Env); +create_self_signed_cert(Root, CAName, Cnf, C) -> + CARoot = filename:join([Root, CAName]), + CnfFile = filename:join([CARoot, "req.cnf"]), + file:write_file(CnfFile, Cnf), + KeyFile = filename:join([CARoot, "private", "key.pem"]), + CertFile = filename:join([CARoot, "cert.pem"]), + Cmd = [C#config.openssl_cmd, " req" " -new" " -x509" " -config ", CnfFile, " -keyout ", KeyFile, - " -out ", CertFile], - Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env), - fix_key_file(OpenSSLCmd, KeyFile). - -% openssl 1.0 generates key files in pkcs8 format by default and we don't handle this format -fix_key_file(OpenSSLCmd, KeyFile) -> - KeyFileTmp = KeyFile ++ ".tmp", - Cmd = [OpenSSLCmd, " rsa", - " -in ", - KeyFile, - " -out ", - KeyFileTmp], - cmd(Cmd, []), - ok = file:rename(KeyFileTmp, KeyFile). + " -outform PEM", + " -out ", CertFile], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env). + create_ca_dir(Root, CAName, Cnf) -> CARoot = filename:join([Root, CAName]), + ok = filelib:ensure_dir(CARoot), file:make_dir(CARoot), create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]), create_rnd(Root, filename:join([CAName, "private"])), create_files(CARoot, [{"serial", "01\n"}, + {"crlnumber", "01"}, {"index.txt", ""}, {"ca.cnf", Cnf}]). -create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) -> - Cmd = [OpenSSLCmd, " req" +create_req(Root, CnfFile, KeyFile, ReqFile, C = #config{ecc_certs = true}) -> + Cmd = [C#config.openssl_cmd, " ecparam" + " -out ", KeyFile, + " -name secp521r1 ", + %" -name sect283k1 ", + " -genkey "], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env), + Cmd2 = [C#config.openssl_cmd, " req" + " -new ", + " -key ", KeyFile, + " -outform PEM ", + " -out ", ReqFile, + " -config ", CnfFile], + cmd(Cmd2, Env); + %fix_key_file(KeyFile). +create_req(Root, CnfFile, KeyFile, ReqFile, C) -> + Cmd = [C#config.openssl_cmd, " req" " -new" " -config ", CnfFile, - " -keyout ", KeyFile, - " -out ", ReqFile], - Env = [{"ROOTDIR", Root}], - cmd(Cmd, Env), - fix_key_file(OpenSSLCmd, KeyFile). + " -outform PEM ", + " -keyout ", KeyFile, + " -out ", ReqFile], + Env = [{"ROOTDIR", filename:absname(Root)}], + cmd(Cmd, Env). + %fix_key_file(KeyFile). + -sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) -> +sign_req(Root, CA, CertType, ReqFile, CertFile, C) -> CACnfFile = filename:join([Root, CA, "ca.cnf"]), - Cmd = [OpenSSLCmd, " ca" + Cmd = [C#config.openssl_cmd, " ca" " -batch" " -notext" - " -config ", CACnfFile, + " -config ", CACnfFile, " -extensions ", CertType, - " -in ", ReqFile, + " -in ", ReqFile, " -out ", CertFile], - Env = [{"ROOTDIR", Root}], + Env = [{"ROOTDIR", filename:absname(Root)}], cmd(Cmd, Env). - + %% %% Misc %% - + create_dirs(Root, Dirs) -> lists:foreach(fun(Dir) -> file:make_dir(filename:join([Root, Dir])) end, @@ -192,30 +312,30 @@ remove_rnd(Dir) -> cmd(Cmd, Env) -> FCmd = lists:flatten(Cmd), - Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout, + Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout, {env, Env}]), - eval_cmd(Port). + eval_cmd(Port, FCmd). -eval_cmd(Port) -> - receive +eval_cmd(Port, Cmd) -> + receive {Port, {data, _}} -> - eval_cmd(Port); + eval_cmd(Port, Cmd); {Port, eof} -> ok end, receive {Port, {exit_status, Status}} when Status /= 0 -> %% io:fwrite("exit status: ~w~n", [Status]), - exit({eval_cmd, Status}) + exit({eval_cmd, Cmd, Status}) after 0 -> ok end. %% -%% Contents of configuration files +%% Contents of configuration files %% -req_cnf(DN) -> +req_cnf(C) -> ["# Purpose: Configuration for requests (end users and CAs)." "\n" "ROOTDIR = $ENV::ROOTDIR\n" @@ -224,10 +344,10 @@ req_cnf(DN) -> "[req]\n" "input_password = secret\n" "output_password = secret\n" - "default_bits = 1024\n" + "default_bits = ", integer_to_list(C#config.default_bits), "\n" "RANDFILE = $ROOTDIR/RAND\n" "encrypt_key = no\n" - "default_md = sha1\n" + "default_md = md5\n" "#string_mask = pkix\n" "x509_extensions = ca_ext\n" "prompt = no\n" @@ -235,12 +355,12 @@ req_cnf(DN) -> "\n" "[name]\n" - "commonName = ", DN#dn.commonName, "\n" - "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n" - "organizationName = ", DN#dn.organizationName, "\n" - "localityName = ", DN#dn.localityName, "\n" - "countryName = ", DN#dn.countryName, "\n" - "emailAddress = ", DN#dn.emailAddress, "\n" + "commonName = ", C#config.commonName, "\n" + "organizationalUnitName = ", C#config.organizationalUnitName, "\n" + "organizationName = ", C#config.organizationName, "\n" + "localityName = ", C#config.localityName, "\n" + "countryName = ", C#config.countryName, "\n" + "emailAddress = ", C#config.emailAddress, "\n" "\n" "[ca_ext]\n" @@ -249,8 +369,7 @@ req_cnf(DN) -> "subjectKeyIdentifier = hash\n" "subjectAltName = email:copy\n"]. - -ca_cnf(CA) -> +ca_cnf(C) -> ["# Purpose: Configuration for CAs.\n" "\n" "ROOTDIR = $ENV::ROOTDIR\n" @@ -258,21 +377,23 @@ ca_cnf(CA) -> "\n" "[ca]\n" - "dir = $ROOTDIR/", CA, "\n" + "dir = $ROOTDIR/", C#config.commonName, "\n" "certs = $dir/certs\n" "crl_dir = $dir/crl\n" "database = $dir/index.txt\n" "new_certs_dir = $dir/newcerts\n" "certificate = $dir/cert.pem\n" "serial = $dir/serial\n" - "crl = $dir/crl.pem\n" + "crl = $dir/crl.pem\n", + ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls], "private_key = $dir/private/key.pem\n" "RANDFILE = $dir/private/RAND\n" "\n" - "x509_extensions = user_cert\n" + "x509_extensions = user_cert\n", + ["crl_extensions = crl_ext\n" || C#config.v2_crls], "unique_subject = no\n" "default_days = 3600\n" - "default_md = sha1\n" + "default_md = md5\n" "preserve = no\n" "policy = policy_match\n" "\n" @@ -286,6 +407,13 @@ ca_cnf(CA) -> "emailAddress = supplied\n" "\n" + "[crl_ext]\n" + "authorityKeyIdentifier=keyid:always,issuer:always\n", + ["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point], + + "[idpsec]\n" + "fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n" + "[user_cert]\n" "basicConstraints = CA:false\n" "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n" @@ -293,6 +421,12 @@ ca_cnf(CA) -> "authorityKeyIdentifier = keyid,issuer:always\n" "subjectAltName = email:copy\n" "issuerAltName = issuer:copy\n" + "crlDistributionPoints=@crl_section\n" + + "[crl_section]\n" + %% intentionally invalid + "URI.1=http://localhost/",C#config.commonName,"/crl.pem\n" + "URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n" "\n" "[user_cert_digital_signature_only]\n" @@ -310,4 +444,7 @@ ca_cnf(CA) -> "subjectKeyIdentifier = hash\n" "authorityKeyIdentifier = keyid:always,issuer:always\n" "subjectAltName = email:copy\n" - "issuerAltName = issuer:copy\n"]. + "issuerAltName = issuer:copy\n" + "crlDistributionPoints=@crl_section\n" + ]. + diff --git a/lib/eldap/vsn.mk b/lib/eldap/vsn.mk index 5e32f92fa8..432ba2e742 100644 --- a/lib/eldap/vsn.mk +++ b/lib/eldap/vsn.mk @@ -1 +1 @@ -ELDAP_VSN = 1.0.4
\ No newline at end of file +ELDAP_VSN = 1.1 diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index f194fb6d6c..c2f81dfcc1 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -30,7 +30,23 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.3.6</title> + <section><title>Erl_Docgen 0.3.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Maps: Properly align union typed assoc values in + documentation</p> + <p> + Own Id: OTP-12190</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Docgen 0.3.6</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index 8bfcc08698..8957d6ac40 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1 +1 @@ -ERL_DOCGEN_VSN = 0.3.6 +ERL_DOCGEN_VSN = 0.3.7 diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4 deleted file mode 100644 index ed492d55ff..0000000000 --- a/lib/erl_interface/aclocal.m4 +++ /dev/null @@ -1,1954 +0,0 @@ -dnl -dnl %CopyrightBegin% -dnl -dnl Copyright Ericsson AB 1998-2013. 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 - -AC_DEFUN(LM_PRECIOUS_VARS, -[ - -dnl ERL_TOP -AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) - -dnl Tools -AC_ARG_VAR(CC, [C compiler]) -AC_ARG_VAR(CFLAGS, [C compiler flags]) -AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) -AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) -AC_ARG_VAR(CPP, [C/C++ preprocessor]) -AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) -AC_ARG_VAR(CXX, [C++ compiler]) -AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) -AC_ARG_VAR(LD, [linker (is often overridden by configure)]) -AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) -AC_ARG_VAR(LIBS, [libraries]) -AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) -AC_ARG_VAR(RANLIB, [ranlib]) -AC_ARG_VAR(AR, [ar]) -AC_ARG_VAR(GETCONF, [getconf]) - -dnl Cross system root -AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) - -dnl Cross compilation variables -AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) - -dnl Cross compilation variables for OSE -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file]) -AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) - -]) - -AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, -[ -erl_xcomp_without_sysroot=no -if test "$cross_compiling" = "yes"; then - test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes - test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" -else - erl_xcomp_sysroot= - erl_xcomp_isysroot= -fi -]) - -AC_DEFUN(LM_CHECK_GETCONF, -[ -if test "$cross_compiling" != "yes"; then - AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) -else - dnl First check if we got a `<HOST>-getconf' in $PATH - host_getconf="$host_alias-getconf" - AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) - if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then - dnl We should perhaps give up if we have'nt found it by now, but at - dnl least in one Tilera MDE `getconf' under sysroot is a bourne - dnl shell script which we can use. We try to find `<HOST>-getconf' - dnl or `getconf' under sysconf, but only under sysconf since - dnl `getconf' in $PATH is almost guaranteed to be for the build - dnl machine. - GETCONF= - prfx="$erl_xcomp_sysroot" - AC_PATH_TOOL([GETCONF], [getconf], [false], - ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) - fi -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_WINDOWS_ENVIRONMENT -dnl -dnl -dnl Tries to determine thw windows build environment, i.e. -dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC -dnl - -AC_DEFUN(LM_WINDOWS_ENVIRONMENT, -[ -MIXED_CYGWIN=no -MIXED_MSYS=no - -AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) -if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([Cygwin and VC]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - elif test -x /usr/bin/msysinfo; then - CFLAGS="-O2" - MIXED_MSYS=yes - AC_MSG_RESULT([MSYS and VC]) - MIXED_MSYS_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no - MIXED_MSYS_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) -AC_SUBST(MIXED_MSYS_VC) - -MIXED_VC=no -if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then - MIXED_VC=yes -fi - -AC_SUBST(MIXED_VC) - -if test "x$MIXED_MSYS" != "xyes"; then - AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) - if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi - else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no - fi -else - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) - -AC_MSG_CHECKING(if we mix msys with another native compiler) -if test "X$MIXED_MSYS" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_MSYS) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_FIND_EMU_CC -dnl -dnl -dnl Tries fairly hard to find a C compiler that can handle jump tables. -dnl Defines the @EMU_CC@ variable for the makefiles and -dnl inserts NO_JUMP_TABLE in the header if one cannot be found... -dnl - -AC_DEFUN(LM_FIND_EMU_CC, - [AC_CACHE_CHECK(for a compiler that handles jumptables, - ac_cv_prog_emu_cc, - [ -AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; -lbl1: - return 1; -lbl2: - return 2; -],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - -if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc-4.2 gcc; do - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_progname; then - ac_cv_prog_emu_cc=$ac_dir/$ac_progname - break - fi - done - IFS="$ac_save_ifs" - if test $ac_cv_prog_emu_cc != no; then - break - fi - done -fi - -if test $ac_cv_prog_emu_cc != no; then - save_CC=$CC - save_CFLAGS=$CFLAGS - save_CPPFLAGS=$CPPFLAGS - CC=$ac_cv_prog_emu_cc - CFLAGS="" - CPPFLAGS="" - AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; - lbl1: - return 1; - lbl2: - return 2; - ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - CC=$save_CC - CFLAGS=$save_CFLAGS - CPPFLAGS=$save_CPPFLAGS -fi -]) -if test $ac_cv_prog_emu_cc = no; then - AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) - EMU_CC=$CC -else - EMU_CC=$ac_cv_prog_emu_cc -fi -AC_SUBST(EMU_CC) -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_INSTALL_DIR -dnl -dnl This macro may be used by any OTP application. -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 -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_PERL5 -dnl -dnl Try to find perl version 5. If found set PERL to the absolute path -dnl of the program, if not found set PERL to false. -dnl -dnl On some systems /usr/bin/perl is perl 4 and e.g. -dnl /usr/local/bin/perl is perl 5. We try to handle this case by -dnl putting a couple of -dnl Tries to handle the case that there are two programs called perl -dnl in the path and one of them is perl 5 and the other isn't. -dnl -AC_DEFUN(LM_PROG_PERL5, -[AC_PATH_PROGS(PERL, perl5 perl, false, - /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) -changequote(, )dnl -dnl[ That bracket is needed to balance the right bracket below -if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then -changequote([, ])dnl - ac_cv_path_PERL=false - PERL=false -dnl AC_MSG_WARN(perl version 5 not found) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SO_BSDCOMPAT -dnl -dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) -dnl -AC_DEFUN(LM_DECL_SO_BSDCOMPAT, -[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, -AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], - ac_cv_decl_so_bsdcompat=yes, - ac_cv_decl_so_bsdcompat=no)) - -case "${ac_cv_decl_so_bsdcompat}" in - "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], - [Define if you have SO_BSDCOMPAT flag on sockets]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_INADDR_LOOPBACK -dnl -dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default -dnl - -AC_DEFUN(LM_DECL_INADDR_LOOPBACK, -[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], - ac_cv_decl_inaddr_loopback, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], -ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) -]) - -if test ${ac_cv_decl_inaddr_loopback} = no; then - AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], - ac_cv_decl_inaddr_loopback_rpc, - AC_TRY_COMPILE([#include <rpc/types.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_rpc=yes, - ac_cv_decl_inaddr_loopback_rpc=no)) - - case "${ac_cv_decl_inaddr_loopback_rpc}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], - [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; - * ) - AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], - ac_cv_decl_inaddr_loopback_winsock2, - AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN - #include <winsock2.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_winsock2=yes, - ac_cv_decl_inaddr_loopback_winsock2=no)) - case "${ac_cv_decl_inaddr_loopback_winsock2}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], - [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; - * ) - # couldn't find it anywhere - AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], - [Define if you don't have a definition of INADDR_LOOPBACK]) ;; - esac;; - esac -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_SOCKADDR_SA_LEN -dnl -dnl Check if the sockaddr structure has the field sa_len -dnl - -AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, -[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], - ac_cv_struct_sockaddr_sa_len, -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], - ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) - -dnl FIXME convbreak -case ${ac_cv_struct_sockaddr_sa_len} in - "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; - *) ;; -esac -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_EXCEPTION -dnl -dnl Check to see whether the system supports the matherr function -dnl and its associated type "struct exception". -dnl - -AC_DEFUN(LM_STRUCT_EXCEPTION, -[AC_CACHE_CHECK([for struct exception (and matherr function)], - ac_cv_struct_exception, -AC_TRY_COMPILE([#include <math.h>], - [struct exception x; x.type = DOMAIN; x.type = SING;], - ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) - -case "${ac_cv_struct_exception}" in - "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_IPV6 -dnl -dnl Check for ipv6 support and what the in6_addr structure is called. -dnl (early linux used in_addr6 insted of in6_addr) -dnl - -AC_DEFUN(LM_SYS_IPV6, -[AC_MSG_CHECKING(for IP version 6 support) -AC_CACHE_VAL(ac_cv_sys_ipv6_support, -[ok_so_far=yes - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) - -if test $ok_so_far = yes; then - ac_cv_sys_ipv6_support=yes -else - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in_addr6 a6; struct sockaddr_in6 s6;], - ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) -fi -])dnl - -dnl -dnl Have to use old style AC_DEFINE due to BC with old autoconf. -dnl - -case ${ac_cv_sys_ipv6_support} in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - ;; - in_addr6) - AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) - ;; - *) - AC_MSG_RESULT(no) - ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_MULTICAST -dnl -dnl Check for multicast support. Only checks for multicast options in -dnl setsockopt(), no check is performed that multicasting actually works. -dnl If options are found defines HAVE_MULTICAST_SUPPORT -dnl - -AC_DEFUN(LM_SYS_MULTICAST, -[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, -[AC_EGREP_CPP(yes, -[#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) -yes -#endif -], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) -if test $ac_cv_sys_multicast_support = yes; then - AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], - [Define if setsockopt() accepts multicast options]) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SYS_ERRLIST -dnl -dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared -dnl in a system header file, stdio.h or errno.h. -dnl - -AC_DEFUN(LM_DECL_SYS_ERRLIST, -[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], - ac_cv_decl_sys_errlist, -[AC_TRY_COMPILE([#include <stdio.h> -#include <errno.h>], [char *msg = *(sys_errlist + 1);], - ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) -if test $ac_cv_decl_sys_errlist = yes; then - AC_DEFINE(SYS_ERRLIST_DECLARED,[], - [define if the variable sys_errlist is declared in a system header file]) -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes -dnl [, action-if-found [, action-if-not-found]]] ) -dnl -dnl Checks if the declaration "declaration" of "funname" conflicts -dnl with the header files idea of how the function should be -dnl declared. It is useful on systems which lack prototypes and you -dnl need to provide your own (e.g. when you want to take the address -dnl of a function). The 4'th argument is expanded if conflicting, -dnl the 5'th argument otherwise -dnl -dnl - -AC_DEFUN(LM_CHECK_FUNC_DECL, -[AC_MSG_CHECKING([for conflicting declaration of $1]) -AC_CACHE_VAL(ac_cv_func_decl_$1, -[AC_TRY_COMPILE([#include <stdio.h> -$3],[$2 -char *c = (char *)$1; -], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) -if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then - AC_MSG_RESULT(yes) - ifelse([$4], , :, [$4]) -else - AC_MSG_RESULT(no) -ifelse([$5], , , [$5 -])dnl -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl AC_DOUBLE_MIDDLE_ENDIAN -dnl -dnl Checks whether doubles are represented in "middle-endian" format. -dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly, -dnl as well as DOUBLE_MIDDLE_ENDIAN. -dnl -dnl - -AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN], -[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian, -[# It does not; compile a test program. -AC_RUN_IFELSE( -[AC_LANG_SOURCE([[#include <stdlib.h> - -int -main(void) -{ - int i = 0; - int zero = 0; - int bigendian; - int zero_index = 0; - - union - { - long int l; - char c[sizeof (long int)]; - } u; - - /* we'll use the one with 32-bit words */ - union - { - double d; - unsigned int c[2]; - } vint; - - union - { - double d; - unsigned long c[2]; - } vlong; - - union - { - double d; - unsigned short c[2]; - } vshort; - - - /* Are we little or big endian? From Harbison&Steele. */ - u.l = 1; - bigendian = (u.c[sizeof (long int) - 1] == 1); - - zero_index = bigendian ? 1 : 0; - - vint.d = 1.0; - vlong.d = 1.0; - vshort.d = 1.0; - - if (sizeof(unsigned int) == 4) - { - if (vint.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned long) == 4) - { - if (vlong.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned short) == 4) - { - if (vshort.c[zero_index] != 0) - zero = 1; - } - - exit (zero); -} -]])], - [ac_cv_c_double_middle_endian=no], - [ac_cv_c_double_middle_endian=yes], - [ac_cv_c_double_middle=unknown])]) -case $ac_cv_c_double_middle_endian in - yes) - m4_default([$1], - [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1, - [Define to 1 if your processor stores the words in a double in - middle-endian format (like some ARMs).])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_WARN([unknown double endianness -presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;; -esac -])# AC_C_DOUBLE_MIDDLE_ENDIAN - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_THR_LIB -dnl -dnl This macro may be used by any OTP application. -dnl -dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also -dnl checks for some pthread headers which will appear in DEFS or config.h. -dnl - -AC_DEFUN(LM_CHECK_THR_LIB, -[ - -NEED_NPTL_PTHREAD_H=no - -dnl win32? -AC_MSG_CHECKING([for native win32 threads]) -if test "X$host_os" = "Xwin32"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DWIN32_THREADS" - THR_LIBS= - THR_LIB_NAME=win32_threads - THR_LIB_TYPE=win32_threads -elif test "X$host_os" = "Xose"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DOSE_THREADS" - THR_LIBS= - THR_LIB_NAME=ose_threads - THR_LIB_TYPE=ose_threads -else - AC_MSG_RESULT(no) - THR_DEFS= - THR_LIBS= - THR_LIB_NAME= - THR_LIB_TYPE=posix_unknown - -dnl Try to find POSIX threads - -dnl The usual pthread lib... - AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") - -dnl Very old versions of FreeBSD have pthreads in special c library, c_r... - if test "x$THR_LIBS" = "x"; then - AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") - fi - -dnl QNX has pthreads in standard C library - if test "x$THR_LIBS" = "x"; then - AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed") - fi - -dnl On ofs1 the '-pthread' switch should be used - if test "x$THR_LIBS" = "x"; then - AC_MSG_CHECKING([if the '-pthread' switch can be used]) - saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -pthread" - AC_TRY_LINK([#include <pthread.h>], - pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, - [THR_DEFS="-pthread" - THR_LIBS="-pthread"]) - CFLAGS=$saved_cflags - if test "x$THR_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - fi - - if test "x$THR_LIBS" != "x"; then - THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" - THR_LIB_NAME=pthread - if test "x$THR_LIBS" = "xnone_needed"; then - THR_LIBS= - fi - case $host_os in - solaris*) - THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; - linux*) - THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" - - LM_CHECK_GETCONF - AC_MSG_CHECKING(for Native POSIX Thread Library) - libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` - if test $? -eq 0; then - case "$libpthr_vsn" in - *nptl*|*NPTL*) nptl=yes;; - *) nptl=no;; - esac - elif test "$cross_compiling" = "yes"; then - case "$erl_xcomp_linux_nptl" in - "") nptl=cross;; - yes|no) nptl=$erl_xcomp_linux_nptl;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; - esac - else - nptl=no - fi - AC_MSG_RESULT($nptl) - if test $nptl = cross; then - nptl=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $nptl = yes; then - THR_LIB_TYPE=posix_nptl - need_nptl_incldir=no - AC_CHECK_HEADER(nptl/pthread.h, - [need_nptl_incldir=yes - NEED_NPTL_PTHREAD_H=yes]) - if test $need_nptl_incldir = yes; then - # Ahh... - nptl_path="$C_INCLUDE_PATH:$CPATH" - if test X$cross_compiling != Xyes; then - nptl_path="$nptl_path:/usr/local/include:/usr/include" - else - IROOT="$erl_xcomp_isysroot" - test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" - test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) - nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" - fi - nptl_ws_path= - save_ifs="$IFS"; IFS=":" - for dir in $nptl_path; do - if test "x$dir" != "x"; then - nptl_ws_path="$nptl_ws_path $dir" - fi - done - IFS=$save_ifs - nptl_incldir= - for dir in $nptl_ws_path; do - AC_CHECK_HEADER($dir/nptl/pthread.h, - nptl_incldir=$dir/nptl) - if test "x$nptl_incldir" != "x"; then - THR_DEFS="$THR_DEFS -isystem $nptl_incldir" - break - fi - done - if test "x$nptl_incldir" = "x"; then - AC_MSG_ERROR(Failed to locate nptl system include directory) - fi - fi - fi - ;; - *) ;; - esac - - dnl We sometimes need THR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $THR_DEFS" - - dnl - dnl Check for headers - dnl - - AC_CHECK_HEADER(pthread.h, - AC_DEFINE(HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - fi -fi - -]) - -AC_DEFUN(ERL_INTERNAL_LIBS, -[ - -ERTS_INTERNAL_X_LIBS= - -AC_CHECK_LIB(kstat, kstat_open, -[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) -ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) - -AC_SUBST(ERTS_INTERNAL_X_LIBS) - -]) - -AC_DEFUN(ETHR_CHK_SYNC_OP, -[ - AC_MSG_CHECKING([for $3-bit $1()]) - case "$2" in - "1") sync_call="$1(&var);";; - "2") sync_call="$1(&var, ($4) 0);";; - "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; - esac - have_sync_op=no - AC_TRY_LINK([], - [ - $4 res; - volatile $4 var; - res = $sync_call - ], - [have_sync_op=yes]) - test $have_sync_op = yes && $5 - AC_MSG_RESULT([$have_sync_op]) -]) - -AC_DEFUN(ETHR_CHK_INTERLOCKED, -[ - ilckd="$1" - AC_MSG_CHECKING([for ${ilckd}()]) - case "$2" in - "1") ilckd_call="${ilckd}(var);";; - "2") ilckd_call="${ilckd}(var, ($3) 0);";; - "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; - "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; - esac - have_interlocked_op=no - AC_TRY_LINK( - [ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <intrin.h> - ], - [ - volatile $3 *var; - volatile $3 arr[2]; - - $ilckd_call - return 0; - ], - [have_interlocked_op=yes]) - test $have_interlocked_op = yes && $4 - AC_MSG_RESULT([$have_interlocked_op]) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_FIND_ETHR_LIB -dnl -dnl NOTE! This macro may be changed at any time! Should *only* be used by -dnl ERTS! -dnl -dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link -dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS -dnl except that the ethread lib itself is not included), ETHR_DEFS to -dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the -dnl thread library which the ethread library is based on, and ETHR_LIB_NAME -dnl to the name of the library where the ethread implementation is located. -dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and -dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, -dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the -dnl empty string. -dnl - -AC_DEFUN(ERL_FIND_ETHR_LIB, -[ - -AC_ARG_ENABLE(native-ethr-impls, - AS_HELP_STRING([--disable-native-ethr-impls], - [disable native ethread implementations]), -[ case "$enableval" in - no) disable_native_ethr_impls=yes ;; - *) disable_native_ethr_impls=no ;; - esac ], disable_native_ethr_impls=no) - -test "X$disable_native_ethr_impls" = "Xyes" && - AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) - -AC_ARG_ENABLE(x86-out-of-order, - AS_HELP_STRING([--enable-x86-out-of-order], - [enable x86/x84_64 out of order support (default disabled)])) - -AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, - AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [prefer gcc native ethread implementations]), -[ case "$enableval" in - yes) enable_prefer_gcc_native_ethr_impls=yes ;; - *) enable_prefer_gcc_native_ethr_impls=no ;; - esac ], enable_prefer_gcc_native_ethr_impls=no) - -test $enable_prefer_gcc_native_ethr_impls = yes && - AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) - -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [specify and prefer usage of libatomic_ops in the ethread library])) - -AC_ARG_WITH(with_sparc_memory_order, - AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], - [specify sparc memory order (defaults to RMO)])) - -LM_CHECK_THR_LIB -ERL_INTERNAL_LIBS - -ethr_have_native_atomics=no -ethr_have_native_spinlock=no -ETHR_THR_LIB_BASE="$THR_LIB_NAME" -ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" -ETHR_DEFS="$THR_DEFS" -ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" -ETHR_LIBS= -ETHR_LIB_NAME= - -ethr_modified_default_stack_size= - -dnl Name of lib where ethread implementation is located -ethr_lib_name=ethread - -case "$THR_LIB_NAME" in - - win32_threads) - ETHR_THR_LIB_BASE_DIR=win - # * _WIN32_WINNT >= 0x0400 is needed for - # TryEnterCriticalSection - # * _WIN32_WINNT >= 0x0403 is needed for - # InitializeCriticalSectionAndSpinCount - # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. - # - # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it - # and save it in ETHR_DEFS. - found_win32_winnt=no - for cppflag in $CPPFLAGS; do - case $cppflag in - -DWINVER*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - ;; - -D_WIN32_WINNT*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - found_win32_winnt=yes - ;; - *) - ;; - esac - done - if test $found_win32_winnt = no; then - AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) - fi - - AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) - - if test "X$disable_native_ethr_impls" = "Xyes"; then - have_interlocked_op=no - ethr_have_native_atomics=no - else - ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) - fi - test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes - ;; - - pthread|ose_threads) - case "$THR_LIB_NAME" in - pthread) - ETHR_THR_LIB_BASE_DIR=pthread - AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) - ;; - ose_threads) - AC_DEFINE(ETHR_OSE_THREADS, 1, - [Define if you have OSE style threads]) - ETHR_THR_LIB_BASE_DIR=ose - AC_CHECK_HEADER(ose_spi/ose_spi.h, - AC_DEFINE(HAVE_OSE_SPI_H, 1, - [Define if you have the "ose_spi/ose_spi.h" header file.])) - ;; - esac - if test "x$THR_LIB_NAME" = "xpthread"; then - case $host_os in - openbsd*) - # The default stack size is insufficient for our needs - # on OpenBSD. We increase it to 256 kilo words. - ethr_modified_default_stack_size=256;; - linux*) - ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" - - if test X$cross_compiling = Xyes; then - case X$erl_xcomp_linux_usable_sigusrx in - X) usable_sigusrx=cross;; - Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; - esac - case X$erl_xcomp_linux_usable_sigaltstack in - X) usable_sigaltstack=cross;; - Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; - esac - else - # FIXME: Test for actual problems instead of kernel versions - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) - usable_sigusrx=no - usable_sigaltstack=no;; - 2.[[2-3]]|2.[[2-3]].*) - usable_sigusrx=yes - usable_sigaltstack=no;; - *) - usable_sigusrx=yes - usable_sigaltstack=yes;; - esac - fi - - AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) - AC_MSG_RESULT($usable_sigusrx) - if test $usable_sigusrx = cross; then - usable_sigusrx=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigusrx = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" - fi - - AC_MSG_CHECKING(if sigaltstack can be used) - AC_MSG_RESULT($usable_sigaltstack) - if test $usable_sigaltstack = cross; then - usable_sigaltstack=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigaltstack = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" - fi - ;; - *) ;; - esac - - fi - dnl We sometimes need ETHR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ETHR_DEFS" - - dnl We need the thread library in order to find some functions - saved_libs="$LIBS" - LIBS="$LIBS $ETHR_X_LIBS" - - dnl - dnl Check for headers - dnl - AC_CHECK_HEADER(pthread.h, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - if test $NEED_NPTL_PTHREAD_H = yes; then - AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ -[Define if you need the <nptl/pthread.h> header file.]) - fi - - AC_CHECK_HEADER(sched.h, \ - AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ -[Define if you have the <sched.h> header file.])) - - AC_CHECK_HEADER(sys/time.h, \ - AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ -[Define if you have the <sys/time.h> header file.])) - - AC_TRY_COMPILE([#include <time.h> - #include <sys/time.h>], - [struct timeval *tv; return 0;], - AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ -[Define if you can safely include both <sys/time.h> and <time.h>.])) - - - dnl - dnl Check for functions - dnl - if test "x$THR_LIB_NAME" = "xpthread"; then - AC_CHECK_FUNC(pthread_spin_lock, \ - [ethr_have_native_spinlock=yes \ - AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ -[Define if you have the pthread_spin_lock function.])]) - - have_sched_yield=no - have_librt_sched_yield=no - AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) - if test $have_sched_yield = no; then - AC_CHECK_LIB(rt, sched_yield, - [have_librt_sched_yield=yes - ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) - fi - if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then - AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) - AC_MSG_CHECKING([whether sched_yield() returns an int]) - sched_yield_ret_int=no - AC_TRY_COMPILE([ - #ifdef ETHR_HAVE_SCHED_H - #include <sched.h> - #endif - ], - [int sched_yield();], - [sched_yield_ret_int=yes]) - AC_MSG_RESULT([$sched_yield_ret_int]) - if test $sched_yield_ret_int = yes; then - AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) - fi - fi - - have_pthread_yield=no - AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) - if test $have_pthread_yield = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) - AC_MSG_CHECKING([whether pthread_yield() returns an int]) - pthread_yield_ret_int=no - AC_TRY_COMPILE([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [int pthread_yield();], - [pthread_yield_ret_int=yes]) - AC_MSG_RESULT([$pthread_yield_ret_int]) - if test $pthread_yield_ret_int = yes; then - AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) - fi - fi - - have_pthread_rwlock_init=no - AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) - if test $have_pthread_rwlock_init = yes; then - - ethr_have_pthread_rwlockattr_setkind_np=no - AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, - [ethr_have_pthread_rwlockattr_setkind_np=yes]) - - if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ -[Define if you have the pthread_rwlockattr_setkind_np() function.]) - - AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) - ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no - AC_TRY_LINK([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [ - pthread_rwlockattr_t *attr; - return pthread_rwlockattr_setkind_np(attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - ], - [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) - AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) - if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ -[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) - fi - fi - fi - - if test "$force_pthread_rwlocks" = "yes"; then - - AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ -[Define if you want to force usage of pthread rwlocks]) - - if test $have_pthread_rwlock_init = yes; then - AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) - else - AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) - fi - fi - - AC_CHECK_FUNC(pthread_attr_setguardsize, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ -[Define if you have the pthread_attr_setguardsize function.])) - - linux_futex=no - AC_MSG_CHECKING([for Linux futexes]) - AC_TRY_LINK([ - #include <sys/syscall.h> - #include <unistd.h> - #include <linux/futex.h> - #include <sys/time.h> - ], - [ - int i = 1; - syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, - (void*)0,(void*)0, 0); - syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, - (void*)0,(void*)0, 0); - return 0; - ], - linux_futex=yes) - AC_MSG_RESULT([$linux_futex]) - test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) - - fi - - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int128_t) - - if test "$ac_cv_sizeof_int" = "4"; then - int32="int" - elif test "$ac_cv_sizeof_long" = "4"; then - int32="long" - elif test "$ac_cv_sizeof_long_long" = "4"; then - int32="long long" - else - AC_MSG_ERROR([No 32-bit type found]) - fi - - if test "$ac_cv_sizeof_int" = "8"; then - int64="int" - elif test "$ac_cv_sizeof_long" = "8"; then - int64="long" - elif test "$ac_cv_sizeof_long_long" = "8"; then - int64="long long" - else - AC_MSG_ERROR([No 64-bit type found]) - fi - - int128=no - if test "$ac_cv_sizeof___int128_t" = "16"; then - int128="__int128_t" - fi - - if test "X$disable_native_ethr_impls" = "Xyes"; then - ethr_have_native_atomics=no - else - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) - - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) - - if test $int128 != no; then - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) - fi - - AC_MSG_CHECKING([for a usable libatomic_ops implementation]) - case "x$with_libatomic_ops" in - xno | xyes | x) - libatomic_ops_include= - ;; - *) - if test -d "${with_libatomic_ops}/include"; then - libatomic_ops_include="-I$with_libatomic_ops/include" - CPPFLAGS="$CPPFLAGS $libatomic_ops_include" - else - AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) - fi;; - esac - ethr_have_libatomic_ops=no - AC_TRY_LINK([#include "atomic_ops.h"], - [ - volatile AO_t x; - AO_t y; - int z; - - AO_nop_full(); - AO_store(&x, (AO_t) 0); - z = AO_load(&x); - z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); - ], - [ethr_have_native_atomics=yes - ethr_have_libatomic_ops=yes]) - AC_MSG_RESULT([$ethr_have_libatomic_ops]) - if test $ethr_have_libatomic_ops = yes; then - AC_CHECK_SIZEOF(AO_t, , - [ - #include <stdio.h> - #include "atomic_ops.h" - ]) - AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) - - AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) - if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) - fi - ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" - elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_MSG_ERROR([No usable libatomic_ops implementation found]) - fi - - case "$host_cpu" in - sparc | sun4u | sparc64 | sun4v) - case "$with_sparc_memory_order" in - "TSO") - AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; - "PSO") - AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; - "RMO"|"") - AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; - *) - AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; - esac - ethr_have_native_atomics=yes;; - i86pc | i*86 | x86_64 | amd64) - if test "$enable_x86_out_of_order" = "yes"; then - AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) - fi - ethr_have_native_atomics=yes;; - macppc | ppc | powerpc | "Power Macintosh") - ethr_have_native_atomics=yes;; - tile) - ethr_have_native_atomics=yes;; - *) - ;; - esac - - fi - - test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes - - dnl Restore LIBS - LIBS=$saved_libs - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - ;; - *) - ;; -esac - -AC_MSG_CHECKING([whether default stack size should be modified]) -if test "x$ethr_modified_default_stack_size" != "x"; then - AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) - AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) -else - AC_MSG_RESULT([no]) -fi - -if test "x$ETHR_THR_LIB_BASE" != "x"; then - ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" - ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" - ETHR_LIB_NAME=$ethr_lib_name -fi - -AC_CHECK_SIZEOF(void *) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) - -AC_CHECK_SIZEOF(int) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) -AC_CHECK_SIZEOF(long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) -AC_CHECK_SIZEOF(long long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) -AC_CHECK_SIZEOF(__int64) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) -AC_CHECK_SIZEOF(__int128_t) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) - - -case X$erl_xcomp_bigendian in - X) ;; - Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; - *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; -esac - -AC_C_BIGENDIAN - -if test "$ac_cv_c_bigendian" = "yes"; then - AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) -fi - -case X$erl_xcomp_double_middle_endian in - X) ;; - Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;; - *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);; -esac - -AC_C_DOUBLE_MIDDLE_ENDIAN - -ETHR_X86_SSE2_ASM=no -case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in - yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) - AC_MSG_CHECKING([for gcc sse2 asm support]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -msse2" - gcc_sse2_asm=no - AC_TRY_COMPILE([], - [ - long long x, *y; - __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); - ], - [gcc_sse2_asm=yes]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$gcc_sse2_asm]) - if test "$gcc_sse2_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) - ETHR_X86_SSE2_ASM=yes - fi - ;; - *) - ;; -esac - -case "$GCC-$host_cpu" in - yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) - gcc_dw_cmpxchg_asm=no - AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; - __asm__ __volatile__( -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "pushl %%ebx\n\t" - "movl %8, %%ebx\n\t" -#endif -#if ETHR_SIZEOF_PTR == 4 - "lock; cmpxchg8b %0\n\t" -#else - "lock; cmpxchg16b %0\n\t" -#endif - "setz %3\n\t" -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "popl %%ebx\n\t" -#endif - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "r"(new[0]) -#else - "b"(new[0]) -#endif - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; -#if !defined(__PIC__) || !__PIC__ -# error nope -#endif - __asm__ __volatile__( - "pushl %%ebx\n\t" - "movl (%7), %%ebx\n\t" - "movl 4(%7), %%ecx\n\t" - "lock; cmpxchg8b %0\n\t" - "setz %3\n\t" - "popl %%ebx\n\t" - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) - fi - fi - AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) - fi;; - *) - ;; -esac - -AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ -[Define if you have all ethread defines]) - -AC_SUBST(ETHR_X_LIBS) -AC_SUBST(ETHR_LIBS) -AC_SUBST(ETHR_LIB_NAME) -AC_SUBST(ETHR_DEFS) -AC_SUBST(ETHR_THR_LIB_BASE) -AC_SUBST(ETHR_THR_LIB_BASE_DIR) -AC_SUBST(ETHR_X86_SSE2_ASM) - -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_TIME_CORRECTION -dnl -dnl In the presence of a high resolution realtime timer Erlang can adapt -dnl its view of time relative to this timer. On solaris such a timer is -dnl available with the syscall gethrtime(). On other OS's a fallback -dnl solution using times() is implemented. (However on e.g. FreeBSD times() -dnl is implemented using gettimeofday so it doesn't make much sense to -dnl use it there...) On second thought, it seems to be safer to do it the -dnl other way around. I.e. only use times() on OS's where we know it will -dnl work... -dnl - -AC_DEFUN(ERL_TIME_CORRECTION, -[if test x$ac_cv_func_gethrtime = x; then - AC_CHECK_FUNC(gethrtime) -fi -if test x$clock_gettime_correction = xunknown; then - AC_TRY_COMPILE([#include <time.h>], - [struct timespec ts; - long long result; - clock_gettime(CLOCK_MONOTONIC,&ts); - result = ((long long) ts.tv_sec) * 1000000000LL + - ((long long) ts.tv_nsec);], - clock_gettime_compiles=yes, - clock_gettime_compiles=no) -else - clock_gettime_compiles=no -fi - - -AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, -[ -case $clock_gettime_correction in - yes) - erl_cv_time_correction=clock_gettime;; - no|unknown) - case $ac_cv_func_gethrtime in - yes) - erl_cv_time_correction=hrtime ;; - no) - case $host_os in - linux*) - case $clock_gettime_correction in - unknown) - if test x$clock_gettime_compiles = xyes; then - if test X$cross_compiling != Xyes; then - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) - erl_cv_time_correction=times ;; - *) - erl_cv_time_correction=clock_gettime;; - esac - else - case X$erl_xcomp_linux_clock_gettime_correction in - X) - erl_cv_time_correction=cross;; - Xyes|Xno) - if test $erl_xcomp_linux_clock_gettime_correction = yes; then - erl_cv_time_correction=clock_gettime - else - erl_cv_time_correction=times - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; - esac - fi - else - erl_cv_time_correction=times - fi - ;; - *) - erl_cv_time_correction=times ;; - esac - ;; - *) - erl_cv_time_correction=none ;; - esac - ;; - esac - ;; -esac -]) - -xrtlib="" -case $erl_cv_time_correction in - times) - AC_DEFINE(CORRECT_USING_TIMES,[], - [Define if you do not have a high-res. timer & want to use times() instead]) - ;; - clock_gettime|cross) - if test $erl_cv_time_correction = cross; then - erl_cv_time_correction=clock_gettime - AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) - fi - xrtlib="-lrt" - AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], - [Define if you want to use clock_gettime to simulate gethrtime]) - ;; -esac -dnl -dnl Check if gethrvtime is working, and if to use procfs ioctl -dnl or (yet to be written) write to the procfs ctl file. -dnl - -AC_MSG_CHECKING([if gethrvtime works and how to use it]) -AC_TRY_RUN([ -/* gethrvtime procfs ioctl test */ -/* These need to be undef:ed to not break activation of - * micro level process accounting on /proc/self - */ -#ifdef _LARGEFILE_SOURCE -# undef _LARGEFILE_SOURCE -#endif -#ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -#endif -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/signal.h> -#include <sys/fault.h> -#include <sys/syscall.h> -#include <sys/procfs.h> -#include <fcntl.h> - -int main() { - long msacct = PR_MSACCT; - int fd; - long long start, stop; - int i; - pid_t pid = getpid(); - char proc_self[30] = "/proc/"; - - sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); - if ( (fd = open(proc_self, O_WRONLY)) == -1) - exit(1); - if (ioctl(fd, PIOCSET, &msacct) < 0) - exit(2); - if (close(fd) < 0) - exit(3); - start = gethrvtime(); - for (i = 0; i < 100; i++) - stop = gethrvtime(); - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; -} -], -erl_gethrvtime=procfs_ioctl, -erl_gethrvtime=false, -[ -case X$erl_xcomp_gethrvtime_procfs_ioctl in - X) - erl_gethrvtime=cross;; - Xyes|Xno) - if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then - erl_gethrvtime=procfs_ioctl - else - erl_gethrvtime=false - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; -esac -]) - -case $erl_gethrvtime in - procfs_ioctl) - AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], - [define if gethrvtime() works and uses ioctl() to /proc/self]) - AC_MSG_RESULT(uses ioctl to procfs) - ;; - *) - if test $erl_gethrvtime = cross; then - erl_gethrvtime=false - AC_MSG_RESULT(cross) - AC_MSG_WARN([result 'not working' guessed because of cross compilation]) - else - AC_MSG_RESULT(not working) - fi - - dnl - dnl Check if clock_gettime (linux) is working - dnl - - AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) - save_libs=$LIBS - LIBS="-lrt" - AC_TRY_RUN([ - #include <stdlib.h> - #include <unistd.h> - #include <string.h> - #include <stdio.h> - #include <time.h> - int main() { - long long start, stop; - int i; - struct timespec tp; - - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) - exit(1); - start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - for (i = 0; i < 100; i++) - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); - stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; - } - ], - erl_clock_gettime=yes, - erl_clock_gettime=no, - [ - case X$erl_xcomp_clock_gettime_cpu_time in - X) erl_clock_gettime=cross;; - Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; - *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; - esac - ]) - LIBS=$save_libs - case $host_os in - linux*) - AC_MSG_RESULT([no; not stable]) - LIBRT=$xrtlib - ;; - *) - AC_MSG_RESULT($erl_clock_gettime) - case $erl_clock_gettime in - yes) - AC_DEFINE(HAVE_CLOCK_GETTIME,[], - [define if clock_gettime() works for getting process time]) - LIBRT=-lrt - ;; - cross) - erl_clock_gettime=no - AC_MSG_WARN([result no guessed because of cross compilation]) - LIBRT=$xrtlib - ;; - *) - LIBRT=$xrtlib - ;; - esac - ;; - esac - AC_SUBST(LIBRT) - ;; -esac -])dnl - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_TRY_ENABLE_CFLAG -dnl -dnl -dnl Tries a CFLAG and sees if it can be enabled without compiler errors -dnl $1: textual cflag to add -dnl $2: variable to store the modified CFLAG in -dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS]) -dnl -dnl -AC_DEFUN([LM_TRY_ENABLE_CFLAG], [ - AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)]) - saved_CFLAGS=$CFLAGS; - CFLAGS="$1 $$2"; - AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false) - CFLAGS=$saved_CFLAGS; - if test "X$can_enable_flag" = "Xtrue"; then - AC_MSG_RESULT([yes]) - AS_VAR_SET($2, "$1 $$2") - else - AC_MSG_RESULT([no]) - fi -]) - -dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY -dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a -dnl AC_LANG_JAVA instead...) -AC_DEFUN(ERL_TRY_LINK_JAVA, -[java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(, )dnl -cat > conftest.java <<EOF -$1 -class conftest { public static void main(String[] args) { - $2 - ; return; }} -EOF -changequote([, ])dnl -if AC_TRY_EVAL(java_link) && test -s conftest.class; then - ifelse([$3], , :, [rm -rf conftest* - $3]) -else - echo "configure: failed program was:" 1>&AC_FD_CC - cat conftest.java 1>&AC_FD_CC - echo "configure: PATH was $PATH" 1>&AC_FD_CC -ifelse([$4], , , [ rm -rf conftest* - $4 -])dnl -fi -rm -f conftest*]) -#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ - - diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index a055e854e3..29a9d71041 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -30,6 +30,42 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.7.20</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Use C99 function isfinite() instead of finite() when + available on non GCC compilers.</p> + <p> + Own Id: OTP-12268</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + <item> + <p> + Added an .appup file for the application.</p> + <p> + Own Id: OTP-12358 Aux Id: OTP-12178 </p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.7.19</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index 7d914a02ca..7c09b605fa 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -43,10 +43,13 @@ include $(ERL_TOP)/make/output.mk EBINDIR=../ebin APP_FILE= erl_interface.app - APP_SRC= $(APP_FILE).src APP_TARGET= $(EBINDIR)/$(APP_FILE) +APPUP_FILE= erl_interface.appup +APPUP_SRC= $(APPUP_FILE).src +APPUP_TARGET= $(EBINDIR)/$(APPUP_FILE) + USING_MINGW=@MIXED_CYGWIN_MINGW@ USING_MSYS_VC==@MIXED_MSYS_VC@ USING_CYGWIN_VC==@MIXED_MSYS_VC@ @@ -220,7 +223,8 @@ ifeq ($(USING_VC),yes) TARGETS = \ $(OBJ_TARGETS) \ $(EXE_TARGETS) \ - $(APP_TARGET) + $(APP_TARGET) \ + $(APPUP_TARGET) OBJ_TARGETS = \ $(MT_EILIB) \ @@ -250,7 +254,8 @@ ifeq ($USING_MINGW,yes) TARGETS = \ $(OBJ_TARGETS) \ $(EXE_TARGETS) \ - $(APP_TARGET) + $(APP_TARGET) \ + $(APPUP_TARGET) OBJ_TARGETS = \ $(MD_EILIB) \ @@ -269,7 +274,8 @@ ifdef THR_DEFS TARGETS = \ $(OBJ_TARGETS) \ $(EXE_TARGETS) \ - $(APP_TARGET) + $(APP_TARGET) \ + $(APPUP_TARGET) OBJ_TARGETS = \ $(ST_EILIB) \ @@ -292,7 +298,8 @@ else TARGETS = \ $(OBJ_TARGETS) \ $(EXE_TARGETS) \ - $(APP_TARGET) + $(APP_TARGET) \ + $(APPUP_TARGET) OBJ_TARGETS = \ $(ST_EILIB) \ @@ -558,6 +565,8 @@ clean: rm -f $(MDD_EIOBJECTS) $(MDD_ERLOBJECTS) $(MDD_EILIB) $(MDD_ERLLIB) rm -f $(ERL_CALL) rm -f $(FAKE_TARGETS) + rm -f $(APP_TARGET) + rm -f $(APPUP_TARGET) distclean: clean rm -f config.h config.log config.status configure @@ -616,6 +625,8 @@ _create_dirs := $(shell mkdir -p $(EBINDIR) $(BINDIR) $(OBJDIR) $(ST_OBJDIR) $(M $(APP_TARGET): $(APP_SRC) ../vsn.mk $(vsn_verbose)sed -e 's;%VSN%;$(ERL_INTERFACE_VSN);' $< > $@ +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + $(vsn_verbose)sed -e 's;%VSN%;$(ERL_INTERFACE_VSN);' $< > $@ ifeq ($(TARGET),win32) @@ -884,6 +895,7 @@ release: opt $(INSTALL_DIR) "$(RELEASE_PATH)/usr/include" $(INSTALL_DIR) "$(RELEASE_PATH)/usr/lib" $(INSTALL_DATA) $(APP_TARGET) "$(RELSYSDIR)/ebin/$(APP_FILE)" + $(INSTALL_DATA) $(APPUP_TARGET) "$(RELSYSDIR)/ebin/$(APPUP_FILE)" $(INSTALL_DATA) $(HEADERS) "$(RELSYSDIR)/include" $(INSTALL_DATA) $(HEADERS) "$(RELEASE_PATH)/usr/include" $(INSTALL_DATA) $(OBJ_TARGETS) "$(RELSYSDIR)/lib" diff --git a/lib/erl_interface/src/auxdir/config.guess b/lib/erl_interface/src/auxdir/config.guess deleted file mode 100755 index f475ceb413..0000000000 --- a/lib/erl_interface/src/auxdir/config.guess +++ /dev/null @@ -1,1534 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to [email protected]. - - -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 1992-2013 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - 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 ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <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:*:[4567]) - 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 -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <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:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-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 ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </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 i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <[email protected]> - 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*) - # From [email protected]. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From [email protected]. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From [email protected]. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - 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 ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -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/erl_interface/src/auxdir/config.sub b/lib/erl_interface/src/auxdir/config.sub deleted file mode 100755 index bb6edbdb47..0000000000 --- a/lib/erl_interface/src/auxdir/config.sub +++ /dev/null @@ -1,1789 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to [email protected]. -# -# 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. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# 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 1992-2013 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-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - 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 | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -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 \ - | aarch64 | aarch64_be \ - | 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[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-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-* \ - | aarch64-* | aarch64_be-* \ - | 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-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | 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-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - 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-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - 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 - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - 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 | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - 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 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - 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 - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -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* | -es*) - # 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 - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -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 - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - 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 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or1k-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: - diff --git a/lib/erl_interface/src/auxdir/install-sh b/lib/erl_interface/src/auxdir/install-sh deleted file mode 100755 index a5897de6ea..0000000000 --- a/lib/erl_interface/src/auxdir/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/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c index b54ac85be2..477880b331 100644 --- a/lib/erl_interface/src/decode/decode_big.c +++ b/lib/erl_interface/src/decode/decode_big.c @@ -151,13 +151,29 @@ int ei_big_comp(erlang_big *x, erlang_big *y) #endif #ifdef USE_ISINF_ISNAN /* simulate finite() */ -# define finite(f) (!isinf(f) && !isnan(f)) -# define HAVE_FINITE +# define isfinite(f) (!isinf(f) && !isnan(f)) +# define HAVE_ISFINITE +#elif defined(__GNUC__) && defined(HAVE_FINITE) +/* We use finite in gcc as it emits assembler instead of + the function call that isfinite emits. The assembler is + significantly faster. */ +# ifdef isfinite +# undef isfinite +# endif +# define isfinite finite +# ifndef HAVE_ISFINITE +# define HAVE_ISFINITE +# endif +#elif defined(isfinite) && !defined(HAVE_ISFINITE) +# define HAVE_ISFINITE +#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE) +# define isfinite finite +# define HAVE_ISFINITE #endif #ifdef NO_FPE_SIGNALS # define ERTS_FP_CHECK_INIT() do {} while (0) -# define ERTS_FP_ERROR(f, Action) if (!finite(f)) { Action; } else {} +# define ERTS_FP_ERROR(f, Action) if (!isfinite(f)) { Action; } else {} # define ERTS_SAVE_FP_EXCEPTION() # define ERTS_RESTORE_FP_EXCEPTION() #else diff --git a/lib/erl_interface/src/erl_interface.appup.src b/lib/erl_interface/src/erl_interface.appup.src new file mode 100644 index 0000000000..d267e3d3d5 --- /dev/null +++ b/lib/erl_interface/src/erl_interface.appup.src @@ -0,0 +1,18 @@ +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2014. 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% +{"%VSN%", [], []}. diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index e39aa4f514..c809d5421e 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 3.7.19 +EI_VSN = 3.7.20 ERL_INTERFACE_VSN = $(EI_VSN) diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml index e5a190e3e9..6b76e097b6 100644 --- a/lib/eunit/doc/src/notes.xml +++ b/lib/eunit/doc/src/notes.xml @@ -32,6 +32,28 @@ </header> <p>This document describes the changes made to the EUnit application.</p> +<section><title>Eunit 2.2.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure to install .hrl files when needed</p> + <p> + Own Id: OTP-12197</p> + </item> + <item> + <p> + Make sure the clean rule for ssh, ssl, eunit and otp_mibs + actually removes generated files.</p> + <p> + Own Id: OTP-12200</p> + </item> + </list> + </section> + +</section> + <section><title>Eunit 2.2.8</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk index 855e1dac88..dca8b3ece0 100644 --- a/lib/eunit/vsn.mk +++ b/lib/eunit/vsn.mk @@ -1 +1 @@ -EUNIT_VSN = 2.2.8 +EUNIT_VSN = 2.2.9 diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 4b2bec5fa8..4215448c61 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2014. All Rights Reserved. +%% Copyright Ericsson AB 2003-2015. 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 @@ -4230,7 +4230,7 @@ t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) -> t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) -> {t_arity(), []}; t_from_form({type, _L, array, []}, TypeNames, RecDict, VarDict) -> - builtin_type(array, t_array(), TypeNames, RecDict, VarDict); + builtin_type(array, t_array(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) -> {t_atom(), []}; t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) -> @@ -4253,9 +4253,9 @@ t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) -> t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) -> {t_char(), []}; t_from_form({type, _L, dict, []}, TypeNames, RecDict, VarDict) -> - builtin_type(dict, t_dict(), TypeNames, RecDict, VarDict); + builtin_type(dict, t_dict(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, digraph, []}, TypeNames, RecDict, VarDict) -> - builtin_type(digraph, t_digraph(), TypeNames, RecDict, VarDict); + builtin_type(digraph, t_digraph(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) -> {t_float(), []}; t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) -> @@ -4272,9 +4272,9 @@ t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]}, {T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict), {t_fun(L, T), R1 ++ R2}; t_from_form({type, _L, gb_set, []}, TypeNames, RecDict, VarDict) -> - builtin_type(gb_set, t_gb_set(), TypeNames, RecDict, VarDict); + builtin_type(gb_set, t_gb_set(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, gb_tree, []}, TypeNames, RecDict, VarDict) -> - builtin_type(gb_tree, t_gb_tree(), TypeNames, RecDict, VarDict); + builtin_type(gb_tree, t_gb_tree(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) -> {t_identifier(), []}; t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) -> @@ -4288,8 +4288,12 @@ t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) -> t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) -> {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict), {t_list(T), R}; -t_from_form({type, _L, map, _}, TypeNames, RecDict, VarDict) -> - builtin_type(map, t_map([]), TypeNames, RecDict, VarDict); +t_from_form({type, _L, map, As0}, TypeNames, RecDict, VarDict) -> + As = case is_list(As0) of + true -> As0; + false -> [] + end, + builtin_type(map, t_map([]), As, TypeNames, RecDict, VarDict); t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) -> {t_mfa(), []}; t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) -> @@ -4348,7 +4352,7 @@ t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) -> {L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict), {t_product(L), R}; t_from_form({type, _L, queue, []}, TypeNames, RecDict, VarDict) -> - builtin_type(queue, t_queue(), TypeNames, RecDict, VarDict); + builtin_type(queue, t_queue(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, range, [From, To]} = Type, _TypeNames, _RecDict, _VarDict) -> case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of @@ -4361,13 +4365,13 @@ t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) -> t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) -> {t_reference(), []}; t_from_form({type, _L, set, []}, TypeNames, RecDict, VarDict) -> - builtin_type(set, t_set(), TypeNames, RecDict, VarDict); + builtin_type(set, t_set(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) -> {t_string(), []}; t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) -> {t_any(), []}; t_from_form({type, _L, tid, []}, TypeNames, RecDict, VarDict) -> - builtin_type(tid, t_tid(), TypeNames, RecDict, VarDict); + builtin_type(tid, t_tid(), [], TypeNames, RecDict, VarDict); t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) -> {t_timeout(), []}; t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) -> @@ -4384,10 +4388,10 @@ t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _RecDict, _VarDict) -> {t_opaque(Mod, Name, Args, Rep), []}. -builtin_type(Name, Type, TypeNames, RecDict, VarDict) -> - case lookup_type(Name, 0, RecDict) of +builtin_type(Name, Type, Args, TypeNames, RecDict, VarDict) -> + case lookup_type(Name, length(Args), RecDict) of {_, {_M, _T, _A}} -> - type_from_form(Name, [], TypeNames, RecDict, VarDict); + type_from_form(Name, Args, TypeNames, RecDict, VarDict); error -> {Type, []} end. @@ -4588,7 +4592,7 @@ t_form_to_string({type, _L, iodata, []}) -> "iodata()"; t_form_to_string({type, _L, iolist, []}) -> "iolist()"; t_form_to_string({type, _L, list, [Type]}) -> "[" ++ t_form_to_string(Type) ++ "]"; -t_form_to_string({type, _L, map, _}) -> +t_form_to_string({type, _L, map, Args}) when not is_list(Args) -> "#{}"; t_form_to_string({type, _L, mfa, []}) -> "mfa()"; t_form_to_string({type, _L, module, []}) -> "module()"; diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 2962e4a9ac..2d6fd245f7 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.11.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed internal elf_format hrl file to contain valid + erlang</p> + <p> + Own Id: OTP-12322</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.11.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/llvm/elf_format.hrl b/lib/hipe/llvm/elf_format.hrl index 78592e6e2a..7a3cdfead6 100644 --- a/lib/hipe/llvm/elf_format.hrl +++ b/lib/hipe/llvm/elf_format.hrl @@ -68,7 +68,7 @@ -define(E_IDENT, {?E_IDENT_OFFSET, ?E_IDENT_SIZE}). -define(E_TYPE, {?E_TYPE_OFFSET, ?E_TYPE_SIZE}). -define(E_MACHINE, {?E_MACHINE_OFFSET, ?E_MACHINE_SIZE}). --define(E_VERSION, {?E_VERSION_OFFSET, ?E_VERSION_SIZE}) +-define(E_VERSION, {?E_VERSION_OFFSET, ?E_VERSION_SIZE}). -define(E_ENTRY, {?E_ENTRY_OFFSET, ?E_ENTRY_SIZE}). -define(E_PHOFF, {?E_PHOFF_OFFSET, ?E_PHOFF_SIZE}). -define(E_SHOFF, {?E_SHOFF_OFFSET, ?E_SHOFF_SIZE}). diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl index 7dfa56df29..a55fc137c3 100644 --- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl +++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl @@ -102,10 +102,18 @@ conv_insn(I, Map, Data) -> end. conv_fconv(I, Map, Data) -> - %% Dst := (double)Src, where Dst is FP reg and Src is int reg + %% Dst := (double)Src, where Dst is FP reg and Src is GP reg or imm {Dst, Map0} = conv_fpreg(hipe_rtl:fconv_dst(I), Map), - {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0), % exclude imm src - I2 = mk_fconv(Dst, Src), + {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0), + I2 = + case hipe_ppc:is_temp(Src) of + true -> + mk_fconv(Dst, Src); + false -> + Tmp = new_untagged_temp(), + mk_li(Tmp, Src, + mk_fconv(Dst, Tmp)) + end, {I2, Map1, Data}. mk_fconv(Dst, Src) -> diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index bc61bec0bd..2f62dd79ad 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -413,11 +413,11 @@ rtl_info_update(Rtl, Info) -> Rtl#rtl{info=Info}. %% move %% -mk_move(Dst, Src) -> #move{dst=Dst, src=Src}. +mk_move(Dst, Src) -> false = is_fpreg(Dst), false = is_fpreg(Src), #move{dst=Dst, src=Src}. move_dst(#move{dst=Dst}) -> Dst. -move_dst_update(M, NewDst) -> M#move{dst=NewDst}. +move_dst_update(M, NewDst) -> false = is_fpreg(NewDst), M#move{dst=NewDst}. move_src(#move{src=Src}) -> Src. -move_src_update(M, NewSrc) -> M#move{src=NewSrc}. +move_src_update(M, NewSrc) -> false = is_fpreg(NewSrc), M#move{src=NewSrc}. %% is_move(#move{}) -> true; %% is_move(_) -> false. @@ -469,7 +469,11 @@ phi_remove_pred(Phi, Pred) -> case NewArgList of [Arg] -> %% the phi should be turned into a move instruction {_Label,Var} = Arg, - mk_move(phi_dst(Phi), Var); + Dst = phi_dst(Phi), + case {is_fpreg(Dst), is_fpreg(Var)} of + {true, true} -> mk_fmove(Dst, Var); + {false, false} -> mk_move(Dst, Var) + end; %% io:format("~nPhi (~w) turned into move (~w) when removing pred ~w~n",[Phi,Move,Pred]), [_|_] -> Phi#phi{arglist=NewArgList} @@ -836,11 +840,11 @@ fp_unop_op(#fp_unop{op=Op}) -> Op. %% fmove %% -mk_fmove(X, Y) -> #fmove{dst=X, src=Y}. +mk_fmove(X, Y) -> true = is_fpreg(X), true = is_fpreg(Y), #fmove{dst=X, src=Y}. fmove_dst(#fmove{dst=Dst}) -> Dst. -fmove_dst_update(M, NewDst) -> M#fmove{dst=NewDst}. +fmove_dst_update(M, NewDst) -> true = is_fpreg(NewDst), M#fmove{dst=NewDst}. fmove_src(#fmove{src=Src}) -> Src. -fmove_src_update(M, NewSrc) -> M#fmove{src=NewSrc}. +fmove_src_update(M, NewSrc) -> true = is_fpreg(NewSrc), M#fmove{src=NewSrc}. %% %% fconv diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl index 8831199244..af8903904b 100644 --- a/lib/hipe/rtl/hipe_rtl_binary_match.erl +++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl @@ -990,19 +990,19 @@ unsigned_bignum(Dst1, Src, TrueLblName) -> hipe_tagscheme:unsafe_mk_big(Dst1, Src, unsigned), hipe_rtl:mk_goto(TrueLblName)]. -load_bytes(Dst, Base, Offset, {Signedness, _Endianess},1) -> +load_bytes(Dst, Base, Offset, {Signedness, _Endianness},1) -> [hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness), hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))]; -load_bytes(Dst, Base, Offset, {Signedness, Endianess},2) -> - case Endianess of +load_bytes(Dst, Base, Offset, {Signedness, Endianness},2) -> + case Endianness of big -> hipe_rtl_arch:load_big_2(Dst, Base, Offset, Signedness); little -> hipe_rtl_arch:load_little_2(Dst, Base, Offset, Signedness) end; -load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) -> +load_bytes(Dst, Base, Offset, {Signedness, Endianness},3) -> Tmp1 = hipe_rtl:mk_new_reg(), - case Endianess of + case Endianness of big -> [hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness), hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1)), @@ -1026,18 +1026,18 @@ load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) -> hipe_rtl:mk_alu(Dst, Dst, 'or', Tmp1), hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))] end; -load_bytes(Dst, Base, Offset, {Signedness, Endianess}, 4) -> - case Endianess of +load_bytes(Dst, Base, Offset, {Signedness, Endianness}, 4) -> + case Endianness of big -> hipe_rtl_arch:load_big_4(Dst, Base, Offset, Signedness); little -> hipe_rtl_arch:load_little_4(Dst, Base, Offset, Signedness) end; -load_bytes(Dst, Base, Offset, {Signedness, Endianess}, X) when X > 1 -> +load_bytes(Dst, Base, Offset, {Signedness, Endianness}, X) when X > 1 -> [LoopLbl, EndLbl] = create_lbls(2), [Tmp1, Limit, TmpOffset] = create_regs(3), - case Endianess of + case Endianness of big -> [hipe_rtl:mk_alu(Limit, Offset, add, hipe_rtl:mk_imm(X)), hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness), diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl index dc001f865e..fd21be3ae7 100644 --- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl +++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl @@ -85,17 +85,17 @@ conv_insn(I, Map, Data) -> end. conv_fconv(I, Map, Data) -> - %% Dst := (double)Src, where Dst is FP reg and Src is int reg - {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map), % exclude imm src + %% Dst := (double)Src, where Dst is FP reg and Src is GP reg or imm + {Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map), {Dst, Map2} = conv_fpreg(hipe_rtl:fconv_dst(I), Map1), I2 = mk_fconv(Src, Dst), {I2, Map2, Data}. mk_fconv(Src, Dst) -> CSP = hipe_sparc:mk_temp(14, 'untagged'), % o6 - Disp = hipe_sparc:mk_simm13(100), - [hipe_sparc:mk_store('stw', Src, CSP, Disp), - hipe_sparc:mk_pseudo_fload(CSP, Disp, Dst, true), + Offset = 100, + mk_store('stw', Src, CSP, Offset) ++ + [hipe_sparc:mk_pseudo_fload(CSP, hipe_sparc:mk_simm13(Offset), Dst, true), hipe_sparc:mk_fp_unary('fitod', Dst, Dst)]. conv_fmove(I, Map, Data) -> diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index cf1976d8d6..4cf09830cb 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.11.1 +HIPE_VSN = 3.11.2 diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl index d77e4fed3b..36da2f4d44 100644 --- a/lib/hipe/x86/hipe_rtl_to_x86.erl +++ b/lib/hipe/x86/hipe_rtl_to_x86.erl @@ -236,7 +236,7 @@ conv_insn(I, Map, Data) -> #fconv{} -> {Dst, Map0} = conv_dst(hipe_rtl:fconv_dst(I), Map), {[], Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0), - I2 = [hipe_x86:mk_fmove(Src, Dst)], + I2 = conv_fconv(Dst, Src), {I2, Map1, Data}; X -> %% gctest?? @@ -712,6 +712,19 @@ vmap_lookup(Map, Key) -> vmap_bind(Map, Key, Val) -> gb_trees:insert(Key, Val, Map). +%%% Finalise the conversion of an Integer-to-Float operation. + +conv_fconv(Dst, Src) -> + case hipe_x86:is_imm(Src) of + false -> + [hipe_x86:mk_fmove(Src, Dst)]; + true -> + %% cvtsi2sd does not allow src to be an immediate + Tmp = new_untagged_temp(), + [hipe_x86:mk_move(Src, Tmp), + hipe_x86:mk_fmove(Tmp, Dst)] + end. + %%% Finalise the conversion of a 2-address FP operation. conv_fp_unary(Dst, Src, FpUnOp) -> diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml index e64c375bba..acbd79b201 100644 --- a/lib/inets/doc/src/http_uri.xml +++ b/lib/inets/doc/src/http_uri.xml @@ -63,6 +63,7 @@ host() = string() port() = pos_integer() path() = string() - Representing a file path or directory path query() = string() +fragment() = string() ]]></code> <marker id="scheme_defaults"></marker> @@ -92,13 +93,16 @@ query() = string() <v>URI = uri() </v> <v>Options = [Option] </v> <v>Option = {ipv6_host_with_brackets, boolean()} | - {scheme_defaults, scheme_defaults()}]</v> - <v>Result = {Scheme, UserInfo, Host, Port, Path, Query}</v> + {scheme_defaults, scheme_defaults()} | + {fragment, boolean()}]</v> + <v>Result = {Scheme, UserInfo, Host, Port, Path, Query} | + {Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v> <v>UserInfo = user_info()</v> <v>Host = host()</v> <v>Port = pos_integer()</v> <v>Path = path()</v> <v>Query = query()</v> + <v>Fragment = fragment()</v> <v>Reason = term() </v> </type> <desc> @@ -111,6 +115,9 @@ query() = string() a scheme not found in the scheme defaults) a port number must be provided or else the parsing will fail. </p> + <p>If the fragment option is true, the URI fragment will be returned as + part of the parsing result, otherwise it is completely ignored.</p> + <marker id="encode"></marker> </desc> </func> diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml index 4ca038cc99..20c8a6b1b1 100644 --- a/lib/inets/doc/src/httpd.xml +++ b/lib/inets/doc/src/httpd.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -249,7 +249,16 @@ <p>Limits the size of the message header of HTTP request. Defaults to 10240. </p> </item> - + + <marker id="prop_max_content_length"></marker> + <tag>{max_content_length, integer()}</tag> + <item> + <p>Maximum Content-Length in an incoming request, in bytes. Requests + with content larger than this are answered with Status 413. + Defaults to 100000000 (100 MB). + </p> + </item> + <marker id="prop_max_uri"></marker> <tag>{max_uri_size, integer()}</tag> <item> diff --git a/lib/inets/doc/src/httpd_conf.xml b/lib/inets/doc/src/httpd_conf.xml index 3ef03966a7..60fc2f135e 100644 --- a/lib/inets/doc/src/httpd_conf.xml +++ b/lib/inets/doc/src/httpd_conf.xml @@ -97,7 +97,7 @@ <v>FilePath = string()</v> <v>Result = {ok,Directory} | {error,Reason}</v> <v>Directory = string()</v> - <v>Reason = string() | enoent | eaccess | enotdir | FileInfo</v> + <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v> <v>FileInfo = File info record</v> </type> <desc> @@ -105,7 +105,7 @@ <p><c>is_directory/1</c> checks if <c>FilePath</c> is a directory in which case it is returned. Please read <c>file(3)</c> for a description of <c>enoent</c>, - <c>eaccess</c> and <c>enotdir</c>. The definition of + <c>eacces</c> and <c>enotdir</c>. The definition of the file info record can be found by including <c>file.hrl</c> from the kernel application, see file(3).</p> @@ -120,14 +120,14 @@ <v>FilePath = string()</v> <v>Result = {ok,File} | {error,Reason}</v> <v>File = string()</v> - <v>Reason = string() | enoent | eaccess | enotdir | FileInfo</v> + <v>Reason = string() | enoent | eacces | enotdir | FileInfo</v> <v>FileInfo = File info record</v> </type> <desc> <marker id="is_file"></marker> <p><c>is_file/1</c> checks if <c>FilePath</c> is a regular file in which case it is returned. Read <c>file(3)</c> for a - description of <c>enoent</c>, <c>eaccess</c> and + description of <c>enoent</c>, <c>eacces</c> and <c>enotdir</c>. The definition of the file info record can be found by including <c>file.hrl</c> from the kernel application, see file(3).</p> diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 921de8e490..7f73aa5e7b 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -32,7 +32,70 @@ <file>notes.xml</file> </header> - <section><title>Inets 5.10.3</title> + <section><title>Inets 5.10.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + mod_alias now handles https-URIs properly</p> + <p> + Consistent view of configuration parameter + keep_alive_timeout, should be presented in the + httpd:info/[1,2] function in the same unit as it is + inputted.</p> + <p> + Own Id: OTP-12436 Aux Id: seq12786 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Gracefully handle invalid content-lenght headers instead + of crashing in list_to_integer.</p> + <p> + Own Id: OTP-12429</p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 5.10.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a spelling mistake in httpc documentation.</p> + <p> + Own Id: OTP-12221</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add option {ftp_extension, boolean} to enable use of + extended commands EPSV and EPRT, as specified in RFC + 2428, for IPv4 instead of using the legacy commands. Ipv6 + can not be supported without the extended commands.</p> + <p> + Own Id: OTP-12255</p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 5.10.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/examples/httpd_load_test/hdlt_slave.erl b/lib/inets/examples/httpd_load_test/hdlt_slave.erl index 52af9b5b90..41361418bc 100644 --- a/lib/inets/examples/httpd_load_test/hdlt_slave.erl +++ b/lib/inets/examples/httpd_load_test/hdlt_slave.erl @@ -180,7 +180,7 @@ ssh_slave_start(Host, ErlCmd) -> ?DEBUG("ssh_exec_erl -> done", []), {ok, Connection, Channel}; Error3 -> - ?LOG("failed exec comand: ~p", [Error3]), + ?LOG("failed exec command: ~p", [Error3]), throw({error, {ssh_exec_failed, Error3}}) end. diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 5674599ac5..8e51b1be5a 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -60,6 +60,7 @@ -define(DATA_ACCEPT_TIMEOUT, infinity). -define(DEFAULT_MODE, passive). -define(PROGRESS_DEFAULT, ignore). +-define(FTP_EXT_DEFAULT, false). %% Internal Constants -define(FTP_PORT, 21). @@ -94,7 +95,8 @@ ipfamily, % inet | inet6 | inet6fb4 progress = ignore, % ignore | pid() dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity - tls_upgrading_data_connection = false + tls_upgrading_data_connection = false, + ftp_extension = ?FTP_EXT_DEFAULT }). @@ -969,6 +971,8 @@ start_options(Options) -> %% timeout %% dtimeout %% progress +%% ftp_extension + open_options(Options) -> ?fcrt("open_options", [{options, Options}]), ValidateMode = @@ -1013,6 +1017,11 @@ open_options(Options) -> (_) -> false end, + ValidateFtpExtension = + fun(true) -> true; + (false) -> true; + (_) -> false + end, ValidOptions = [{mode, ValidateMode, false, ?DEFAULT_MODE}, {host, ValidateHost, true, ehost}, @@ -1020,7 +1029,8 @@ open_options(Options) -> {ipfamily, ValidateIpFamily, false, inet}, {timeout, ValidateTimeout, false, ?CONNECTION_TIMEOUT}, {dtimeout, ValidateDTimeout, false, ?DATA_ACCEPT_TIMEOUT}, - {progress, ValidateProgress, false, ?PROGRESS_DEFAULT}], + {progress, ValidateProgress, false, ?PROGRESS_DEFAULT}, + {ftp_extension, ValidateFtpExtension, false, ?FTP_EXT_DEFAULT}], validate_options(Options, ValidOptions, []). tls_options(Options) -> @@ -1174,12 +1184,14 @@ handle_call({_, {open, ip_comm, Opts}}, From, State) -> DTimeout = key_search(dtimeout, Opts, ?DATA_ACCEPT_TIMEOUT), Progress = key_search(progress, Opts, ignore), IpFamily = key_search(ipfamily, Opts, inet), + FtpExt = key_search(ftp_extension, Opts, ?FTP_EXT_DEFAULT), State2 = State#state{client = From, mode = Mode, progress = progress(Progress), ipfamily = IpFamily, - dtimeout = DTimeout}, + dtimeout = DTimeout, + ftp_extension = FtpExt}, ?fcrd("handle_call(open) -> setup ctrl connection with", [{host, Host}, {port, Port}, {timeout, Timeout}]), @@ -1202,11 +1214,13 @@ handle_call({_, {open, ip_comm, Host, Opts}}, From, State) -> Timeout = key_search(timeout, Opts, ?CONNECTION_TIMEOUT), DTimeout = key_search(dtimeout, Opts, ?DATA_ACCEPT_TIMEOUT), Progress = key_search(progress, Opts, ignore), + FtpExt = key_search(ftp_extension, Opts, ?FTP_EXT_DEFAULT), State2 = State#state{client = From, mode = Mode, progress = progress(Progress), - dtimeout = DTimeout}, + dtimeout = DTimeout, + ftp_extension = FtpExt}, case setup_ctrl_connection(Host, Port, Timeout, State2) of {ok, State3, WaitTimeout} -> @@ -1785,7 +1799,8 @@ handle_ctrl_result({pos_compl, Lines}, ipfamily = inet, client = From, caller = {setup_data_connection, Caller}, - timeout = Timeout} = State) -> + timeout = Timeout, + ftp_extension = false} = State) -> {_, [?LEFT_PAREN | Rest]} = lists:splitwith(fun(?LEFT_PAREN) -> false; (_) -> true end, Lines), @@ -1806,6 +1821,28 @@ handle_ctrl_result({pos_compl, Lines}, {noreply,State#state{client = undefined, caller = undefined}} end; +handle_ctrl_result({pos_compl, Lines}, + #state{mode = passive, + ipfamily = inet, + client = From, + caller = {setup_data_connection, Caller}, + csock = CSock, + timeout = Timeout, + ftp_extension = true} = State) -> + + [_, PortStr | _] = lists:reverse(string:tokens(Lines, "|")), + {ok, {IP, _}} = peername(CSock), + + ?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,PortStr,Caller]), + case connect(IP, list_to_integer(PortStr), Timeout, State) of + {ok, _, Socket} -> + handle_caller(State#state{caller = Caller, dsock = {tcp, Socket}}); + {error, _Reason} = Error -> + gen_server:reply(From, Error), + {noreply, State#state{client = undefined, caller = undefined}} + end; + + %% FTP server does not support passive mode: try to fallback on active mode handle_ctrl_result(_, #state{mode = passive, @@ -2157,7 +2194,8 @@ setup_ctrl_connection(Host, Port, Timeout, State) -> setup_data_connection(#state{mode = active, caller = Caller, - csock = CSock} = State) -> + csock = CSock, + ftp_extension = FtpExt} = State) -> case (catch sockname(CSock)) of {ok, {{_, _, _, _, _, _, _, _} = IP, _}} -> {ok, LSock} = @@ -2174,11 +2212,18 @@ setup_data_connection(#state{mode = active, {ok, LSock} = gen_tcp:listen(0, [{ip, IP}, {active, false}, binary, {packet, 0}]), {ok, Port} = inet:port(LSock), - {IP1, IP2, IP3, IP4} = IP, - {Port1, Port2} = {Port div 256, Port rem 256}, - send_ctrl_message(State, - mk_cmd("PORT ~w,~w,~w,~w,~w,~w", - [IP1, IP2, IP3, IP4, Port1, Port2])), + case FtpExt of + false -> + {IP1, IP2, IP3, IP4} = IP, + {Port1, Port2} = {Port div 256, Port rem 256}, + send_ctrl_message(State, + mk_cmd("PORT ~w,~w,~w,~w,~w,~w", + [IP1, IP2, IP3, IP4, Port1, Port2])); + true -> + IpAddress = inet_parse:ntoa(IP), + Cmd = mk_cmd("EPRT |1|~s|~p|", [IpAddress, Port]), + send_ctrl_message(State, Cmd) + end, activate_ctrl_connection(State), {noreply, State#state{caller = {setup_data_connection, {LSock, Caller}}}} @@ -2191,9 +2236,17 @@ setup_data_connection(#state{mode = passive, ipfamily = inet6, {noreply, State#state{caller = {setup_data_connection, Caller}}}; setup_data_connection(#state{mode = passive, ipfamily = inet, - caller = Caller} = State) -> + caller = Caller, + ftp_extension = false} = State) -> send_ctrl_message(State, mk_cmd("PASV", [])), activate_ctrl_connection(State), + {noreply, State#state{caller = {setup_data_connection, Caller}}}; + +setup_data_connection(#state{mode = passive, ipfamily = inet, + caller = Caller, + ftp_extension = true} = State) -> + send_ctrl_message(State, mk_cmd("EPSV", [])), + activate_ctrl_connection(State), {noreply, State#state{caller = {setup_data_connection, Caller}}}. connect(Host, Port, Timeout, #state{ipfamily = inet = IpFam}) -> diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl index 134115bdfa..ed306a84f5 100644 --- a/lib/inets/src/http_client/httpc_cookie.erl +++ b/lib/inets/src/http_client/httpc_cookie.erl @@ -334,9 +334,23 @@ add_domain(Str, #http_cookie{domain_default = true}) -> add_domain(Str, #http_cookie{domain = Domain}) -> Str ++ "; $Domain=" ++ Domain. +is_set_cookie_valid("") -> + %% an empty Set-Cookie header is not valid + false; +is_set_cookie_valid([$=|_]) -> + %% a Set-Cookie header without name is not valid + false; +is_set_cookie_valid(SetCookieHeader) -> + %% a Set-Cookie header without name/value is not valid + case string:chr(SetCookieHeader, $=) of + 0 -> false; + _ -> true + end. + parse_set_cookies(CookieHeaders, DefaultPathDomain) -> - %% empty Set-Cookie header is invalid according to RFC but some sites violate it - SetCookieHeaders = [Value || {"set-cookie", Value} <- CookieHeaders, Value /= ""], + %% filter invalid Set-Cookie headers + SetCookieHeaders = [Value || {"set-cookie", Value} <- CookieHeaders, + is_set_cookie_valid(Value)], Cookies = [parse_set_cookie(SetCookieHeader, DefaultPathDomain) || SetCookieHeader <- SetCookieHeaders], %% print_cookies("Parsed Cookies", Cookies), @@ -348,6 +362,8 @@ parse_set_cookie(CookieHeader, {DefaultPath, DefaultDomain}) -> Name = string:substr(CookieHeader, 1, Pos - 1), {Value, Attrs} = case string:substr(CookieHeader, Pos + 1) of + [] -> + {"", ""}; [$;|ValueAndAttrs] -> {"", string:tokens(ValueAndAttrs, ";")}; ValueAndAttrs -> diff --git a/lib/inets/src/http_lib/http_internal.hrl b/lib/inets/src/http_lib/http_internal.hrl index 53b776c4e7..54425740b5 100644 --- a/lib/inets/src/http_lib/http_internal.hrl +++ b/lib/inets/src/http_lib/http_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2014. All Rights Reserved. +%% Copyright Ericsson AB 2002-2015. 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 @@ -28,6 +28,7 @@ -define(HTTP_MAX_URI_SIZE, nolimit). -define(HTTP_MAX_VERSION_STRING, 8). -define(HTTP_MAX_METHOD_STRING, 20). +-define(HTTP_MAX_CONTENT_LENGTH, 100000000). -ifndef(HTTP_DEFAULT_SSL_KIND). -define(HTTP_DEFAULT_SSL_KIND, essl). diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl index f295453bdd..a0833ddf01 100644 --- a/lib/inets/src/http_lib/http_request.erl +++ b/lib/inets/src/http_lib/http_request.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2014. All Rights Reserved. +%% Copyright Ericsson AB 2005-2015. 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 @@ -21,8 +21,16 @@ -include("http_internal.hrl"). --export([headers/2, http_headers/1, is_absolut_uri/1]). +-export([headers/2, http_headers/1, is_absolut_uri/1, key_value/1]). + +key_value(KeyValueStr) -> + case lists:splitwith(fun($:) -> false; (_) -> true end, KeyValueStr) of + {Key, [$: | Value]} -> + {http_util:to_lower(string:strip(Key)), string:strip(Value)}; + {_, []} -> + undefined + end. %%------------------------------------------------------------------------- %% headers(HeaderList, #http_request_h{}) -> #http_request_h{} %% HeaderList - ["HeaderField:Value"] @@ -34,14 +42,12 @@ %%------------------------------------------------------------------------- headers([], Headers) -> Headers; -headers([Header | Tail], Headers) -> - case lists:splitwith(fun($:) -> false; (_) -> true end, Header) of - {Key, [$: | Value]} -> - headers(Tail, headers(http_util:to_lower(string:strip(Key)), - string:strip(Value), Headers)); - {_, []} -> - headers(Tail, Headers) - end. +headers([{Key, Value} | Tail], Headers) -> + headers(Tail, headers(Key, Value, Headers)); +headers([undefined], Headers) -> + Headers; +headers(KeyValues, Headers) -> + headers([key_value(KeyValue) || KeyValue <- KeyValues], Headers). %%------------------------------------------------------------------------- %% headers(#http_request_h{}) -> HeaderList diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 5962001c3a..350a4bc169 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -90,8 +90,8 @@ parse(AbsURI, Opts) -> {error, Reason}; {Scheme, DefaultPort, Rest} -> case (catch parse_uri_rest(Scheme, DefaultPort, Rest, Opts)) of - {ok, {UserInfo, Host, Port, Path, Query}} -> - {ok, {Scheme, UserInfo, Host, Port, Path, Query}}; + {ok, Result} -> + {ok, Result}; {error, Reason} -> {error, {Reason, Scheme, AbsURI}}; _ -> @@ -148,27 +148,22 @@ parse_scheme(AbsURI, Opts) -> end. parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) -> - {Authority, PathQuery} = - case split_uri(URIPart, "/", URIPart, 1, 0) of - Split = {_, _} -> - Split; - URIPart -> - case split_uri(URIPart, "\\?", URIPart, 1, 0) of - Split = {_, _} -> - Split; - URIPart -> - {URIPart,""} - end - end, + {Authority, PathQueryFragment} = + split_uri(URIPart, "[/?#]", {URIPart, ""}, 1, 0), + {RawPath, QueryFragment} = + split_uri(PathQueryFragment, "[?#]", {PathQueryFragment, ""}, 1, 0), + {Query, Fragment} = + split_uri(QueryFragment, "#", {QueryFragment, ""}, 1, 0), {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1), {Host, Port} = parse_host_port(Scheme, DefaultPort, HostPort, Opts), - {Path, Query} = parse_path_query(PathQuery), - {ok, {UserInfo, Host, Port, Path, Query}}. - + Path = path(RawPath), + case lists:keyfind(fragment, 1, Opts) of + {fragment, true} -> + {ok, {Scheme, UserInfo, Host, Port, Path, Query, Fragment}}; + _ -> + {ok, {Scheme, UserInfo, Host, Port, Path, Query}} + end. -parse_path_query(PathQuery) -> - {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0), - {path(Path), Query}. %% In this version of the function, we no longer need %% the Scheme argument, but just in case... diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl index 27446ca7fe..78dda794db 100644 --- a/lib/inets/src/http_server/httpd_conf.erl +++ b/lib/inets/src/http_server/httpd_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -44,7 +44,7 @@ %% FilePath = string() %% Result = {ok,Directory} | {error,Reason} %% Directory = string() -%% Reason = string() | enoent | eaccess | enotdir | FileInfo +%% Reason = string() | enoent | eacces | enotdir | FileInfo %% FileInfo = File info record %% %% Description: Checks if FilePath is a directory in which case it is @@ -71,7 +71,7 @@ is_directory(_Type,_Access,FileInfo,_Directory) -> %% FilePath = string() %% Result = {ok,File} | {error,Reason} %% File = string() -%% Reason = string() | enoent | eaccess | enotdir | FileInfo +%% Reason = string() | enoent | eacces | enotdir | FileInfo %% FileInfo = File info record %% %% Description: Checks if FilePath is a regular file in which case it @@ -205,13 +205,13 @@ load("MaxURISize " ++ MaxHeaderSize, []) -> " is an invalid number of MaxHeaderSize")} end; -load("MaxBodySize " ++ MaxBodySize, []) -> - case make_integer(MaxBodySize) of +load("MaxContentLength " ++ Max, []) -> + case make_integer(Max) of {ok, Integer} -> - {ok, [], {max_body_size,Integer}}; + {ok, [], {max_content_length, Integer}}; {error, _} -> - {error, ?NICE(clean(MaxBodySize) ++ - " is an invalid number of MaxBodySize")} + {error, ?NICE(clean(Max) ++ + " is an invalid number of MaxContentLength")} end; load("ServerName " ++ ServerName, []) -> @@ -337,7 +337,7 @@ load("MaxKeepAliveRequest " ++ MaxRequests, []) -> load("KeepAliveTimeout " ++ Timeout, []) -> case make_integer(Timeout) of {ok, Integer} -> - {ok, [], {keep_alive_timeout, Integer*1000}}; + {ok, [], {keep_alive_timeout, Integer}}; {error, _} -> {error, ?NICE(clean(Timeout)++" is an invalid KeepAliveTimeout")} end; @@ -569,6 +569,12 @@ validate_config_params([{max_body_size, Value} | Rest]) validate_config_params([{max_body_size, Value} | _]) -> throw({max_body_size, Value}); +validate_config_params([{max_content_length, Value} | Rest]) + when is_integer(Value) andalso (Value > 0) -> + validate_config_params(Rest); +validate_config_params([{max_content_length, Value} | _]) -> + throw({max_content_length, Value}); + validate_config_params([{server_name, Value} | Rest]) when is_list(Value) -> validate_config_params(Rest); @@ -635,7 +641,7 @@ validate_config_params([{max_keep_alive_request, Value} | Rest]) when is_integer(Value) andalso (Value > 0) -> validate_config_params(Rest); validate_config_params([{max_keep_alive_request, Value} | _]) -> - throw({max_header_size, Value}); + throw({max_keep_alive_request, Value}); validate_config_params([{keep_alive_timeout, Value} | Rest]) when is_integer(Value) andalso (Value >= 0) -> @@ -799,7 +805,7 @@ store({server_tokens, ServerTokens} = Entry, _ConfigList) -> Server = server(ServerTokens), {ok, [Entry, {server, Server}]}; store({keep_alive_timeout, KeepAliveTimeout}, _ConfigList) -> - {ok, {keep_alive_timeout, KeepAliveTimeout * 1000}}; + {ok, {keep_alive_timeout, KeepAliveTimeout}}; store(ConfigListEntry, _ConfigList) -> {ok, ConfigListEntry}. diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl index 712c73599f..6985065c3e 100644 --- a/lib/inets/src/http_server/httpd_request.erl +++ b/lib/inets/src/http_server/httpd_request.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2014. All Rights Reserved. +%% Copyright Ericsson AB 2005-2015. 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 @@ -118,18 +118,17 @@ validate(Method, Uri, Version) -> %% create it. %% ---------------------------------------------------------------------- update_mod_data(ModData, Method, RequestURI, HTTPVersion, Headers)-> - ParsedHeaders = tagup_header(Headers), - PersistentConn = get_persistens(HTTPVersion, ParsedHeaders, + PersistentConn = get_persistens(HTTPVersion, Headers, ModData#mod.config_db), {ok, ModData#mod{data = [], method = Method, absolute_uri = format_absolute_uri(RequestURI, - ParsedHeaders), + Headers), request_uri = format_request_uri(RequestURI), http_version = HTTPVersion, request_line = Method ++ " " ++ RequestURI ++ " " ++ HTTPVersion, - parsed_header = ParsedHeaders, + parsed_header = Headers, connection = PersistentConn}}. %%%======================================================================== @@ -146,14 +145,14 @@ parse_method(_, _, _, Max, _, _) -> %% We do not know the version of the client as it comes after the %% method send the lowest version in the response so that the client %% will be able to handle it. - {error, {too_long, Max, 413, "Method unreasonably long"}, lowest_version()}. + {error, {size_error, Max, 413, "Method unreasonably long"}, lowest_version()}. parse_uri(_, _, Current, MaxURI, _, _) when (Current > MaxURI) andalso (MaxURI =/= nolimit) -> %% We do not know the version of the client as it comes after the %% uri send the lowest version in the response so that the client %% will be able to handle it. - {error, {too_long, MaxURI, 414, "URI unreasonably long"},lowest_version()}; + {error, {size_error, MaxURI, 414, "URI unreasonably long"},lowest_version()}; parse_uri(<<>>, URI, Current, Max, MaxSizes, Result) -> {?MODULE, parse_uri, [URI, Current, Max, MaxSizes, Result]}; parse_uri(<<?SP, Rest/binary>>, URI, _, _, MaxSizes, Result) -> @@ -179,12 +178,12 @@ parse_version(<<?CR>> = Data, Version, Current, Max, MaxSizes, Result) -> parse_version(<<Octet, Rest/binary>>, Version, Current, Max, MaxSizes, Result) when Current =< Max -> parse_version(Rest, [Octet | Version], Current + 1, Max, MaxSizes, Result); parse_version(_, _, _, Max,_,_) -> - {error, {too_long, Max, 413, "Version string unreasonably long"}, lowest_version()}. + {error, {size_error, Max, 413, "Version string unreasonably long"}, lowest_version()}. parse_headers(_, _, _, Current, Max, _, Result) when Max =/= nolimit andalso Current > Max -> HttpVersion = lists:nth(3, lists:reverse(Result)), - {error, {too_long, Max, 413, "Headers unreasonably long"}, HttpVersion}; + {error, {size_error, Max, 413, "Headers unreasonably long"}, HttpVersion}; parse_headers(<<>>, Header, Headers, Current, Max, MaxSizes, Result) -> {?MODULE, parse_headers, [<<>>, Header, Headers, Current, Max, @@ -204,14 +203,22 @@ parse_headers(<<?CR,?LF,?CR,?LF,Body/binary>>, [], [], _, _, _, Result) -> Result])), {ok, NewResult}; parse_headers(<<?CR,?LF,?CR,?LF,Body/binary>>, Header, Headers, _, _, - _, Result) -> - HTTPHeaders = [lists:reverse(Header) | Headers], - RequestHeaderRcord = - http_request:headers(HTTPHeaders, #http_request_h{}), - NewResult = - list_to_tuple(lists:reverse([Body, {RequestHeaderRcord, - HTTPHeaders} | Result])), - {ok, NewResult}; + MaxSizes, Result) -> + case http_request:key_value(lists:reverse(Header)) of + undefined -> %% Skip headers with missing : + {ok, list_to_tuple(lists:reverse([Body, {http_request:headers(Headers, #http_request_h{}), Headers} | Result]))}; + NewHeader -> + case check_header(NewHeader, MaxSizes) of + ok -> + {ok, list_to_tuple(lists:reverse([Body, {http_request:headers([NewHeader | Headers], + #http_request_h{}), + [NewHeader | Headers]} | Result]))}; + + {error, Reason} -> + HttpVersion = lists:nth(3, lists:reverse(Result)), + {error, Reason, HttpVersion} + end + end; parse_headers(<<?CR,?LF,?CR>> = Data, Header, Headers, Current, Max, MaxSizes, Result) -> @@ -243,8 +250,21 @@ parse_headers(<<?LF, Octet, Rest/binary>>, Header, Headers, Current, Max, MaxSizes, Result); parse_headers(<<?CR,?LF, Octet, Rest/binary>>, Header, Headers, _, Max, MaxSizes, Result) -> - parse_headers(Rest, [Octet], [lists:reverse(Header) | Headers], - 0, Max, MaxSizes, Result); + case http_request:key_value(lists:reverse(Header)) of + undefined -> %% Skip headers with missing : + parse_headers(Rest, [Octet], Headers, + 0, Max, MaxSizes, Result); + NewHeader -> + case check_header(NewHeader, MaxSizes) of + ok -> + parse_headers(Rest, [Octet], [NewHeader | Headers], + 0, Max, MaxSizes, Result); + {error, Reason} -> + HttpVersion = lists:nth(3, lists:reverse(Result)), + {error, Reason, HttpVersion} + end + end; + parse_headers(<<?CR>> = Data, Header, Headers, Current, Max, MaxSizes, Result) -> {?MODULE, parse_headers, [Data, Header, Headers, Current, Max, @@ -388,29 +408,25 @@ get_persistens(HTTPVersion,ParsedHeader,ConfigDB)-> false end. - -%%---------------------------------------------------------------------- -%% tagup_header -%% -%% Parses the header of a HTTP request and returns a key,value tuple -%% list containing Name and Value of each header directive as of: -%% -%% Content-Type: multipart/mixed -> {"Content-Type", "multipart/mixed"} -%% -%% But in http/1.1 the field-names are case insencitive so now it must be -%% Content-Type: multipart/mixed -> {"content-type", "multipart/mixed"} -%% The standard furthermore says that leading and traling white space -%% is not a part of the fieldvalue and shall therefore be removed. -%%---------------------------------------------------------------------- -tagup_header([]) -> []; -tagup_header([Line|Rest]) -> [tag(Line, [])|tagup_header(Rest)]. - -tag([], Tag) -> - {http_util:to_lower(lists:reverse(Tag)), ""}; -tag([$:|Rest], Tag) -> - {http_util:to_lower(lists:reverse(Tag)), string:strip(Rest)}; -tag([Chr|Rest], Tag) -> - tag(Rest, [Chr|Tag]). - lowest_version()-> "HTTP/0.9". + +check_header({"content-length", Value}, Maxsizes) -> + Max = proplists:get_value(max_content_length, Maxsizes), + MaxLen = length(integer_to_list(Max)), + case length(Value) =< MaxLen of + true -> + try + _ = list_to_integer(Value), + ok + catch _:_ -> + {error, {size_error, Max, 411, "content-length not an integer"}} + end; + false -> + {error, {size_error, Max, 413, "content-length unreasonably long"}} + end; +check_header(_, _) -> + ok. + + + diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index 9bea58cc9e..f7a9fe5d49 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -96,8 +96,9 @@ init([Manager, ConfigDB, AcceptTimeout]) -> proc_lib:init_ack({ok, self()}), {SocketType, Socket} = await_socket_ownership_transfer(AcceptTimeout), - - KeepAliveTimeOut = httpd_util:lookup(ConfigDB, keep_alive_timeout, 150000), + + %%Timeout value is in seconds we want it in milliseconds + KeepAliveTimeOut = 1000 * httpd_util:lookup(ConfigDB, keep_alive_timeout, 150), case http_transport:negotiate(SocketType, Socket, ?HANDSHAKE_TIMEOUT) of {error, _Error} -> @@ -119,11 +120,15 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> MaxHeaderSize = max_header_size(ConfigDB), MaxURISize = max_uri_size(ConfigDB), NrOfRequest = max_keep_alive_request(ConfigDB), - + MaxContentLen = max_content_length(ConfigDB), + {_, Status} = httpd_manager:new_connection(Manager), MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize}, - {max_version, ?HTTP_MAX_VERSION_STRING}, {max_method, ?HTTP_MAX_METHOD_STRING}]]}, + {max_version, ?HTTP_MAX_VERSION_STRING}, + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, MaxContentLen} + ]]}, State = #state{mod = Mod, manager = Manager, @@ -207,7 +212,7 @@ handle_info({Proto, Socket, Data}, set_new_data_size(cancel_request_timeout(State), NewDataSize) end, handle_http_msg(Result, NewState); - {error, {too_long, MaxSize, ErrCode, ErrStr}, Version} -> + {error, {size_error, MaxSize, ErrCode, ErrStr}, Version} -> NewModData = ModData#mod{http_version = Version}, httpd_response:send_status(NewModData, ErrCode, ErrStr), Reason = io_lib:format("~p: ~p max size is ~p~n", @@ -444,8 +449,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, error_log(Reason, ModData), {stop, normal, State#state{response_sent = true}}; _ -> - Length = - list_to_integer(Headers#http_request_h.'content-length'), + Length = list_to_integer(Headers#http_request_h.'content-length'), case ((Length =< MaxBodySize) or (MaxBodySize == nolimit)) of true -> case httpd_request:whole_body(Body, Length) of @@ -454,7 +458,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, ModData#mod.socket, [{active, once}]), {noreply, State#state{mfa = - {Module, Function, Args}}}; + {Module, Function, Args}}}; {ok, NewBody} -> handle_response( @@ -471,7 +475,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State, handle_expect(#state{headers = Headers, mod = #mod{config_db = ConfigDB} = ModData} = State, MaxBodySize) -> - Length = Headers#http_request_h.'content-length', + Length = list_to_integer(Headers#http_request_h.'content-length'), case expect(Headers, ModData#mod.http_version, ConfigDB) of continue when (MaxBodySize > Length) orelse (MaxBodySize =:= nolimit) -> httpd_response:send_status(ModData, 100, ""), @@ -545,9 +549,13 @@ handle_next_request(#state{mod = #mod{connection = true} = ModData, init_data = ModData#mod.init_data}, MaxHeaderSize = max_header_size(ModData#mod.config_db), MaxURISize = max_uri_size(ModData#mod.config_db), + MaxContentLen = max_content_length(ModData#mod.config_db), MFA = {httpd_request, parse, [[{max_uri, MaxURISize}, {max_header, MaxHeaderSize}, - {max_version, ?HTTP_MAX_VERSION_STRING}, {max_method, ?HTTP_MAX_METHOD_STRING}]]}, + {max_version, ?HTTP_MAX_VERSION_STRING}, + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, MaxContentLen} + ]]}, TmpState = State#state{mod = NewModData, mfa = MFA, max_keep_alive_request = decrease(Max), @@ -630,3 +638,5 @@ max_body_size(ConfigDB) -> max_keep_alive_request(ConfigDB) -> httpd_util:lookup(ConfigDB, max_keep_alive_request, infinity). +max_content_length(ConfigDB) -> + httpd_util:lookup(ConfigDB, max_content_length, ?HTTP_MAX_CONTENT_LENGTH). diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl index 0b9fe4cfe0..5039cd56b5 100644 --- a/lib/inets/src/http_server/mod_alias.erl +++ b/lib/inets/src/http_server/mod_alias.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -55,6 +55,7 @@ do(#mod{data = Data} = Info) -> do_alias(#mod{config_db = ConfigDB, request_uri = ReqURI, + socket_type = SocketType, data = Data}) -> {ShortPath, Path, AfterPath} = real_name(ConfigDB, ReqURI, which_alias(ConfigDB)), @@ -70,8 +71,9 @@ do_alias(#mod{config_db = ConfigDB, (LastChar =/= $/)) -> ?hdrt("directory and last-char is a /", []), ServerName = which_server_name(ConfigDB), - Port = port_string( which_port(ConfigDB) ), - URL = "http://" ++ ServerName ++ Port ++ ReqURI ++ "/", + Port = port_string(which_port(ConfigDB)), + Protocol = get_protocol(SocketType), + URL = Protocol ++ ServerName ++ Port ++ ReqURI ++ "/", ReasonPhrase = httpd_util:reason_phrase(301), Message = httpd_util:message(301, URL, ConfigDB), {proceed, @@ -94,6 +96,12 @@ port_string(80) -> port_string(Port) -> ":" ++ integer_to_list(Port). +get_protocol(ip_comm) -> + "http://"; +get_protocol(_) -> + %% Should clean up to have only one ssl type essl vs ssl is not relevant any more + "https://". + %% real_name real_name(ConfigDB, RequestURI, []) -> diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 4bc49e1e67..90524ac367 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -17,44 +17,9 @@ %% %CopyrightEnd% {"%VSN%", [ - {"5.10.2", - [ - {load_module, httpd_request_handler, soft_purge, soft_purge, - []}]}, - {"5.10.1", - [{load_module, httpc_handler, soft_purge, soft_purge, []}, - {load_module, httpd, soft_purge, soft_purge, []}, - {load_module, httpd_manager, soft_purge, soft_purge, []}, - {load_module, httpd_request, soft_purge, soft_purge, []}, - {load_module, httpd_request_handler, soft_purge, soft_purge, - []}]}, - {"5.10", - [{load_module, httpc_handler, soft_purge, soft_purge, []}, - {load_module, httpd, soft_purge, soft_purge, []}, - {load_module, httpd_manager, soft_purge, soft_purge, []}, - {load_module, httpd_request, soft_purge, soft_purge, []}, - {load_module, httpd_request_handler, soft_purge, soft_purge, - []}]}, {<<"5\\..*">>,[{restart_application, inets}]} ], [ - {"5.10.2", - [ - {load_module, httpd_request_handler, soft_purge, soft_purge, - []}]}, - {"5.10.1", - [{load_module, httpc_handler, soft_purge, soft_purge, []}, - {load_module, httpd, soft_purge, soft_purge, []}, - {load_module, httpd_manager, soft_purge, soft_purge, []}, - {load_module, httpd_request, soft_purge, soft_purge, []}, - {load_module, httpd_request_handler, soft_purge, soft_purge, - []}]}, - {"5.10", - [{load_module, httpc_handler, soft_purge, soft_purge, []}, - {load_module, httpd, soft_purge, soft_purge, []}, - {load_module, httpd_manager, soft_purge, soft_purge, []}, - {load_module, httpd_request, soft_purge, soft_purge, []}, - {load_module, httpd_request_handler, soft_purge, soft_purge, []}]}, {<<"5\\..*">>,[{restart_application, inets}]} ] }. diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl index d4a3f28f38..5952e9fd6e 100644 --- a/lib/inets/test/http_format_SUITE.erl +++ b/lib/inets/test/http_format_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2014. All Rights Reserved. +%% Copyright Ericsson AB 2004-2015. 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 @@ -355,10 +355,12 @@ http_request(Config) when is_list(Config) -> "http://www.erlang.org", "HTTP/1.1", {#http_request_h{host = "www.erlang.org", te = []}, - ["te: ","host:www.erlang.org"]}, <<>>} = + [{"te", []}, {"host", "www.erlang.org"}]}, <<>>} = parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE}, {max_version, ?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]], + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]], HttpHead), HttpHead1 = ["GET http://www.erlang.org HTTP/1.1" ++ @@ -369,7 +371,9 @@ http_request(Config) when is_list(Config) -> {#http_request_h{}, []}, <<>>} = parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE}, {max_version, ?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]], HttpHead1), + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]], HttpHead1), HttpHead2 = ["GET http://www.erlang.org HTTP/1.1" ++ @@ -380,7 +384,9 @@ http_request(Config) when is_list(Config) -> {#http_request_h{}, []}, <<>>} = parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE}, {max_version, ?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]], HttpHead2), + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]], HttpHead2), %% Note the following body is not related to the headers above HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n", diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index c535d59b9f..21be7862cb 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2014. All Rights Reserved. +%% Copyright Ericsson AB 2004-2015. 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 @@ -91,6 +91,7 @@ only_simulated() -> cookie, cookie_profile, empty_set_cookie, + invalid_set_cookie, trace, stream_once, stream_single_chunk, @@ -568,6 +569,18 @@ empty_set_cookie(Config) when is_list(Config) -> ok = httpc:set_options([{cookies, disabled}]). %%------------------------------------------------------------------------- +invalid_set_cookie(doc) -> + ["Test ignoring invalid Set-Cookie header"]; +invalid_set_cookie(Config) when is_list(Config) -> + ok = httpc:set_options([{cookies, enabled}]), + + URL = url(group_name(Config), "/invalid_set_cookie.html", Config), + {ok, {{_,200,_}, [_|_], [_|_]}} = + httpc:request(get, {URL, []}, [], []), + + ok = httpc:set_options([{cookies, disabled}]). + +%%------------------------------------------------------------------------- headers_as_is(doc) -> ["Test the option headers_as_is"]; headers_as_is(Config) when is_list(Config) -> @@ -1246,8 +1259,9 @@ dummy_server_init(Caller, ip_comm, Inet, _) -> dummy_ipcomm_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE}, {max_header, ?HTTP_MAX_HEADER_SIZE}, {max_version,?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]]}, - [], ListenSocket); + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}]]}, + [], ListenSocket); dummy_server_init(Caller, ssl, Inet, SSLOptions) -> BaseOpts = [binary, {reuseaddr,true}, {active, false} | @@ -1261,7 +1275,9 @@ dummy_ssl_server_init(Caller, BaseOpts, Inet) -> dummy_ssl_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE}, {max_method, ?HTTP_MAX_METHOD_STRING}, {max_version,?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]]}, + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]]}, [], ListenSocket). dummy_ipcomm_server_loop(MFA, Handlers, ListenSocket) -> @@ -1338,16 +1354,20 @@ handle_request(Module, Function, Args, Socket) -> stop -> stop; <<>> -> - {httpd_request, parse, [[<<>>, [{max_uri, ?HTTP_MAX_URI_SIZE}, + {httpd_request, parse, [[{max_uri,?HTTP_MAX_URI_SIZE}, {max_header, ?HTTP_MAX_HEADER_SIZE}, {max_version,?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]]]}; + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]]}; Data -> handle_request(httpd_request, parse, [Data, [{max_uri, ?HTTP_MAX_URI_SIZE}, - {max_header, ?HTTP_MAX_HEADER_SIZE}, - {max_version,?HTTP_MAX_VERSION_STRING}, - {max_method, ?HTTP_MAX_METHOD_STRING}]], Socket) + {max_header, ?HTTP_MAX_HEADER_SIZE}, + {max_version,?HTTP_MAX_VERSION_STRING}, + {max_method, ?HTTP_MAX_METHOD_STRING}, + {max_content_length, ?HTTP_MAX_CONTENT_LENGTH} + ]], Socket) end; NewMFA -> NewMFA @@ -1437,7 +1457,7 @@ dummy_ssl_server_hang_loop(_) -> ensure_host_header_with_port([]) -> false; -ensure_host_header_with_port(["host: " ++ Host| _]) -> +ensure_host_header_with_port([{"host", Host}| _]) -> case string:tokens(Host, [$:]) of [_ActualHost, _Port] -> true; @@ -1449,7 +1469,7 @@ ensure_host_header_with_port([_|T]) -> auth_header([]) -> auth_header_not_found; -auth_header(["authorization:" ++ Value | _]) -> +auth_header([{"authorization", Value} | _]) -> {ok, string:strip(Value)}; auth_header([_ | Tail]) -> auth_header(Tail). @@ -1466,7 +1486,7 @@ handle_auth("Basic " ++ UserInfo, Challange, DefaultResponse) -> check_cookie([]) -> ct:fail(no_cookie_header); -check_cookie(["cookie:" ++ _Value | _]) -> +check_cookie([{"cookie", _} | _]) -> ok; check_cookie([_Head | Tail]) -> check_cookie(Tail). @@ -1686,6 +1706,14 @@ handle_uri(_,"/empty_set_cookie.html",_,_,_,_) -> "Content-Length:32\r\n\r\n"++ "<HTML><BODY>foobar</BODY></HTML>"; +handle_uri(_,"/invalid_set_cookie.html",_,_,_,_) -> + "HTTP/1.1 200 ok\r\n" ++ + "set-cookie: =\r\n" ++ + "set-cookie: name=\r\n" ++ + "set-cookie: name-or-value\r\n" ++ + "Content-Length:32\r\n\r\n"++ + "<HTML><BODY>foobar</BODY></HTML>"; + handle_uri(_,"/missing_crlf.html",_,_,_,_) -> "HTTP/1.1 200 ok" ++ "Content-Length:32\r\n" ++ diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index 4010597657..342004f19b 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2015. 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 @@ -132,6 +132,7 @@ http_get() -> bad_hex, missing_CR, max_header, + max_content_length, ipv6 ]. @@ -979,13 +980,22 @@ max_header(Config) when is_list(Config) -> Host = ?config(host, Config), case Version of "HTTP/0.9" -> - {skip, no_implemented}; + {skip, not_implemented}; _ -> dos_hostname(?config(type, Config), ?config(port, Config), Host, ?config(node, Config), Version, ?MAX_HEADER_SIZE) end. %%------------------------------------------------------------------------- +max_content_length() -> + ["Denial Of Service (DOS) attack, prevented by max_content_length"]. +max_content_length(Config) when is_list(Config) -> + Version = ?config(http_version, Config), + Host = ?config(host, Config), + garbage_content_length(?config(type, Config), ?config(port, Config), Host, + ?config(node, Config), Version). + +%%------------------------------------------------------------------------- security_1_1(Config) when is_list(Config) -> security([{http_version, "HTTP/1.1"} | Config]). @@ -1368,7 +1378,9 @@ server_config(http_reload, Config) -> server_config(https_reload, Config) -> [{keep_alive_timeout, 2}] ++ server_config(https, Config); server_config(http_limit, Config) -> - [{max_clients, 1}] ++ server_config(http, Config); + [{max_clients, 1}, + %% Make sure option checking code is run + {max_content_length, 100000002}] ++ server_config(http, Config); server_config(https_limit, Config) -> [{max_clients, 1}] ++ server_config(https, Config); server_config(http_basic_auth, Config) -> @@ -1814,7 +1826,7 @@ dos_hostname(Type, Port, Host, Node, Version, Max) -> ok = httpd_test_lib:verify_request(Type, Host, Port, Node, dos_hostname_request(TooLongHeader, Version), - [{statuscode, dos_code(Version)}, + [{statuscode, request_entity_too_large_code(Version)}, {version, Version}]). dos_hostname_request(Host, Version) -> dos_http_request("GET / ", Version, Host). @@ -1824,11 +1836,32 @@ dos_http_request(Request, "HTTP/1.1" = Version, Host) -> dos_http_request(Request, Version, Host) -> Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n\r\n". -dos_code("HTTP/1.0") -> +request_entity_too_large_code("HTTP/1.0") -> 403; %% 413 not defined in HTTP/1.0 -dos_code(_) -> +request_entity_too_large_code(_) -> 413. +length_required_code("HTTP/1.0") -> + 403; %% 411 not defined in HTTP/1.0 +length_required_code(_) -> + 411. + +garbage_content_length(Type, Port, Host, Node, Version) -> + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + garbage_content_length_request("GET / ", Version, Host, "aaaa"), + [{statuscode, length_required_code(Version)}, + {version, Version}]), + ok = httpd_test_lib:verify_request(Type, Host, Port, Node, + garbage_content_length_request("GET / ", Version, Host, + lists:duplicate($a, 100)), + [{statuscode, request_entity_too_large_code(Version)}, + {version, Version}]). + +garbage_content_length_request(Request, Version, Host, Garbage) -> + http_request(Request, Version, Host, + {"content-length:" ++ Garbage, "Body with garbage content length indicator"}). + + update_password(Node, ServerRoot, _Address, Port, AuthPrefix, Dir, Old, New)-> Directory = filename:join([ServerRoot, "htdocs", AuthPrefix ++ Dir]), rpc:call(Node, mod_auth, update_password, diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl index 9ba09e1474..f75e347d0c 100644 --- a/lib/inets/test/uri_SUITE.erl +++ b/lib/inets/test/uri_SUITE.erl @@ -46,6 +46,7 @@ all() -> userinfo, scheme, queries, + fragments, escaped, hexed_query ]. @@ -105,6 +106,42 @@ queries(Config) when is_list(Config) -> {ok, {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"}} = http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42"). +fragments(Config) when is_list(Config) -> + {ok, {http,[],"localhost",80,"/",""}} = + http_uri:parse("http://localhost#fragment"), + {ok, {http,[],"localhost",80,"/path",""}} = + http_uri:parse("http://localhost/path#fragment"), + {ok, {http,[],"localhost",80,"/","?query"}} = + http_uri:parse("http://localhost?query#fragment"), + {ok, {http,[],"localhost",80,"/path","?query"}} = + http_uri:parse("http://localhost/path?query#fragment"), + {ok, {http,[],"localhost",80,"/","","#fragment"}} = + http_uri:parse("http://localhost#fragment", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","","#fragment"}} = + http_uri:parse("http://localhost/path#fragment", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/","?query","#fragment"}} = + http_uri:parse("http://localhost?query#fragment", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","?query","#fragment"}} = + http_uri:parse("http://localhost/path?query#fragment", + [{fragment,true}]), + {ok, {http,[],"localhost",80,"/","",""}} = + http_uri:parse("http://localhost", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","",""}} = + http_uri:parse("http://localhost/path", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/","?query",""}} = + http_uri:parse("http://localhost?query", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","?query",""}} = + http_uri:parse("http://localhost/path?query", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/","","#"}} = + http_uri:parse("http://localhost#", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","","#"}} = + http_uri:parse("http://localhost/path#", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/","?query","#"}} = + http_uri:parse("http://localhost?query#", [{fragment,true}]), + {ok, {http,[],"localhost",80,"/path","?query","#"}} = + http_uri:parse("http://localhost/path?query#", [{fragment,true}]), + ok. + escaped(Config) when is_list(Config) -> {ok, {http,[],"www.somedomain.com",80,"/%2Eabc",[]}} = http_uri:parse("http://www.somedomain.com/%2Eabc"), diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 029f6ac4d2..7d11916454 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 5.10.3 +INETS_VSN = 5.10.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index 46d89f0cdb..fc5f8be53e 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -30,6 +30,40 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> +<section><title>Jinterface 1.5.12</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + handle empty .erlang.cookie without crashing and + OtpErlangList.clone must not return null</p> + <p> + Own Id: OTP-12210</p> + </item> + <item> + <p> + This fixes all the compilation warnings in the Java code</p> + <p> + Own Id: OTP-12211</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added an .appup file for the application.</p> + <p> + Own Id: OTP-12358 Aux Id: OTP-12178 </p> + </item> + </list> + </section> + +</section> + <section><title>Jinterface 1.5.11</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile index fd923f85ae..ea3ab770ce 100644 --- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile @@ -37,10 +37,13 @@ VSN=$(JINTERFACE_VSN) EBINDIR=$(ERL_TOP)/lib/jinterface/ebin APP_FILE= jinterface.app - APP_SRC= $(APP_FILE).src APP_TARGET= $(EBINDIR)/$(APP_FILE) +APPUP_FILE= jinterface.appup +APPUP_SRC= $(APPUP_FILE).src +APPUP_TARGET= $(EBINDIR)/$(APPUP_FILE) + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- @@ -54,7 +57,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/jinterface-$(VSN) # all java sourcefiles listed in common include file include $(ERL_TOP)/lib/jinterface/java_src/$(JAVA_CLASS_SUBDIR)/java_files -TARGET_FILES= $(JAVA_FILES:%=$(JAVA_DEST_ROOT)$(JAVA_CLASS_SUBDIR)%.class) $(APP_TARGET) +TARGET_FILES= $(JAVA_FILES:%=$(JAVA_DEST_ROOT)$(JAVA_CLASS_SUBDIR)%.class) $(APP_TARGET) $(APPUP_TARGET) JAVA_SRC= $(JAVA_FILES:%=%.java) JARFILE= OtpErlang.jar @@ -90,6 +93,8 @@ endif $(APP_TARGET): $(APP_SRC) $(ERL_TOP)/lib/jinterface/vsn.mk $(vsn_verbose)sed -e 's;%VSN%;$(JINTERFACE_VSN);' $< > $@ +$(APPUP_TARGET): $(APPUP_SRC) $(ERL_TOP)/lib/jinterface/vsn.mk + $(vsn_verbose)sed -e 's;%VSN%;$(JINTERFACE_VSN);' $< > $@ debug opt: make_dirs $(JAVA_DEST_ROOT)$(JARFILE) @@ -120,6 +125,7 @@ release_spec: opt $(V_at)$(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) "$(RELSYSDIR)/priv" $(V_at)$(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(V_at)$(INSTALL_DATA) $(APP_TARGET) "$(RELSYSDIR)/ebin/$(APP_FILE)" + $(V_at)$(INSTALL_DATA) $(APPUP_TARGET) "$(RELSYSDIR)/ebin/$(APPUP_FILE)" release_docs_spec: diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src new file mode 100644 index 0000000000..d267e3d3d5 --- /dev/null +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/jinterface.appup.src @@ -0,0 +1,18 @@ +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2014. 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% +{"%VSN%", [], []}. diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index eea83c2f3f..72ad316333 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.5.11 +JINTERFACE_VSN = 1.5.12 diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml index 1c03efe7fd..dcb9640dcf 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -1283,6 +1283,8 @@ or before unix time epoch which is 1970-01-01 00:00 UTC. Default is <c>{time, local}</c>. </p> + <p>If the <c>raw</c> option is set, the file server will not be called + and only informations about local files will be returned.</p> <note> <p> Since file times is stored in posix time on most OS it is @@ -1509,6 +1511,8 @@ the link will be returned in the <c>file_info</c> record and the <c>type</c> field of the record will be set to <c>symlink</c>.</p> + <p>If the <c>raw</c> option is set, the file server will not be called + and only informations about local files will be returned.</p> <p>If <c><anno>Name</anno></c> is not a symbolic link, this function returns exactly the same result as <c>read_file_info/1</c>. On platforms that do not support symbolic links, this function @@ -1847,6 +1851,8 @@ interpret it as universal time and <c>posix</c> must be seconds since or before unix time epoch which is 1970-01-01 00:00 UTC. Default is <c>{time, local}</c>. + <p>If the <c>raw</c> option is set, the file server will not be called + and only informations about local files will be returned.</p> </p> <p>The following fields are used from the record, if they are given.</p> diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index dc9e4766a9..ee8cd441d4 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -961,7 +961,7 @@ <pre> #sctp_paddrinfo{ assoc_id = assoc_id(), address = {IP, Port}, - state = inactive | active, + state = inactive | active | unconfirmed, cwnd = integer(), srtt = integer(), rto = integer(), diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 50e1cc290c..77a8caaaf6 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -138,7 +138,7 @@ fe80::204:acff:fe17:bf38 <name name="get_rc" arity="0"/> <fsummary>Return a list of IP configuration parameters</fsummary> <desc> - <p>Returns the state of the Inet configuration database in + <p>Returns the state of the Inet configuration database in form of a list of recorded configuration parameters. (See the ERTS User's Guide, Inet configuration, for more information). Only parameters with other than default values are returned.</p> @@ -258,8 +258,8 @@ fe80::204:acff:fe17:bf38 <type name="socket_getopt"/> <type name="socket_setopt"/> <desc> - <p>Gets one or more options for a socket. - See <seealso marker="#setopts/2">setopts/2</seealso> + <p>Gets one or more options for a socket. + See <seealso marker="#setopts/2">setopts/2</seealso> for a list of available options.</p> <p>The number of elements in the returned <c><anno>OptionValues</anno></c> list does not necessarily correspond to the number of options @@ -278,14 +278,14 @@ fe80::204:acff:fe17:bf38 by the protocol level, the option number and either a binary or the size, in bytes, of the buffer in which the option value is to be stored. A binary - should be used when the underlying <c>getsockopt</c> requires + should be used when the underlying <c>getsockopt</c> requires <em>input</em> in the argument field, in which case the size of the binary should correspond to the required buffer size of the return value. The supplied values in a <c>RawOptReq</c> correspond to the second, third and fourth/fifth parameters to the <c>getsockopt</c> call in the C socket API. The value stored - in the buffer is returned as a binary <c>ValueBin</c> + in the buffer is returned as a binary <c>ValueBin</c> where all values are coded in the native endianess.</p> <p>Asking for and inspecting raw socket options require low level information about the current operating system and TCP @@ -306,7 +306,7 @@ fe80::204:acff:fe17:bf38 value to be a 32 bit integer. We could use the following code to retrieve the value:</p> <code type="none"><![CDATA[ - get_tcpi_sacked(Sock) -> + get_tcpi_sacked(Sock) -> {ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]), <<_:28/binary,TcpiSacked:32/native,_/binary>> = Info, TcpiSacked.]]></code> @@ -332,23 +332,23 @@ fe80::204:acff:fe17:bf38 <taglist> <tag><c>recv_avg</c></tag> <item> - <p>Average size of packets in bytes received to the socket.</p> + <p>Average size of packets in bytes received by the socket.</p> </item> <tag><c>recv_cnt</c></tag> <item> - <p>Number of packets received to the socket.</p> + <p>Number of packets received by the socket.</p> </item> <tag><c>recv_dvi</c></tag> <item> - <p>Average packet size deviation in bytes received to the socket.</p> + <p>Average packet size deviation in bytes received by the socket.</p> </item> <tag><c>recv_max</c></tag> <item> - <p>The size of the largest packet in bytes received to the socket.</p> + <p>The size of the largest packet in bytes received by the socket.</p> </item> <tag><c>recv_oct</c></tag> <item> - <p>Number of bytes received to the socket.</p> + <p>Number of bytes received by the socket.</p> </item> <tag><c>send_avg</c></tag> @@ -408,7 +408,7 @@ fe80::204:acff:fe17:bf38 <name name="parse_ipv6strict_address" arity="1" /> <fsummary>Parse an IPv6 address strict.</fsummary> <desc> - <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>. + <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>. Does <b>not</b> accept IPv4 adresses.</p> </desc> </func> @@ -613,15 +613,20 @@ fe80::204:acff:fe17:bf38 <marker id="option-buffer"></marker> </item> - <tag><c>{buffer, Size}</c></tag> + <tag><c>{buffer, Size}</c></tag> <item> - <p>Determines the size of the user-level software buffer used by - the driver. Not to be confused with <c>sndbuf</c> - and <c>recbuf</c> options which correspond to - the kernel socket buffers. It is recommended - to have <c>val(buffer) >= max(val(sndbuf),val(recbuf))</c>. - In fact, the <c>val(buffer)</c> is automatically set to - the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p> + <p>The size of the user-level software buffer used by + the driver. Not to be confused with <c>sndbuf</c> + and <c>recbuf</c> options which correspond to + the kernel socket buffers. It is recommended + to have <c>val(buffer) >= max(val(sndbuf),val(recbuf))</c> to + avoid performance issues due to unnecessary copying. + In fact, the <c>val(buffer)</c> is automatically set to + the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set. + However, since the actual sizes set for <c>sndbuf</c> and <c>recbuf</c> + usually becomes larger, you are encouraged to use + <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso> + to analyze the behavior of your operating system.</p> </item> <tag><c>{delay_send, Boolean}</c></tag> @@ -998,8 +1003,12 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp </item> <tag><c>{recbuf, Size}</c></tag> <item> - <p>Gives the size of the receive buffer to use for - the socket.</p> + <p>The minimum size of the receive buffer to use for + the socket. You are encouraged to use + <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>, + to retrieve the actual size set by your operating system. + + </p> </item> <tag><c>{reuseaddr, Boolean}</c></tag> <item> @@ -1030,20 +1039,24 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp <tag><c>{sndbuf, Size}</c></tag> <item> - <p>Gives the size of the send buffer to use for the socket.</p> + <p>The minimum size of the send buffer to use for the socket. + You are encouraged to use + <seealso marker="inet#getopts/2"><c>inet:getopts/2</c></seealso>, + to retrieve the actual size set by your operating system. + </p> </item> <tag><c>{priority, Integer}</c></tag> <item> - <p>Sets the SO_PRIORITY socket level option on platforms where - this is implemented. The behaviour and allowed range varies on - different systems. The option is ignored on platforms where the + <p>Sets the SO_PRIORITY socket level option on platforms where + this is implemented. The behaviour and allowed range varies on + different systems. The option is ignored on platforms where the option is not implemented. Use with caution.</p> </item> <tag><c>{tos, Integer}</c></tag> <item> - <p>Sets IP_TOS IP level options on platforms where this is - implemented. The behaviour and allowed range varies on different - systems. The option is ignored on platforms where the option is + <p>Sets IP_TOS IP level options on platforms where this is + implemented. The behaviour and allowed range varies on different + systems. The option is ignored on platforms where the option is not implemented. Use with caution.</p> </item> </taglist> diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 00c6bc33d6..96e3651140 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -4,7 +4,7 @@ <appref> <header> <copyright> - <year>1996</year><year>2014</year> + <year>1996</year><year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -188,6 +188,18 @@ <p>Define the <c>First..Last</c> port range for the listener socket of a distributed Erlang node.</p> </item> + <tag><c>{inet_dist_listen_options, Opts}</c></tag> + <item> + <p>Define a list of extra socket options to be used when opening the + listening socket for a distributed Erlang node. + See <seealso marker="gen_tcp#listen/2">gen_tcp:listen/2</seealso></p> + </item> + <tag><c>{inet_dist_connect_options, Opts}</c></tag> + <item> + <p>Define a list of extra socket options to be used when connecting to + other distributed Erlang nodes. + See <seealso marker="gen_tcp#connect/4">gen_tcp:connect/4</seealso></p> + </item> <tag><c>inet_parse_error_log = silent</c></tag> <item> <p>If this configuration parameter is set, no diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 7eaf2d4a44..1ef106e17a 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,59 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure to install .hrl files when needed</p> + <p> + Own Id: OTP-12197</p> + </item> + <item> + <p> + Removed the undocumented application environment variable + 'raw_files' from the kernel application. This variable + was checked (by call to application:get_env/2) each time + a raw file was to be opened in the file module.</p> + <p> + Own Id: OTP-12276</p> + </item> + <item> + <p> + A bug has been fixed when using the netns option to + gen_udp, which accidentally only worked if it was the + last option.</p> + <p> + Own Id: OTP-12314</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Updated documentation for inet buffer size options.</p> + <p> + Own Id: OTP-12296</p> + </item> + <item> + <p> + Introduce new option 'raw' in file_info and link_info + functions. This option allows the caller not to go + through the file server for information about files + guaranteed to be local.</p> + <p> + Own Id: OTP-12325</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 3.0.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index daad45b6c2..6635885aaf 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1615,7 +1615,6 @@ conv([Key, Val | T]) -> [{make_term(Key), make_term(Val)} | conv(T)]; conv(_) -> []. -%%% Fix some day: eliminate the duplicated code here make_term(Str) -> case erl_scan:string(Str) of {ok, Tokens, _} -> @@ -1623,16 +1622,17 @@ make_term(Str) -> {ok, Term} -> Term; {error, {_,M,Reason}} -> - error_logger:format("application_controller: ~ts: ~ts~n", - [M:format_error(Reason), Str]), - throw({error, {bad_environment_value, Str}}) + handle_make_term_error(M, Reason, Str) end; {error, {_,M,Reason}, _} -> - error_logger:format("application_controller: ~ts: ~ts~n", - [M:format_error(Reason), Str]), - throw({error, {bad_environment_value, Str}}) + handle_make_term_error(M, Reason, Str) end. +handle_make_term_error(Mod, Reason, Str) -> + error_logger:format("application_controller: ~ts: ~ts~n", + [Mod:format_error(Reason), Str]), + throw({error, {bad_environment_value, Str}}). + get_env_i(Name, #state{conf_data = ConfData}) when is_list(ConfData) -> case lists:keyfind(Name, 1, ConfData) of {_Name, Env} -> Env; diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index ee2fb85de2..3d6665a36a 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -114,7 +114,7 @@ -type sendfile_option() :: {chunk_size, non_neg_integer()} | {use_threads, boolean()}. -type file_info_option() :: {'time', 'local'} | {'time', 'universal'} - | {'time', 'posix'}. + | {'time', 'posix'} | raw. %%% BIFs -export([native_name_encoding/0]). @@ -242,7 +242,19 @@ read_file_info(Name) -> Reason :: posix() | badarg. read_file_info(Name, Opts) when is_list(Opts) -> - check_and_call(read_file_info, [file_name(Name), Opts]). + Args = [file_name(Name), Opts], + case check_args(Args) of + ok -> + case lists:member(raw, Opts) of + true -> + [FileName|_] = Args, + ?PRIM_FILE:read_file_info(FileName, Opts); + false -> + call(read_file_info, Args) + end; + Error -> + Error + end. -spec altname(Name :: name_all()) -> any(). @@ -264,7 +276,19 @@ read_link_info(Name) -> Reason :: posix() | badarg. read_link_info(Name, Opts) when is_list(Opts) -> - check_and_call(read_link_info, [file_name(Name),Opts]). + Args = [file_name(Name), Opts], + case check_args(Args) of + ok -> + case lists:member(raw, Opts) of + true -> + [FileName|_] = Args, + ?PRIM_FILE:read_link_info(FileName, Opts); + false -> + call(read_link_info, Args) + end; + Error -> + Error + end. -spec read_link(Name) -> {ok, Filename} | {error, Reason} when @@ -298,7 +322,19 @@ write_file_info(Name, Info = #file_info{}) -> Reason :: posix() | badarg. write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) -> - check_and_call(write_file_info, [file_name(Name), Info, Opts]). + Args = [file_name(Name), Info, Opts], + case check_args(Args) of + ok -> + case lists:member(raw, Opts) of + true -> + [FileName|_] = Args, + ?PRIM_FILE:write_file_info(FileName, Info, Opts); + false -> + call(write_file_info, Args) + end; + Error -> + Error + end. -spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when Dir :: name_all(), @@ -384,26 +420,12 @@ write_file(Name, Bin, ModeList) when is_list(ModeList) -> %% Obsolete, undocumented, local node only, don't use!. %% XXX to be removed. raw_read_file_info(Name) -> - Args = [file_name(Name)], - case check_args(Args) of - ok -> - [FileName] = Args, - ?PRIM_FILE:read_file_info(FileName); - Error -> - Error - end. + read_file_info(Name, [raw]). %% Obsolete, undocumented, local node only, don't use!. %% XXX to be removed. raw_write_file_info(Name, #file_info{} = Info) -> - Args = [file_name(Name)], - case check_args(Args) of - ok -> - [FileName] = Args, - ?PRIM_FILE:write_file_info(FileName, Info); - Error -> - Error - end. + write_file_info(Name, Info, [raw]). %%%----------------------------------------------------------------- %%% File io server functions. diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 70dceb3679..860eec10a0 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -78,7 +78,7 @@ ipv6_v6only. -type socket() :: port(). --export_type([option/0, option_name/0]). +-export_type([option/0, option_name/0, socket/0]). -spec open(Port) -> {ok, Socket} | {error, Reason} when Port :: inet:port_number(), diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index d17da2d329..ec2c350931 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -695,9 +695,9 @@ connect_options(Opts, Family) -> Error -> Error end. -con_opt([{raw,A,B,C}|Opts],R,As) -> +con_opt([{raw,A,B,C}|Opts],#connect_opts{} = R,As) -> con_opt([{raw,{A,B,C}}|Opts],R,As); -con_opt([Opt | Opts], R, As) -> +con_opt([Opt | Opts], #connect_opts{} = R, As) -> case Opt of {ip,IP} -> con_opt(Opts, R#connect_opts { ifaddr = IP }, As); {ifaddr,IP} -> con_opt(Opts, R#connect_opts { ifaddr = IP }, As); @@ -722,10 +722,10 @@ con_opt([Opt | Opts], R, As) -> {Name,Val} when is_atom(Name) -> con_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; -con_opt([], R, _) -> +con_opt([], #connect_opts{} = R, _) -> {ok, R}. -con_add(Name, Val, R, Opts, AllOpts) -> +con_add(Name, Val, #connect_opts{} = R, Opts, AllOpts) -> case add_opt(Name, Val, R#connect_opts.opts, AllOpts) of {ok, SOpts} -> con_opt(Opts, R#connect_opts { opts = SOpts }, AllOpts); @@ -763,9 +763,9 @@ listen_options(Opts, Family) -> Error -> Error end. -list_opt([{raw,A,B,C}|Opts], R, As) -> +list_opt([{raw,A,B,C}|Opts], #listen_opts{} = R, As) -> list_opt([{raw,{A,B,C}}|Opts], R, As); -list_opt([Opt | Opts], R, As) -> +list_opt([Opt | Opts], #listen_opts{} = R, As) -> case Opt of {ip,IP} -> list_opt(Opts, R#listen_opts { ifaddr = IP }, As); {ifaddr,IP} -> list_opt(Opts, R#listen_opts { ifaddr = IP }, As); @@ -791,10 +791,10 @@ list_opt([Opt | Opts], R, As) -> {Name,Val} when is_atom(Name) -> list_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; -list_opt([], R, _SockOpts) -> +list_opt([], #listen_opts{} = R, _SockOpts) -> {ok, R}. -list_add(Name, Val, R, Opts, As) -> +list_add(Name, Val, #listen_opts{} = R, Opts, As) -> case add_opt(Name, Val, R#listen_opts.opts, As) of {ok, SOpts} -> list_opt(Opts, R#listen_opts { opts = SOpts }, As); @@ -821,9 +821,9 @@ udp_options(Opts, Family) -> Error -> Error end. -udp_opt([{raw,A,B,C}|Opts], R, As) -> +udp_opt([{raw,A,B,C}|Opts], #udp_opts{} = R, As) -> udp_opt([{raw,{A,B,C}}|Opts], R, As); -udp_opt([Opt | Opts], R, As) -> +udp_opt([Opt | Opts], #udp_opts{} = R, As) -> case Opt of {ip,IP} -> udp_opt(Opts, R#udp_opts { ifaddr = IP }, As); {ifaddr,IP} -> udp_opt(Opts, R#udp_opts { ifaddr = IP }, As); @@ -838,7 +838,7 @@ udp_opt([Opt | Opts], R, As) -> BinNS = filename2binary(NS), case prim_inet:is_sockopt_val(netns, BinNS) of true -> - list_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As); + udp_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As); false -> {error, badarg} end; @@ -848,10 +848,10 @@ udp_opt([Opt | Opts], R, As) -> {Name,Val} when is_atom(Name) -> udp_add(Name, Val, R, Opts, As); _ -> {error, badarg} end; -udp_opt([], R, _SockOpts) -> +udp_opt([], #udp_opts{} = R, _SockOpts) -> {ok, R}. -udp_add(Name, Val, R, Opts, As) -> +udp_add(Name, Val, #udp_opts{} = R, Opts, As) -> case add_opt(Name, Val, R#udp_opts.opts, As) of {ok, SOpts} -> udp_opt(Opts, R#udp_opts { opts = SOpts }, As); @@ -895,7 +895,7 @@ sctp_options(Opts, Mod) -> Error -> Error end. -sctp_opt([Opt|Opts], Mod, R, As) -> +sctp_opt([Opt|Opts], Mod, #sctp_opts{} = R, As) -> case Opt of {ip,IP} -> sctp_opt_ifaddr(Opts, Mod, R, As, IP); @@ -938,7 +938,7 @@ sctp_opt([], _Mod, #sctp_opts{ifaddr=IfAddr}=R, _SockOpts) -> {ok, R} end. -sctp_opt(Opts, Mod, R, As, Name, Val) -> +sctp_opt(Opts, Mod, #sctp_opts{} = R, As, Name, Val) -> case add_opt(Name, Val, R#sctp_opts.opts, As) of {ok,SocketOpts} -> sctp_opt(Opts, Mod, R#sctp_opts{opts=SocketOpts}, As); @@ -1070,7 +1070,7 @@ gethostbyname_tm(Name, Type, Timer, [wins|_]=Opts) -> gethostbyname_tm_native(Name, Type, Timer, Opts); gethostbyname_tm(Name, Type, Timer, [native|_]=Opts) -> gethostbyname_tm_native(Name, Type, Timer, Opts); -gethostbyname_tm(Name, Type, Timer, [_|_]=Opts) -> +gethostbyname_tm(Name, Type, Timer, [_|Opts]) -> gethostbyname_tm(Name, Type, Timer, Opts); %% Make sure we always can look up our own hostname. gethostbyname_tm(Name, Type, Timer, []) -> diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl index 63f236b069..835dcf2705 100644 --- a/lib/kernel/src/inet_tcp_dist.erl +++ b/lib/kernel/src/inet_tcp_dist.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -77,7 +77,7 @@ listen(Name) -> Error end. -do_listen(Options0) -> +do_listen(Options) -> {First,Last} = case application:get_env(kernel,inet_dist_listen_min) of {ok,N} when is_integer(N) -> case application:get_env(kernel, @@ -90,13 +90,7 @@ do_listen(Options0) -> _ -> {0,0} end, - Options = case application:get_env(kernel, inet_dist_use_interface) of - {ok, Ip} -> - [{ip, Ip} | Options0]; - _ -> - Options0 - end, - do_listen(First, Last, [{backlog,128}|Options]). + do_listen(First, Last, listen_options([{backlog,128}|Options])). do_listen(First,Last,_) when First > Last -> {error,eaddrinuse}; @@ -108,6 +102,23 @@ do_listen(First,Last,Options) -> Other end. +listen_options(Opts0) -> + Opts1 = + case application:get_env(kernel, inet_dist_use_interface) of + {ok, Ip} -> + [{ip, Ip} | Opts0]; + _ -> + Opts0 + end, + case application:get_env(kernel, inet_dist_listen_options) of + {ok,ListenOpts} -> + erlang:display({inet_dist_listen_options, ListenOpts}), + ListenOpts ++ Opts1; + _ -> + Opts1 + end. + + %% ------------------------------------------------------------ %% Accepts new connection attempts from other Erlang nodes. %% ------------------------------------------------------------ @@ -219,7 +230,7 @@ nodelay() -> _ -> {nodelay, true} end. - + %% ------------------------------------------------------------ %% Get remote information about a Socket. @@ -260,9 +271,11 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) -> ?trace("port_please(~p) -> version ~p~n", [Node,Version]), dist_util:reset_timer(Timer), - case inet_tcp:connect(Ip, TcpPort, - [{active, false}, - {packet,2}]) of + case + inet_tcp:connect( + Ip, TcpPort, + connect_options([{active, false}, {packet, 2}])) + of {ok, Socket} -> HSData = #hs_data{ kernel_pid = Kernel, @@ -324,6 +337,15 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) -> ?shutdown(Node) end. +connect_options(Opts) -> + case application:get_env(kernel, inet_dist_connect_options) of + {ok,ConnectOpts} -> + erlang:display({inet_dist_listen_options, ConnectOpts}), + ConnectOpts ++ Opts; + _ -> + Opts + end. + %% %% Close a socket. %% diff --git a/lib/kernel/src/standard_error.erl b/lib/kernel/src/standard_error.erl index 10cf77e0d4..1c43063937 100644 --- a/lib/kernel/src/standard_error.erl +++ b/lib/kernel/src/standard_error.erl @@ -63,7 +63,7 @@ server(PortName,PortSettings) -> run(Port). run(P) -> - put(unicode,false), + put(encoding, latin1), server_loop(P). server_loop(Port) -> @@ -95,25 +95,47 @@ do_io_request(Req, From, ReplyAs, Port) -> io_reply(From, ReplyAs, Reply). %% New in R13B -% Wide characters (Unicode) -io_request({put_chars,Encoding,Chars}, Port) -> % Binary new in R9C - put_chars(wrap_characters_to_binary(Chars,Encoding, - case get(unicode) of - true -> unicode; - _ -> latin1 - end), Port); -io_request({put_chars,Encoding,Mod,Func,Args}, Port) -> - Result = case catch apply(Mod,Func,Args) of - Data when is_list(Data); is_binary(Data) -> - wrap_characters_to_binary(Data,Encoding, - case get(unicode) of - true -> unicode; - _ -> latin1 - end); - Undef -> - Undef - end, - put_chars(Result, Port); +%% Encoding option (unicode/latin1) +io_request({put_chars,unicode,Chars}, Port) -> + case wrap_characters_to_binary(Chars, unicode, get(encoding)) of + error -> + {error,{error,put_chars}}; + Bin -> + put_chars(Bin, Port) + end; +io_request({put_chars,unicode,Mod,Func,Args}, Port) -> + case catch apply(Mod, Func, Args) of + Data when is_list(Data); is_binary(Data) -> + case wrap_characters_to_binary(Data, unicode, get(encoding)) of + Bin when is_binary(Bin) -> + put_chars(Bin, Port); + error -> + {error,{error,put_chars}} + end; + _ -> + {error,{error,put_chars}} + end; +io_request({put_chars,latin1,Chars}, Port) -> + case catch unicode:characters_to_binary(Chars, latin1, get(encoding)) of + Data when is_binary(Data) -> + put_chars(Data, Port); + _ -> + {error,{error,put_chars}} + end; +io_request({put_chars,latin1,Mod,Func,Args}, Port) -> + case catch apply(Mod, Func, Args) of + Data when is_list(Data); is_binary(Data) -> + case + catch unicode:characters_to_binary(Data, latin1, get(encoding)) + of + Bin when is_binary(Bin) -> + put_chars(Bin, Port); + _ -> + {error,{error,put_chars}} + end; + _ -> + {error,{error,put_chars}} + end; %% BC if called from pre-R13 node io_request({put_chars,Chars}, Port) -> io_request({put_chars,latin1,Chars}, Port); @@ -134,10 +156,10 @@ io_request({get_geometry,rows},Port) -> _ -> {error,{error,enotsup}} end; -io_request({getopts,[]}, Port) -> - getopts(Port); -io_request({setopts,Opts}, Port) when is_list(Opts) -> - setopts(Opts, Port); +io_request(getopts, _Port) -> + getopts(); +io_request({setopts,Opts}, _Port) when is_list(Opts) -> + setopts(Opts); io_request({requests,Reqs}, Port) -> io_requests(Reqs, {ok,ok}, Port); io_request(R, _Port) -> %Unknown request @@ -176,47 +198,48 @@ io_reply(From, ReplyAs, Reply) -> %% put_chars put_chars(Chars, Port) when is_binary(Chars) -> _ = put_port(Chars, Port), - {ok,ok}; -put_chars(Chars, Port) -> - case catch list_to_binary(Chars) of - Binary when is_binary(Binary) -> - put_chars(Binary, Port); - _ -> - {error,{error,put_chars}} - end. + {ok,ok}. %% setopts -setopts(Opts0,Port) -> - Opts = proplists:unfold( - proplists:substitute_negations( - [{latin1,unicode}], - Opts0)), +setopts(Opts0) -> + Opts = expand_encoding(Opts0), case check_valid_opts(Opts) of - true -> - do_setopts(Opts,Port); - false -> - {error,{error,enotsup}} + true -> + do_setopts(Opts); + false -> + {error,{error,enotsup}} end. + check_valid_opts([]) -> true; -check_valid_opts([{unicode,Valid}|T]) when Valid =:= true; Valid =:= utf8; Valid =:= false -> +check_valid_opts([{encoding,Valid}|T]) when Valid =:= unicode; + Valid =:= utf8; Valid =:= latin1 -> check_valid_opts(T); check_valid_opts(_) -> false. -do_setopts(Opts, _Port) -> - case proplists:get_value(unicode,Opts) of - Valid when Valid =:= true; Valid =:= utf8 -> - put(unicode,true); - false -> - put(unicode,false); - undefined -> - ok +expand_encoding([]) -> + []; +expand_encoding([latin1 | T]) -> + [{encoding,latin1} | expand_encoding(T)]; +expand_encoding([unicode | T]) -> + [{encoding,unicode} | expand_encoding(T)]; +expand_encoding([H|T]) -> + [H|expand_encoding(T)]. + +do_setopts(Opts) -> + case proplists:get_value(encoding, Opts) of + Valid when Valid =:= unicode; Valid =:= utf8 -> + put(encoding, unicode); + latin1 -> + put(encoding, latin1); + undefined -> + ok end, {ok,ok}. -getopts(_Port) -> - Uni = {unicode, get(unicode) =:= true}, +getopts() -> + Uni = {encoding,get(encoding)}, {ok,[Uni]}. wrap_characters_to_binary(Chars,From,To) -> @@ -227,17 +250,17 @@ wrap_characters_to_binary(Chars,From,To) -> _Else -> 16#10ffff end, - unicode:characters_to_binary( - [ case X of - $\n -> - if - TrNl -> - "\r\n"; - true -> - $\n - end; - High when High > Limit -> - ["\\x{",erlang:integer_to_list(X, 16),$}]; - Ordinary -> - Ordinary - end || X <- unicode:characters_to_list(Chars,From) ],unicode,To). + case catch unicode:characters_to_list(Chars, From) of + L when is_list(L) -> + unicode:characters_to_binary( + [ case X of + $\n when TrNl -> + "\r\n"; + High when High > Limit -> + ["\\x{",erlang:integer_to_list(X, 16),$}]; + Low -> + Low + end || X <- L ], unicode, To); + _ -> + error + end. diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index f1b8a105ed..ef351a25fb 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -77,7 +77,8 @@ MODULES= \ ignore_cores \ zlib_SUITE \ loose_node \ - sendfile_SUITE + sendfile_SUITE \ + standard_error_SUITE APP_FILES = \ appinc.app \ diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl index 9cccdab76b..15c2adc957 100644 --- a/lib/kernel/test/erl_distribution_SUITE.erl +++ b/lib/kernel/test/erl_distribution_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -26,7 +26,8 @@ -export([tick/1, tick_change/1, illegal_nodenames/1, hidden_node/1, table_waste/1, net_setuptime/1, - + inet_dist_options_options/1, + monitor_nodes_nodedown_reason/1, monitor_nodes_complex_nodedown_reason/1, monitor_nodes_node_type/1, @@ -38,7 +39,8 @@ monitor_nodes_many/1]). %% Performs the test at another node. --export([tick_cli_test/1, tick_cli_test1/1, +-export([get_socket_priorities/0, + tick_cli_test/1, tick_cli_test1/1, tick_serv_test/2, tick_serv_test1/1, keep_conn/1, time_ping/1]). @@ -62,7 +64,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [tick, tick_change, illegal_nodenames, hidden_node, - table_waste, net_setuptime, {group, monitor_nodes}]. + table_waste, net_setuptime, inet_dist_options_options, + {group, monitor_nodes}]. groups() -> [{monitor_nodes, [], @@ -554,6 +557,71 @@ check_monitor_nodes_res(Pid, Node) -> end. + +inet_dist_options_options(suite) -> []; +inet_dist_options_options(doc) -> + ["Check the kernel inet_dist_{listen,connect}_options options"]; +inet_dist_options_options(Config) when is_list(Config) -> + Prio = 1, + case gen_udp:open(0, [{priority,Prio}]) of + {ok,Socket} -> + case inet:getopts(Socket, [priority]) of + {ok,[{priority,Prio}]} -> + ok = gen_udp:close(Socket), + do_inet_dist_options_options(Prio); + _ -> + ok = gen_udp:close(Socket), + {skip, + "Can not set priority "++integer_to_list(Prio)++ + " on socket"} + end; + {error,_} -> + {skip, "Can not set priority on socket"} + end. + +do_inet_dist_options_options(Prio) -> + PriorityString0 = "[{priority,"++integer_to_list(Prio)++"}]", + PriorityString = + case os:cmd("echo [{a,1}]") of + "[{a,1}]"++_ -> + PriorityString0; + _ -> + %% Some shells need quoting of [{}] + "'"++PriorityString0++"'" + end, + InetDistOptions = + "-hidden " + "-kernel inet_dist_connect_options "++PriorityString++" " + "-kernel inet_dist_listen_options "++PriorityString, + ?line {ok,Node1} = + start_node(inet_dist_options_1, InetDistOptions), + ?line {ok,Node2} = + start_node(inet_dist_options_2, InetDistOptions), + %% + ?line pong = + rpc:call(Node1, net_adm, ping, [Node2]), + ?line PrioritiesNode1 = + rpc:call(Node1, ?MODULE, get_socket_priorities, []), + ?line PrioritiesNode2 = + rpc:call(Node2, ?MODULE, get_socket_priorities, []), + ?line ?t:format("PrioritiesNode1 = ~p", [PrioritiesNode1]), + ?line ?t:format("PrioritiesNode2 = ~p", [PrioritiesNode2]), + ?line Elevated = [P || P <- PrioritiesNode1, P =:= Prio], + ?line Elevated = [P || P <- PrioritiesNode2, P =:= Prio], + ?line [_|_] = Elevated, + %% + ?line stop_node(Node2), + ?line stop_node(Node1), + ok. + +get_socket_priorities() -> + [Priority || + {ok,[{priority,Priority}]} <- + [inet:getopts(Port, [priority]) || + Port <- erlang:ports(), + element(2, erlang:port_info(Port, name)) =:= "tcp_inet"]]. + + %% %% Testcase: diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index f6d6cd94ab..2ce2303ba3 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -424,7 +424,7 @@ make_del_dir(Config) when is_list(Config) -> ?line ok = ?FILE_MODULE:del_dir(NewDir), ?line {error, enoent} = ?FILE_MODULE:del_dir(NewDir), % Make sure we are not in a directory directly under test_server - % as that would result in eacess errors when trying to delere '..', + % as that would result in eacces errors when trying to delete '..', % because there are processes having that directory as current. ?line ok = ?FILE_MODULE:make_dir(NewDir), ?line {ok,CurrentDir} = file:get_cwd(), @@ -1236,9 +1236,10 @@ file_info_basic_file(Config) when is_list(Config) -> %% Test that the file has the expected attributes. %% The times are tricky, so we will save them to a separate test case. - ?line {ok,#file_info{size=Size,type=Type,access=Access, - atime=AccessTime,mtime=ModifyTime}} = - ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name, [raw]), + #file_info{size=Size,type=Type,access=Access, + atime=AccessTime,mtime=ModifyTime} = FileInfo, ?line io:format("Access ~p, Modify ~p", [AccessTime, ModifyTime]), ?line Size = 7, ?line Type = regular, @@ -1280,9 +1281,10 @@ file_info_basic_directory(Config) when is_list(Config) -> test_server:timetrap_cancel(Dog). test_directory(Name, ExpectedAccess) -> - ?line {ok,#file_info{size=Size,type=Type,access=Access, - atime=AccessTime,mtime=ModifyTime}} = - ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name, [raw]), + #file_info{size=Size,type=Type,access=Access, + atime=AccessTime,mtime=ModifyTime} = FileInfo, ?line io:format("Testing directory ~s", [Name]), ?line io:format("Directory size is ~p", [Size]), ?line io:format("Access ~p", [Access]), @@ -1307,11 +1309,11 @@ file_info_bad(doc) -> []; file_info_bad(Config) when is_list(Config) -> ?line Dog = test_server:timetrap(test_server:seconds(5)), ?line RootDir = filename:join([?config(priv_dir, Config)]), - ?line {error, enoent} = - ?FILE_MODULE:read_file_info( - filename:join(RootDir, - atom_to_list(?MODULE)++ "_nonexistent")), + FileName = filename:join(RootDir, atom_to_list(?MODULE) ++ "_nonexistent"), + {error,enoent} = ?FILE_MODULE:read_file_info(FileName), + {error,enoent} = ?FILE_MODULE:read_file_info(FileName, [raw]), ?line {error, enoent} = ?FILE_MODULE:read_file_info(""), + {error, enoent} = ?FILE_MODULE:read_file_info("", [raw]), ?line [] = flush(), ?line test_server:timetrap_cancel(Dog), ok. @@ -1346,8 +1348,16 @@ file_info_int(Config) -> ?line io:put_chars(Fd1,"foo"), %% check that the file got a modify date max a few seconds away from now - ?line {ok,#file_info{type=regular,atime=AccTime1,mtime=ModTime1}} = - ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo1} = ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo1Raw} = ?FILE_MODULE:read_file_info(Name, [raw]), + + %% We assert that everything but the size is the same, on some OSs the + %% size may not have been flushed to disc and we do not want to do a + %% sync to force it. + FileInfo1Raw = FileInfo1#file_info{ size = FileInfo1Raw#file_info.size }, + + #file_info{type=regular,atime=AccTime1,mtime=ModTime1} = FileInfo1, + ?line Now = erlang:localtime(), %??? ?line io:format("Now ~p",[Now]), ?line io:format("Open file Acc ~p Mod ~p",[AccTime1,ModTime1]), @@ -1363,9 +1373,10 @@ file_info_int(Config) -> %% close the file, and watch the modify date change ?line ok = ?FILE_MODULE:close(Fd1), - ?line {ok,#file_info{size=Size,type=regular,access=Access, - atime=AccTime2,mtime=ModTime2}} = - ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo2} = ?FILE_MODULE:read_file_info(Name), + {ok,FileInfo2} = ?FILE_MODULE:read_file_info(Name, [raw]), + #file_info{size=Size,type=regular,access=Access, + atime=AccTime2,mtime=ModTime2} = FileInfo2, ?line io:format("Closed file Acc ~p Mod ~p",[AccTime2,ModTime2]), ?line true = time_dist(ModTime1,ModTime2) >= 0, @@ -1374,9 +1385,10 @@ file_info_int(Config) -> ?line Access = read_write, %% Do some directory checking - ?line {ok,#file_info{size=DSize,type=directory,access=DAccess, - atime=AccTime3,mtime=ModTime3}} = - ?FILE_MODULE:read_file_info(RootDir), + {ok,FileInfo3} = ?FILE_MODULE:read_file_info(RootDir), + {ok,FileInfo3} = ?FILE_MODULE:read_file_info(RootDir, [raw]), + #file_info{size=DSize,type=directory,access=DAccess, + atime=AccTime3,mtime=ModTime3} = FileInfo3, %% this dir was modified only a few secs ago ?line io:format("Dir Acc ~p; Mod ~p; Now ~p", [AccTime3, ModTime3, Now]), ?line true = abs(time_dist(Now,ModTime3)) < 5, @@ -1449,6 +1461,12 @@ file_write_file_info(Config) when is_list(Config) -> ?line ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#400}), ?line {error, eacces} = ?FILE_MODULE:write_file(Name1, "hello again"), + %% Same with raw. + ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#600}, [raw]), + ok = ?FILE_MODULE:write_file(Name1, "hello again"), + ?FILE_MODULE:write_file_info(Name1, #file_info{mode=8#400}, [raw]), + {error,eacces} = ?FILE_MODULE:write_file(Name1, "hello again"), + %% Write the times again. %% Note: Seconds must be even; see note in file_info_times/1. @@ -2650,7 +2668,9 @@ make_link(Config) when is_list(Config) -> %% since they are not used on symbolic links. ?line {ok, Info} = ?FILE_MODULE:read_link_info(Name), + {ok,Info} = ?FILE_MODULE:read_link_info(Name, [raw]), ?line {ok, Info} = ?FILE_MODULE:read_link_info(Alias), + {ok,Info} = ?FILE_MODULE:read_link_info(Alias, [raw]), ?line #file_info{links = 2, type = regular} = Info, ?line {error, eexist} = ?FILE_MODULE:make_link(Name, Alias), @@ -2670,6 +2690,7 @@ read_link_info_for_non_link(Config) when is_list(Config) -> ?line {ok, #file_info{type=directory}} = ?FILE_MODULE:read_link_info("."), + {ok, #file_info{type=directory}} = ?FILE_MODULE:read_link_info(".", [raw]), ?line [] = flush(), ?line test_server:timetrap_cancel(Dog), @@ -2700,11 +2721,15 @@ symlinks(Config) when is_list(Config) -> {skipped, "Windows user not privileged to create symlinks"}; ok -> ?line {ok, Info1} = ?FILE_MODULE:read_file_info(Name), + {ok,Info1} = ?FILE_MODULE:read_file_info(Name, [raw]), ?line {ok, Info1} = ?FILE_MODULE:read_file_info(Alias), + {ok,Info1} = ?FILE_MODULE:read_file_info(Alias, [raw]), ?line {ok, Info1} = ?FILE_MODULE:read_link_info(Name), + {ok,Info1} = ?FILE_MODULE:read_link_info(Name, [raw]), ?line #file_info{links = 1, type = regular} = Info1, ?line {ok, Info2} = ?FILE_MODULE:read_link_info(Alias), + {ok,Info2} = ?FILE_MODULE:read_link_info(Alias, [raw]), ?line #file_info{links=1, type=symlink} = Info2, ?line {ok, Name} = ?FILE_MODULE:read_link(Alias), {ok, Name} = ?FILE_MODULE:read_link_all(Alias), diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c index 73a6568b30..d774767624 100644 --- a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c +++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c @@ -26,8 +26,10 @@ #ifdef __WIN32__ #include <winsock2.h> +#define sock_close(s) closesocket(s) #else #include <sys/socket.h> +#define sock_close(s) close(s) #endif #define sock_open(af, type, proto) socket((af), (type), (proto)) @@ -46,7 +48,7 @@ static ERL_NIF_TERM closesockfd(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg enif_get_int(env, argv[0], &fd); - close(fd); + sock_close(fd); return enif_make_int(env, fd); } diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index ed43749cc0..849013ac79 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2015. 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 @@ -36,9 +36,10 @@ gethostnative_parallell/1, cname_loop/1, gethostnative_soft_restart/0, gethostnative_soft_restart/1, gethostnative_debug_level/0, gethostnative_debug_level/1, + lookup_bad_search_option/1, getif/1, getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1, - parse_strict_address/1, simple_netns/1]). + parse_strict_address/1, simple_netns/1, simple_netns_open/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0, test_netns/0]). @@ -52,8 +53,9 @@ all() -> ipv4_to_ipv6, host_and_addr, {group, parse}, t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level, gethostnative_soft_restart, + lookup_bad_search_option, getif, getif_ifr_name_overflow, getservbyname_overflow, - getifaddrs, parse_strict_address, simple_netns]. + getifaddrs, parse_strict_address, simple_netns, simple_netns_open]. groups() -> [{parse, [], [parse_hosts, parse_address]}]. @@ -908,6 +910,21 @@ lookup_loop([H|Hs], Delay, Tag, Parent, Cnt, Hosts) -> +lookup_bad_search_option(suite) -> + []; +lookup_bad_search_option(doc) -> + ["Test lookup with erroneously configured lookup option (OTP-12133)"]; +lookup_bad_search_option(Config) when is_list(Config) -> + Db = inet_db, + %% The bad option can not enter through inet_db:set_lookup/1, + %% but through e.g .inetrc. + ets:insert(Db, {res_lookup,[lookup_bad_search_option]}), + {ok,Hostname} = inet:gethostname(), + {ok,_Hent} = inet:gethostbyname(Hostname), % Will hang loop for this bug + ok. + + + getif(suite) -> []; getif(doc) -> @@ -1128,6 +1145,32 @@ jog_netns_opt(S) -> ok. +simple_netns_open(Config) when is_list(Config) -> + case gen_udp:open(0, [binary,{netns,"/"},inet]) of + {ok,U} -> + ok = gen_udp:close(U); + {error,E1} when E1 =:= einval; E1 =:= eperm -> + ok + end, + case gen_tcp:listen(0, [binary,{netns,"/"},inet]) of + {ok,T} -> + ok = gen_tcp:close(T); + {error,E2} when E2 =:= einval; E2 =:= eperm -> + ok + end, + try gen_sctp:open(0, [binary,{netns,"/"},inet]) of + {ok,S} -> + ok = gen_sctp:close(S); + {error,E3} + when E3 =:= einval; E3 =:= eperm; E3 =:= eprotonosupport -> + ok + catch + error:badarg -> + %% Some older platforms does not allow netns for sctp + ok + end. + + %% Manual test to be run outside test_server in an emulator %% started by root, in a machine with setns() support... test_netns() -> diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl index 05bd5b3a3d..f55716cbec 100644 --- a/lib/kernel/test/prim_file_SUITE.erl +++ b/lib/kernel/test/prim_file_SUITE.erl @@ -262,7 +262,7 @@ make_del_dir(Config, Handle, Suffix) -> ?line {error, enoent} = ?PRIM_FILE_call(del_dir, Handle, [NewDir]), % Make sure we are not in a directory directly under test_server - % as that would result in eacess errors when trying to delere '..', + % as that would result in eacces errors when trying to delete '..', % because there are processes having that directory as current. ?line ok = ?PRIM_FILE_call(make_dir, Handle, [NewDir]), ?line {ok, CurrentDir} = ?PRIM_FILE_call(get_cwd, Handle, []), diff --git a/lib/kernel/test/standard_error_SUITE.erl b/lib/kernel/test/standard_error_SUITE.erl new file mode 100644 index 0000000000..b290454b40 --- /dev/null +++ b/lib/kernel/test/standard_error_SUITE.erl @@ -0,0 +1,38 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2014. 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% +%% + +-module(standard_error_SUITE). + +-export([all/0,suite/0]). +-export([badarg/1,getopts/1]). + +suite() -> + [{ct_hooks,[ts_install_cth]}]. + +all() -> + [badarg,getopts]. + +badarg(Config) when is_list(Config) -> + {'EXIT',{badarg,_}} = (catch io:put_chars(standard_error, [oops])), + true = erlang:is_process_alive(whereis(standard_error)), + ok. + +getopts(Config) when is_list(Config) -> + [{encoding,latin1}] = io:getopts(standard_error), + ok. diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index be633a304a..15820a0182 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 3.0.3 +KERNEL_VSN = 3.1 diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4 deleted file mode 100644 index ed492d55ff..0000000000 --- a/lib/megaco/aclocal.m4 +++ /dev/null @@ -1,1954 +0,0 @@ -dnl -dnl %CopyrightBegin% -dnl -dnl Copyright Ericsson AB 1998-2013. 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 - -AC_DEFUN(LM_PRECIOUS_VARS, -[ - -dnl ERL_TOP -AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) - -dnl Tools -AC_ARG_VAR(CC, [C compiler]) -AC_ARG_VAR(CFLAGS, [C compiler flags]) -AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) -AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) -AC_ARG_VAR(CPP, [C/C++ preprocessor]) -AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) -AC_ARG_VAR(CXX, [C++ compiler]) -AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) -AC_ARG_VAR(LD, [linker (is often overridden by configure)]) -AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) -AC_ARG_VAR(LIBS, [libraries]) -AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) -AC_ARG_VAR(RANLIB, [ranlib]) -AC_ARG_VAR(AR, [ar]) -AC_ARG_VAR(GETCONF, [getconf]) - -dnl Cross system root -AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) - -dnl Cross compilation variables -AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) - -dnl Cross compilation variables for OSE -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file]) -AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) - -]) - -AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, -[ -erl_xcomp_without_sysroot=no -if test "$cross_compiling" = "yes"; then - test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes - test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" -else - erl_xcomp_sysroot= - erl_xcomp_isysroot= -fi -]) - -AC_DEFUN(LM_CHECK_GETCONF, -[ -if test "$cross_compiling" != "yes"; then - AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) -else - dnl First check if we got a `<HOST>-getconf' in $PATH - host_getconf="$host_alias-getconf" - AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) - if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then - dnl We should perhaps give up if we have'nt found it by now, but at - dnl least in one Tilera MDE `getconf' under sysroot is a bourne - dnl shell script which we can use. We try to find `<HOST>-getconf' - dnl or `getconf' under sysconf, but only under sysconf since - dnl `getconf' in $PATH is almost guaranteed to be for the build - dnl machine. - GETCONF= - prfx="$erl_xcomp_sysroot" - AC_PATH_TOOL([GETCONF], [getconf], [false], - ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) - fi -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_WINDOWS_ENVIRONMENT -dnl -dnl -dnl Tries to determine thw windows build environment, i.e. -dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC -dnl - -AC_DEFUN(LM_WINDOWS_ENVIRONMENT, -[ -MIXED_CYGWIN=no -MIXED_MSYS=no - -AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) -if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([Cygwin and VC]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - elif test -x /usr/bin/msysinfo; then - CFLAGS="-O2" - MIXED_MSYS=yes - AC_MSG_RESULT([MSYS and VC]) - MIXED_MSYS_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no - MIXED_MSYS_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) -AC_SUBST(MIXED_MSYS_VC) - -MIXED_VC=no -if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then - MIXED_VC=yes -fi - -AC_SUBST(MIXED_VC) - -if test "x$MIXED_MSYS" != "xyes"; then - AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) - if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi - else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no - fi -else - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) - -AC_MSG_CHECKING(if we mix msys with another native compiler) -if test "X$MIXED_MSYS" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_MSYS) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_FIND_EMU_CC -dnl -dnl -dnl Tries fairly hard to find a C compiler that can handle jump tables. -dnl Defines the @EMU_CC@ variable for the makefiles and -dnl inserts NO_JUMP_TABLE in the header if one cannot be found... -dnl - -AC_DEFUN(LM_FIND_EMU_CC, - [AC_CACHE_CHECK(for a compiler that handles jumptables, - ac_cv_prog_emu_cc, - [ -AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; -lbl1: - return 1; -lbl2: - return 2; -],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - -if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc-4.2 gcc; do - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_progname; then - ac_cv_prog_emu_cc=$ac_dir/$ac_progname - break - fi - done - IFS="$ac_save_ifs" - if test $ac_cv_prog_emu_cc != no; then - break - fi - done -fi - -if test $ac_cv_prog_emu_cc != no; then - save_CC=$CC - save_CFLAGS=$CFLAGS - save_CPPFLAGS=$CPPFLAGS - CC=$ac_cv_prog_emu_cc - CFLAGS="" - CPPFLAGS="" - AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; - lbl1: - return 1; - lbl2: - return 2; - ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - CC=$save_CC - CFLAGS=$save_CFLAGS - CPPFLAGS=$save_CPPFLAGS -fi -]) -if test $ac_cv_prog_emu_cc = no; then - AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) - EMU_CC=$CC -else - EMU_CC=$ac_cv_prog_emu_cc -fi -AC_SUBST(EMU_CC) -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_INSTALL_DIR -dnl -dnl This macro may be used by any OTP application. -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 -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_PERL5 -dnl -dnl Try to find perl version 5. If found set PERL to the absolute path -dnl of the program, if not found set PERL to false. -dnl -dnl On some systems /usr/bin/perl is perl 4 and e.g. -dnl /usr/local/bin/perl is perl 5. We try to handle this case by -dnl putting a couple of -dnl Tries to handle the case that there are two programs called perl -dnl in the path and one of them is perl 5 and the other isn't. -dnl -AC_DEFUN(LM_PROG_PERL5, -[AC_PATH_PROGS(PERL, perl5 perl, false, - /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) -changequote(, )dnl -dnl[ That bracket is needed to balance the right bracket below -if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then -changequote([, ])dnl - ac_cv_path_PERL=false - PERL=false -dnl AC_MSG_WARN(perl version 5 not found) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SO_BSDCOMPAT -dnl -dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) -dnl -AC_DEFUN(LM_DECL_SO_BSDCOMPAT, -[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, -AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], - ac_cv_decl_so_bsdcompat=yes, - ac_cv_decl_so_bsdcompat=no)) - -case "${ac_cv_decl_so_bsdcompat}" in - "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], - [Define if you have SO_BSDCOMPAT flag on sockets]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_INADDR_LOOPBACK -dnl -dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default -dnl - -AC_DEFUN(LM_DECL_INADDR_LOOPBACK, -[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], - ac_cv_decl_inaddr_loopback, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], -ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) -]) - -if test ${ac_cv_decl_inaddr_loopback} = no; then - AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], - ac_cv_decl_inaddr_loopback_rpc, - AC_TRY_COMPILE([#include <rpc/types.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_rpc=yes, - ac_cv_decl_inaddr_loopback_rpc=no)) - - case "${ac_cv_decl_inaddr_loopback_rpc}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], - [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; - * ) - AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], - ac_cv_decl_inaddr_loopback_winsock2, - AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN - #include <winsock2.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_winsock2=yes, - ac_cv_decl_inaddr_loopback_winsock2=no)) - case "${ac_cv_decl_inaddr_loopback_winsock2}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], - [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; - * ) - # couldn't find it anywhere - AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], - [Define if you don't have a definition of INADDR_LOOPBACK]) ;; - esac;; - esac -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_SOCKADDR_SA_LEN -dnl -dnl Check if the sockaddr structure has the field sa_len -dnl - -AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, -[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], - ac_cv_struct_sockaddr_sa_len, -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], - ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) - -dnl FIXME convbreak -case ${ac_cv_struct_sockaddr_sa_len} in - "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; - *) ;; -esac -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_EXCEPTION -dnl -dnl Check to see whether the system supports the matherr function -dnl and its associated type "struct exception". -dnl - -AC_DEFUN(LM_STRUCT_EXCEPTION, -[AC_CACHE_CHECK([for struct exception (and matherr function)], - ac_cv_struct_exception, -AC_TRY_COMPILE([#include <math.h>], - [struct exception x; x.type = DOMAIN; x.type = SING;], - ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) - -case "${ac_cv_struct_exception}" in - "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_IPV6 -dnl -dnl Check for ipv6 support and what the in6_addr structure is called. -dnl (early linux used in_addr6 insted of in6_addr) -dnl - -AC_DEFUN(LM_SYS_IPV6, -[AC_MSG_CHECKING(for IP version 6 support) -AC_CACHE_VAL(ac_cv_sys_ipv6_support, -[ok_so_far=yes - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) - -if test $ok_so_far = yes; then - ac_cv_sys_ipv6_support=yes -else - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in_addr6 a6; struct sockaddr_in6 s6;], - ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) -fi -])dnl - -dnl -dnl Have to use old style AC_DEFINE due to BC with old autoconf. -dnl - -case ${ac_cv_sys_ipv6_support} in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - ;; - in_addr6) - AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) - ;; - *) - AC_MSG_RESULT(no) - ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_MULTICAST -dnl -dnl Check for multicast support. Only checks for multicast options in -dnl setsockopt(), no check is performed that multicasting actually works. -dnl If options are found defines HAVE_MULTICAST_SUPPORT -dnl - -AC_DEFUN(LM_SYS_MULTICAST, -[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, -[AC_EGREP_CPP(yes, -[#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) -yes -#endif -], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) -if test $ac_cv_sys_multicast_support = yes; then - AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], - [Define if setsockopt() accepts multicast options]) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SYS_ERRLIST -dnl -dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared -dnl in a system header file, stdio.h or errno.h. -dnl - -AC_DEFUN(LM_DECL_SYS_ERRLIST, -[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], - ac_cv_decl_sys_errlist, -[AC_TRY_COMPILE([#include <stdio.h> -#include <errno.h>], [char *msg = *(sys_errlist + 1);], - ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) -if test $ac_cv_decl_sys_errlist = yes; then - AC_DEFINE(SYS_ERRLIST_DECLARED,[], - [define if the variable sys_errlist is declared in a system header file]) -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes -dnl [, action-if-found [, action-if-not-found]]] ) -dnl -dnl Checks if the declaration "declaration" of "funname" conflicts -dnl with the header files idea of how the function should be -dnl declared. It is useful on systems which lack prototypes and you -dnl need to provide your own (e.g. when you want to take the address -dnl of a function). The 4'th argument is expanded if conflicting, -dnl the 5'th argument otherwise -dnl -dnl - -AC_DEFUN(LM_CHECK_FUNC_DECL, -[AC_MSG_CHECKING([for conflicting declaration of $1]) -AC_CACHE_VAL(ac_cv_func_decl_$1, -[AC_TRY_COMPILE([#include <stdio.h> -$3],[$2 -char *c = (char *)$1; -], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) -if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then - AC_MSG_RESULT(yes) - ifelse([$4], , :, [$4]) -else - AC_MSG_RESULT(no) -ifelse([$5], , , [$5 -])dnl -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl AC_DOUBLE_MIDDLE_ENDIAN -dnl -dnl Checks whether doubles are represented in "middle-endian" format. -dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly, -dnl as well as DOUBLE_MIDDLE_ENDIAN. -dnl -dnl - -AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN], -[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian, -[# It does not; compile a test program. -AC_RUN_IFELSE( -[AC_LANG_SOURCE([[#include <stdlib.h> - -int -main(void) -{ - int i = 0; - int zero = 0; - int bigendian; - int zero_index = 0; - - union - { - long int l; - char c[sizeof (long int)]; - } u; - - /* we'll use the one with 32-bit words */ - union - { - double d; - unsigned int c[2]; - } vint; - - union - { - double d; - unsigned long c[2]; - } vlong; - - union - { - double d; - unsigned short c[2]; - } vshort; - - - /* Are we little or big endian? From Harbison&Steele. */ - u.l = 1; - bigendian = (u.c[sizeof (long int) - 1] == 1); - - zero_index = bigendian ? 1 : 0; - - vint.d = 1.0; - vlong.d = 1.0; - vshort.d = 1.0; - - if (sizeof(unsigned int) == 4) - { - if (vint.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned long) == 4) - { - if (vlong.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned short) == 4) - { - if (vshort.c[zero_index] != 0) - zero = 1; - } - - exit (zero); -} -]])], - [ac_cv_c_double_middle_endian=no], - [ac_cv_c_double_middle_endian=yes], - [ac_cv_c_double_middle=unknown])]) -case $ac_cv_c_double_middle_endian in - yes) - m4_default([$1], - [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1, - [Define to 1 if your processor stores the words in a double in - middle-endian format (like some ARMs).])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_WARN([unknown double endianness -presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;; -esac -])# AC_C_DOUBLE_MIDDLE_ENDIAN - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_THR_LIB -dnl -dnl This macro may be used by any OTP application. -dnl -dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also -dnl checks for some pthread headers which will appear in DEFS or config.h. -dnl - -AC_DEFUN(LM_CHECK_THR_LIB, -[ - -NEED_NPTL_PTHREAD_H=no - -dnl win32? -AC_MSG_CHECKING([for native win32 threads]) -if test "X$host_os" = "Xwin32"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DWIN32_THREADS" - THR_LIBS= - THR_LIB_NAME=win32_threads - THR_LIB_TYPE=win32_threads -elif test "X$host_os" = "Xose"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DOSE_THREADS" - THR_LIBS= - THR_LIB_NAME=ose_threads - THR_LIB_TYPE=ose_threads -else - AC_MSG_RESULT(no) - THR_DEFS= - THR_LIBS= - THR_LIB_NAME= - THR_LIB_TYPE=posix_unknown - -dnl Try to find POSIX threads - -dnl The usual pthread lib... - AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") - -dnl Very old versions of FreeBSD have pthreads in special c library, c_r... - if test "x$THR_LIBS" = "x"; then - AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") - fi - -dnl QNX has pthreads in standard C library - if test "x$THR_LIBS" = "x"; then - AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed") - fi - -dnl On ofs1 the '-pthread' switch should be used - if test "x$THR_LIBS" = "x"; then - AC_MSG_CHECKING([if the '-pthread' switch can be used]) - saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -pthread" - AC_TRY_LINK([#include <pthread.h>], - pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, - [THR_DEFS="-pthread" - THR_LIBS="-pthread"]) - CFLAGS=$saved_cflags - if test "x$THR_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - fi - - if test "x$THR_LIBS" != "x"; then - THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" - THR_LIB_NAME=pthread - if test "x$THR_LIBS" = "xnone_needed"; then - THR_LIBS= - fi - case $host_os in - solaris*) - THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; - linux*) - THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" - - LM_CHECK_GETCONF - AC_MSG_CHECKING(for Native POSIX Thread Library) - libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` - if test $? -eq 0; then - case "$libpthr_vsn" in - *nptl*|*NPTL*) nptl=yes;; - *) nptl=no;; - esac - elif test "$cross_compiling" = "yes"; then - case "$erl_xcomp_linux_nptl" in - "") nptl=cross;; - yes|no) nptl=$erl_xcomp_linux_nptl;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; - esac - else - nptl=no - fi - AC_MSG_RESULT($nptl) - if test $nptl = cross; then - nptl=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $nptl = yes; then - THR_LIB_TYPE=posix_nptl - need_nptl_incldir=no - AC_CHECK_HEADER(nptl/pthread.h, - [need_nptl_incldir=yes - NEED_NPTL_PTHREAD_H=yes]) - if test $need_nptl_incldir = yes; then - # Ahh... - nptl_path="$C_INCLUDE_PATH:$CPATH" - if test X$cross_compiling != Xyes; then - nptl_path="$nptl_path:/usr/local/include:/usr/include" - else - IROOT="$erl_xcomp_isysroot" - test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" - test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) - nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" - fi - nptl_ws_path= - save_ifs="$IFS"; IFS=":" - for dir in $nptl_path; do - if test "x$dir" != "x"; then - nptl_ws_path="$nptl_ws_path $dir" - fi - done - IFS=$save_ifs - nptl_incldir= - for dir in $nptl_ws_path; do - AC_CHECK_HEADER($dir/nptl/pthread.h, - nptl_incldir=$dir/nptl) - if test "x$nptl_incldir" != "x"; then - THR_DEFS="$THR_DEFS -isystem $nptl_incldir" - break - fi - done - if test "x$nptl_incldir" = "x"; then - AC_MSG_ERROR(Failed to locate nptl system include directory) - fi - fi - fi - ;; - *) ;; - esac - - dnl We sometimes need THR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $THR_DEFS" - - dnl - dnl Check for headers - dnl - - AC_CHECK_HEADER(pthread.h, - AC_DEFINE(HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - fi -fi - -]) - -AC_DEFUN(ERL_INTERNAL_LIBS, -[ - -ERTS_INTERNAL_X_LIBS= - -AC_CHECK_LIB(kstat, kstat_open, -[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) -ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) - -AC_SUBST(ERTS_INTERNAL_X_LIBS) - -]) - -AC_DEFUN(ETHR_CHK_SYNC_OP, -[ - AC_MSG_CHECKING([for $3-bit $1()]) - case "$2" in - "1") sync_call="$1(&var);";; - "2") sync_call="$1(&var, ($4) 0);";; - "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; - esac - have_sync_op=no - AC_TRY_LINK([], - [ - $4 res; - volatile $4 var; - res = $sync_call - ], - [have_sync_op=yes]) - test $have_sync_op = yes && $5 - AC_MSG_RESULT([$have_sync_op]) -]) - -AC_DEFUN(ETHR_CHK_INTERLOCKED, -[ - ilckd="$1" - AC_MSG_CHECKING([for ${ilckd}()]) - case "$2" in - "1") ilckd_call="${ilckd}(var);";; - "2") ilckd_call="${ilckd}(var, ($3) 0);";; - "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; - "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; - esac - have_interlocked_op=no - AC_TRY_LINK( - [ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <intrin.h> - ], - [ - volatile $3 *var; - volatile $3 arr[2]; - - $ilckd_call - return 0; - ], - [have_interlocked_op=yes]) - test $have_interlocked_op = yes && $4 - AC_MSG_RESULT([$have_interlocked_op]) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_FIND_ETHR_LIB -dnl -dnl NOTE! This macro may be changed at any time! Should *only* be used by -dnl ERTS! -dnl -dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link -dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS -dnl except that the ethread lib itself is not included), ETHR_DEFS to -dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the -dnl thread library which the ethread library is based on, and ETHR_LIB_NAME -dnl to the name of the library where the ethread implementation is located. -dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and -dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, -dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the -dnl empty string. -dnl - -AC_DEFUN(ERL_FIND_ETHR_LIB, -[ - -AC_ARG_ENABLE(native-ethr-impls, - AS_HELP_STRING([--disable-native-ethr-impls], - [disable native ethread implementations]), -[ case "$enableval" in - no) disable_native_ethr_impls=yes ;; - *) disable_native_ethr_impls=no ;; - esac ], disable_native_ethr_impls=no) - -test "X$disable_native_ethr_impls" = "Xyes" && - AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) - -AC_ARG_ENABLE(x86-out-of-order, - AS_HELP_STRING([--enable-x86-out-of-order], - [enable x86/x84_64 out of order support (default disabled)])) - -AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, - AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [prefer gcc native ethread implementations]), -[ case "$enableval" in - yes) enable_prefer_gcc_native_ethr_impls=yes ;; - *) enable_prefer_gcc_native_ethr_impls=no ;; - esac ], enable_prefer_gcc_native_ethr_impls=no) - -test $enable_prefer_gcc_native_ethr_impls = yes && - AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) - -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [specify and prefer usage of libatomic_ops in the ethread library])) - -AC_ARG_WITH(with_sparc_memory_order, - AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], - [specify sparc memory order (defaults to RMO)])) - -LM_CHECK_THR_LIB -ERL_INTERNAL_LIBS - -ethr_have_native_atomics=no -ethr_have_native_spinlock=no -ETHR_THR_LIB_BASE="$THR_LIB_NAME" -ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" -ETHR_DEFS="$THR_DEFS" -ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" -ETHR_LIBS= -ETHR_LIB_NAME= - -ethr_modified_default_stack_size= - -dnl Name of lib where ethread implementation is located -ethr_lib_name=ethread - -case "$THR_LIB_NAME" in - - win32_threads) - ETHR_THR_LIB_BASE_DIR=win - # * _WIN32_WINNT >= 0x0400 is needed for - # TryEnterCriticalSection - # * _WIN32_WINNT >= 0x0403 is needed for - # InitializeCriticalSectionAndSpinCount - # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. - # - # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it - # and save it in ETHR_DEFS. - found_win32_winnt=no - for cppflag in $CPPFLAGS; do - case $cppflag in - -DWINVER*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - ;; - -D_WIN32_WINNT*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - found_win32_winnt=yes - ;; - *) - ;; - esac - done - if test $found_win32_winnt = no; then - AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) - fi - - AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) - - if test "X$disable_native_ethr_impls" = "Xyes"; then - have_interlocked_op=no - ethr_have_native_atomics=no - else - ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) - fi - test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes - ;; - - pthread|ose_threads) - case "$THR_LIB_NAME" in - pthread) - ETHR_THR_LIB_BASE_DIR=pthread - AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) - ;; - ose_threads) - AC_DEFINE(ETHR_OSE_THREADS, 1, - [Define if you have OSE style threads]) - ETHR_THR_LIB_BASE_DIR=ose - AC_CHECK_HEADER(ose_spi/ose_spi.h, - AC_DEFINE(HAVE_OSE_SPI_H, 1, - [Define if you have the "ose_spi/ose_spi.h" header file.])) - ;; - esac - if test "x$THR_LIB_NAME" = "xpthread"; then - case $host_os in - openbsd*) - # The default stack size is insufficient for our needs - # on OpenBSD. We increase it to 256 kilo words. - ethr_modified_default_stack_size=256;; - linux*) - ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" - - if test X$cross_compiling = Xyes; then - case X$erl_xcomp_linux_usable_sigusrx in - X) usable_sigusrx=cross;; - Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; - esac - case X$erl_xcomp_linux_usable_sigaltstack in - X) usable_sigaltstack=cross;; - Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; - esac - else - # FIXME: Test for actual problems instead of kernel versions - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) - usable_sigusrx=no - usable_sigaltstack=no;; - 2.[[2-3]]|2.[[2-3]].*) - usable_sigusrx=yes - usable_sigaltstack=no;; - *) - usable_sigusrx=yes - usable_sigaltstack=yes;; - esac - fi - - AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) - AC_MSG_RESULT($usable_sigusrx) - if test $usable_sigusrx = cross; then - usable_sigusrx=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigusrx = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" - fi - - AC_MSG_CHECKING(if sigaltstack can be used) - AC_MSG_RESULT($usable_sigaltstack) - if test $usable_sigaltstack = cross; then - usable_sigaltstack=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigaltstack = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" - fi - ;; - *) ;; - esac - - fi - dnl We sometimes need ETHR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ETHR_DEFS" - - dnl We need the thread library in order to find some functions - saved_libs="$LIBS" - LIBS="$LIBS $ETHR_X_LIBS" - - dnl - dnl Check for headers - dnl - AC_CHECK_HEADER(pthread.h, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - if test $NEED_NPTL_PTHREAD_H = yes; then - AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ -[Define if you need the <nptl/pthread.h> header file.]) - fi - - AC_CHECK_HEADER(sched.h, \ - AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ -[Define if you have the <sched.h> header file.])) - - AC_CHECK_HEADER(sys/time.h, \ - AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ -[Define if you have the <sys/time.h> header file.])) - - AC_TRY_COMPILE([#include <time.h> - #include <sys/time.h>], - [struct timeval *tv; return 0;], - AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ -[Define if you can safely include both <sys/time.h> and <time.h>.])) - - - dnl - dnl Check for functions - dnl - if test "x$THR_LIB_NAME" = "xpthread"; then - AC_CHECK_FUNC(pthread_spin_lock, \ - [ethr_have_native_spinlock=yes \ - AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ -[Define if you have the pthread_spin_lock function.])]) - - have_sched_yield=no - have_librt_sched_yield=no - AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) - if test $have_sched_yield = no; then - AC_CHECK_LIB(rt, sched_yield, - [have_librt_sched_yield=yes - ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) - fi - if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then - AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) - AC_MSG_CHECKING([whether sched_yield() returns an int]) - sched_yield_ret_int=no - AC_TRY_COMPILE([ - #ifdef ETHR_HAVE_SCHED_H - #include <sched.h> - #endif - ], - [int sched_yield();], - [sched_yield_ret_int=yes]) - AC_MSG_RESULT([$sched_yield_ret_int]) - if test $sched_yield_ret_int = yes; then - AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) - fi - fi - - have_pthread_yield=no - AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) - if test $have_pthread_yield = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) - AC_MSG_CHECKING([whether pthread_yield() returns an int]) - pthread_yield_ret_int=no - AC_TRY_COMPILE([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [int pthread_yield();], - [pthread_yield_ret_int=yes]) - AC_MSG_RESULT([$pthread_yield_ret_int]) - if test $pthread_yield_ret_int = yes; then - AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) - fi - fi - - have_pthread_rwlock_init=no - AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) - if test $have_pthread_rwlock_init = yes; then - - ethr_have_pthread_rwlockattr_setkind_np=no - AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, - [ethr_have_pthread_rwlockattr_setkind_np=yes]) - - if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ -[Define if you have the pthread_rwlockattr_setkind_np() function.]) - - AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) - ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no - AC_TRY_LINK([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [ - pthread_rwlockattr_t *attr; - return pthread_rwlockattr_setkind_np(attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - ], - [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) - AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) - if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ -[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) - fi - fi - fi - - if test "$force_pthread_rwlocks" = "yes"; then - - AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ -[Define if you want to force usage of pthread rwlocks]) - - if test $have_pthread_rwlock_init = yes; then - AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) - else - AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) - fi - fi - - AC_CHECK_FUNC(pthread_attr_setguardsize, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ -[Define if you have the pthread_attr_setguardsize function.])) - - linux_futex=no - AC_MSG_CHECKING([for Linux futexes]) - AC_TRY_LINK([ - #include <sys/syscall.h> - #include <unistd.h> - #include <linux/futex.h> - #include <sys/time.h> - ], - [ - int i = 1; - syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, - (void*)0,(void*)0, 0); - syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, - (void*)0,(void*)0, 0); - return 0; - ], - linux_futex=yes) - AC_MSG_RESULT([$linux_futex]) - test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) - - fi - - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int128_t) - - if test "$ac_cv_sizeof_int" = "4"; then - int32="int" - elif test "$ac_cv_sizeof_long" = "4"; then - int32="long" - elif test "$ac_cv_sizeof_long_long" = "4"; then - int32="long long" - else - AC_MSG_ERROR([No 32-bit type found]) - fi - - if test "$ac_cv_sizeof_int" = "8"; then - int64="int" - elif test "$ac_cv_sizeof_long" = "8"; then - int64="long" - elif test "$ac_cv_sizeof_long_long" = "8"; then - int64="long long" - else - AC_MSG_ERROR([No 64-bit type found]) - fi - - int128=no - if test "$ac_cv_sizeof___int128_t" = "16"; then - int128="__int128_t" - fi - - if test "X$disable_native_ethr_impls" = "Xyes"; then - ethr_have_native_atomics=no - else - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) - - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) - - if test $int128 != no; then - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) - fi - - AC_MSG_CHECKING([for a usable libatomic_ops implementation]) - case "x$with_libatomic_ops" in - xno | xyes | x) - libatomic_ops_include= - ;; - *) - if test -d "${with_libatomic_ops}/include"; then - libatomic_ops_include="-I$with_libatomic_ops/include" - CPPFLAGS="$CPPFLAGS $libatomic_ops_include" - else - AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) - fi;; - esac - ethr_have_libatomic_ops=no - AC_TRY_LINK([#include "atomic_ops.h"], - [ - volatile AO_t x; - AO_t y; - int z; - - AO_nop_full(); - AO_store(&x, (AO_t) 0); - z = AO_load(&x); - z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); - ], - [ethr_have_native_atomics=yes - ethr_have_libatomic_ops=yes]) - AC_MSG_RESULT([$ethr_have_libatomic_ops]) - if test $ethr_have_libatomic_ops = yes; then - AC_CHECK_SIZEOF(AO_t, , - [ - #include <stdio.h> - #include "atomic_ops.h" - ]) - AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) - - AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) - if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) - fi - ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" - elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_MSG_ERROR([No usable libatomic_ops implementation found]) - fi - - case "$host_cpu" in - sparc | sun4u | sparc64 | sun4v) - case "$with_sparc_memory_order" in - "TSO") - AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; - "PSO") - AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; - "RMO"|"") - AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; - *) - AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; - esac - ethr_have_native_atomics=yes;; - i86pc | i*86 | x86_64 | amd64) - if test "$enable_x86_out_of_order" = "yes"; then - AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) - fi - ethr_have_native_atomics=yes;; - macppc | ppc | powerpc | "Power Macintosh") - ethr_have_native_atomics=yes;; - tile) - ethr_have_native_atomics=yes;; - *) - ;; - esac - - fi - - test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes - - dnl Restore LIBS - LIBS=$saved_libs - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - ;; - *) - ;; -esac - -AC_MSG_CHECKING([whether default stack size should be modified]) -if test "x$ethr_modified_default_stack_size" != "x"; then - AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) - AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) -else - AC_MSG_RESULT([no]) -fi - -if test "x$ETHR_THR_LIB_BASE" != "x"; then - ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" - ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" - ETHR_LIB_NAME=$ethr_lib_name -fi - -AC_CHECK_SIZEOF(void *) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) - -AC_CHECK_SIZEOF(int) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) -AC_CHECK_SIZEOF(long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) -AC_CHECK_SIZEOF(long long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) -AC_CHECK_SIZEOF(__int64) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) -AC_CHECK_SIZEOF(__int128_t) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) - - -case X$erl_xcomp_bigendian in - X) ;; - Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; - *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; -esac - -AC_C_BIGENDIAN - -if test "$ac_cv_c_bigendian" = "yes"; then - AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) -fi - -case X$erl_xcomp_double_middle_endian in - X) ;; - Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;; - *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);; -esac - -AC_C_DOUBLE_MIDDLE_ENDIAN - -ETHR_X86_SSE2_ASM=no -case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in - yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) - AC_MSG_CHECKING([for gcc sse2 asm support]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -msse2" - gcc_sse2_asm=no - AC_TRY_COMPILE([], - [ - long long x, *y; - __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); - ], - [gcc_sse2_asm=yes]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$gcc_sse2_asm]) - if test "$gcc_sse2_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) - ETHR_X86_SSE2_ASM=yes - fi - ;; - *) - ;; -esac - -case "$GCC-$host_cpu" in - yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) - gcc_dw_cmpxchg_asm=no - AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; - __asm__ __volatile__( -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "pushl %%ebx\n\t" - "movl %8, %%ebx\n\t" -#endif -#if ETHR_SIZEOF_PTR == 4 - "lock; cmpxchg8b %0\n\t" -#else - "lock; cmpxchg16b %0\n\t" -#endif - "setz %3\n\t" -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "popl %%ebx\n\t" -#endif - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "r"(new[0]) -#else - "b"(new[0]) -#endif - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; -#if !defined(__PIC__) || !__PIC__ -# error nope -#endif - __asm__ __volatile__( - "pushl %%ebx\n\t" - "movl (%7), %%ebx\n\t" - "movl 4(%7), %%ecx\n\t" - "lock; cmpxchg8b %0\n\t" - "setz %3\n\t" - "popl %%ebx\n\t" - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) - fi - fi - AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) - fi;; - *) - ;; -esac - -AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ -[Define if you have all ethread defines]) - -AC_SUBST(ETHR_X_LIBS) -AC_SUBST(ETHR_LIBS) -AC_SUBST(ETHR_LIB_NAME) -AC_SUBST(ETHR_DEFS) -AC_SUBST(ETHR_THR_LIB_BASE) -AC_SUBST(ETHR_THR_LIB_BASE_DIR) -AC_SUBST(ETHR_X86_SSE2_ASM) - -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_TIME_CORRECTION -dnl -dnl In the presence of a high resolution realtime timer Erlang can adapt -dnl its view of time relative to this timer. On solaris such a timer is -dnl available with the syscall gethrtime(). On other OS's a fallback -dnl solution using times() is implemented. (However on e.g. FreeBSD times() -dnl is implemented using gettimeofday so it doesn't make much sense to -dnl use it there...) On second thought, it seems to be safer to do it the -dnl other way around. I.e. only use times() on OS's where we know it will -dnl work... -dnl - -AC_DEFUN(ERL_TIME_CORRECTION, -[if test x$ac_cv_func_gethrtime = x; then - AC_CHECK_FUNC(gethrtime) -fi -if test x$clock_gettime_correction = xunknown; then - AC_TRY_COMPILE([#include <time.h>], - [struct timespec ts; - long long result; - clock_gettime(CLOCK_MONOTONIC,&ts); - result = ((long long) ts.tv_sec) * 1000000000LL + - ((long long) ts.tv_nsec);], - clock_gettime_compiles=yes, - clock_gettime_compiles=no) -else - clock_gettime_compiles=no -fi - - -AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, -[ -case $clock_gettime_correction in - yes) - erl_cv_time_correction=clock_gettime;; - no|unknown) - case $ac_cv_func_gethrtime in - yes) - erl_cv_time_correction=hrtime ;; - no) - case $host_os in - linux*) - case $clock_gettime_correction in - unknown) - if test x$clock_gettime_compiles = xyes; then - if test X$cross_compiling != Xyes; then - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) - erl_cv_time_correction=times ;; - *) - erl_cv_time_correction=clock_gettime;; - esac - else - case X$erl_xcomp_linux_clock_gettime_correction in - X) - erl_cv_time_correction=cross;; - Xyes|Xno) - if test $erl_xcomp_linux_clock_gettime_correction = yes; then - erl_cv_time_correction=clock_gettime - else - erl_cv_time_correction=times - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; - esac - fi - else - erl_cv_time_correction=times - fi - ;; - *) - erl_cv_time_correction=times ;; - esac - ;; - *) - erl_cv_time_correction=none ;; - esac - ;; - esac - ;; -esac -]) - -xrtlib="" -case $erl_cv_time_correction in - times) - AC_DEFINE(CORRECT_USING_TIMES,[], - [Define if you do not have a high-res. timer & want to use times() instead]) - ;; - clock_gettime|cross) - if test $erl_cv_time_correction = cross; then - erl_cv_time_correction=clock_gettime - AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) - fi - xrtlib="-lrt" - AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], - [Define if you want to use clock_gettime to simulate gethrtime]) - ;; -esac -dnl -dnl Check if gethrvtime is working, and if to use procfs ioctl -dnl or (yet to be written) write to the procfs ctl file. -dnl - -AC_MSG_CHECKING([if gethrvtime works and how to use it]) -AC_TRY_RUN([ -/* gethrvtime procfs ioctl test */ -/* These need to be undef:ed to not break activation of - * micro level process accounting on /proc/self - */ -#ifdef _LARGEFILE_SOURCE -# undef _LARGEFILE_SOURCE -#endif -#ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -#endif -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/signal.h> -#include <sys/fault.h> -#include <sys/syscall.h> -#include <sys/procfs.h> -#include <fcntl.h> - -int main() { - long msacct = PR_MSACCT; - int fd; - long long start, stop; - int i; - pid_t pid = getpid(); - char proc_self[30] = "/proc/"; - - sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); - if ( (fd = open(proc_self, O_WRONLY)) == -1) - exit(1); - if (ioctl(fd, PIOCSET, &msacct) < 0) - exit(2); - if (close(fd) < 0) - exit(3); - start = gethrvtime(); - for (i = 0; i < 100; i++) - stop = gethrvtime(); - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; -} -], -erl_gethrvtime=procfs_ioctl, -erl_gethrvtime=false, -[ -case X$erl_xcomp_gethrvtime_procfs_ioctl in - X) - erl_gethrvtime=cross;; - Xyes|Xno) - if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then - erl_gethrvtime=procfs_ioctl - else - erl_gethrvtime=false - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; -esac -]) - -case $erl_gethrvtime in - procfs_ioctl) - AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], - [define if gethrvtime() works and uses ioctl() to /proc/self]) - AC_MSG_RESULT(uses ioctl to procfs) - ;; - *) - if test $erl_gethrvtime = cross; then - erl_gethrvtime=false - AC_MSG_RESULT(cross) - AC_MSG_WARN([result 'not working' guessed because of cross compilation]) - else - AC_MSG_RESULT(not working) - fi - - dnl - dnl Check if clock_gettime (linux) is working - dnl - - AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) - save_libs=$LIBS - LIBS="-lrt" - AC_TRY_RUN([ - #include <stdlib.h> - #include <unistd.h> - #include <string.h> - #include <stdio.h> - #include <time.h> - int main() { - long long start, stop; - int i; - struct timespec tp; - - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) - exit(1); - start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - for (i = 0; i < 100; i++) - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); - stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; - } - ], - erl_clock_gettime=yes, - erl_clock_gettime=no, - [ - case X$erl_xcomp_clock_gettime_cpu_time in - X) erl_clock_gettime=cross;; - Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; - *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; - esac - ]) - LIBS=$save_libs - case $host_os in - linux*) - AC_MSG_RESULT([no; not stable]) - LIBRT=$xrtlib - ;; - *) - AC_MSG_RESULT($erl_clock_gettime) - case $erl_clock_gettime in - yes) - AC_DEFINE(HAVE_CLOCK_GETTIME,[], - [define if clock_gettime() works for getting process time]) - LIBRT=-lrt - ;; - cross) - erl_clock_gettime=no - AC_MSG_WARN([result no guessed because of cross compilation]) - LIBRT=$xrtlib - ;; - *) - LIBRT=$xrtlib - ;; - esac - ;; - esac - AC_SUBST(LIBRT) - ;; -esac -])dnl - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_TRY_ENABLE_CFLAG -dnl -dnl -dnl Tries a CFLAG and sees if it can be enabled without compiler errors -dnl $1: textual cflag to add -dnl $2: variable to store the modified CFLAG in -dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS]) -dnl -dnl -AC_DEFUN([LM_TRY_ENABLE_CFLAG], [ - AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)]) - saved_CFLAGS=$CFLAGS; - CFLAGS="$1 $$2"; - AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false) - CFLAGS=$saved_CFLAGS; - if test "X$can_enable_flag" = "Xtrue"; then - AC_MSG_RESULT([yes]) - AS_VAR_SET($2, "$1 $$2") - else - AC_MSG_RESULT([no]) - fi -]) - -dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY -dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a -dnl AC_LANG_JAVA instead...) -AC_DEFUN(ERL_TRY_LINK_JAVA, -[java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(, )dnl -cat > conftest.java <<EOF -$1 -class conftest { public static void main(String[] args) { - $2 - ; return; }} -EOF -changequote([, ])dnl -if AC_TRY_EVAL(java_link) && test -s conftest.class; then - ifelse([$3], , :, [rm -rf conftest* - $3]) -else - echo "configure: failed program was:" 1>&AC_FD_CC - cat conftest.java 1>&AC_FD_CC - echo "configure: PATH was $PATH" 1>&AC_FD_CC -ifelse([$4], , , [ rm -rf conftest* - $4 -])dnl -fi -rm -f conftest*]) -#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ - - diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml index 9a260c3878..fd654af051 100644 --- a/lib/megaco/doc/src/notes.xml +++ b/lib/megaco/doc/src/notes.xml @@ -36,7 +36,24 @@ section is the version number of Megaco.</p> - <section><title>Megaco 3.17.2</title> + <section><title>Megaco 3.17.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + </list> + </section> + +</section> + +<section><title>Megaco 3.17.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src index a3a2e2ea9c..92504e8e87 100644 --- a/lib/megaco/src/app/megaco.appup.src +++ b/lib/megaco/src/app/megaco.appup.src @@ -180,11 +180,15 @@ %% | %% v %% 3.17.2 +%% | +%% v +%% 3.17.3 %% %% {"%VSN%", [ + {"3.17.2", []}, {"3.17.1", [{restart_application,megaco}]}, {"3.17.0.3", [{restart_application,megaco}]}, {"3.17.0.2", []}, @@ -198,6 +202,7 @@ } ], [ + {"3.17.2", []}, {"3.17.1", [{restart_application,megaco}]}, {"3.17.0.3", [{restart_application,megaco}]}, {"3.17.0.2", []}, diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index 1f4e3b8e95..8687d622e9 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = megaco -MEGACO_VSN = 3.17.2 +MEGACO_VSN = 3.17.3 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xml b/lib/mnesia/doc/src/Mnesia_chap3.xml index d6b4a1c6a1..ae704b4199 100644 --- a/lib/mnesia/doc/src/Mnesia_chap3.xml +++ b/lib/mnesia/doc/src/Mnesia_chap3.xml @@ -152,7 +152,7 @@ Transformer = <c>ignore</c>, it indicates that only the meta data about the table will be updated. Usage of <c>ignore</c> is not recommended (since it creates inconsistencies between the meta data and the actual data) but included - as a possibility for the user do to his own (off-line) transform.</p> + as a possibility for the user to do his own (off-line) transform.</p> </item> <item><c>change_table_copy_type(Tab, Node, ToType)</c>. This function changes the storage type of a table. For example, a diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc index 65b950bd46..127c23e0f7 100644 --- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc +++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc @@ -867,6 +867,7 @@ ok </section> <section> + <marker id="event_handling"></marker> <title>Mnesia Event Handling</title> <p>System events and table events are the two categories of events that Mnesia will generate in various situations. diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml index 72e9bd7e8f..ed5b879f7f 100644 --- a/lib/mnesia/doc/src/mnesia.xml +++ b/lib/mnesia/doc/src/mnesia.xml @@ -151,9 +151,9 @@ If a new item is inserted with the same key as </item> <item> <p><c>local_content</c> When an application requires - tables whose contents is local to each node, + tables whose contents are local to each node, <c>local_content</c> tables may be used. The name of the - table is known to all Mnesia nodes, but its contents is + table is known to all Mnesia nodes, but its contents are unique on each node. This means that access to such a table must be done locally. Set the <c>local_content</c> field to <c>true</c> if you want to enable the <c>local_content</c> @@ -579,7 +579,7 @@ mnesia:add_table_index(person, age) <desc> <p>The tables are backed up to external media using the backup module <c>BackupMod</c>. Tables with the local contents - property is being backed up as they exist on the current + property are backed up as they exist on the current node. <c>BackupMod</c> is the default backup callback module obtained by <c>mnesia:system_info(backup_module)</c>. See the User's @@ -863,7 +863,7 @@ mnesia:create_table(person, {attributes, record_info(fields,person)}]). </code> <p>The specification of <c>index</c> and <c>attributes</c> may be - hard coded as <c>{index, [2]}</c> and + hard coded as <c>{index, [4]}</c> and <c>{attributes, [name, age, address, salary, children]}</c> respectively. </p> @@ -2188,12 +2188,13 @@ mnesia:create_table(employee, </desc> </func> <func> - <name>subscribe(EventCategory)</name> + <name>subscribe(EventCategory) -> {ok, Node} | {error, Reason} </name> <fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary> <desc> <p>Ensures that a copy of all events of type <c>EventCategory</c> are sent to the caller. The event - types available are described in the Mnesia User's Guide.</p> + types available are described in the Mnesia User's Guide at <seealso marker="Mnesia_chap5#event_handling">Mnesia Event Handling</seealso>.</p> + <p><c>Node</c> is the local node. For table events to be subscribed, mnesia must have a readable local copy of the table on the node.</p> </desc> </func> <func> @@ -2766,7 +2767,7 @@ raise(Name, Amount) -> new type. The <c>Fun</c> argument can also be the atom <c>ignore</c>, it indicates that only the meta data about the table will be updated. Usage of <c>ignore</c> is not recommended but included - as a possibility for the user do to his own transform. + as a possibility for the user to do his own transform. <c>NewAttributeList</c> and <c>NewRecordName</c> specifies the attributes and the new record type of converted table. Table name will always remain unchanged, if the @@ -2861,11 +2862,12 @@ raise(Name, Amount) -> </desc> </func> <func> - <name>unsubscribe(EventCategory)</name> + <name>unsubscribe(EventCategory) -> {ok, Node} | {error, Reason} </name> <fsummary>Subscribe to events of type <c>EventCategory</c>.</fsummary> <desc> <p>Stops sending events of type <c>EventCategory</c> to the caller.</p> + <p><c>Node</c> is the local node.</p> </desc> </func> <func> diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index e5c7d87f52..18f72f4faf 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -38,7 +38,30 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.12.3</title> + <section><title>Mnesia 4.12.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a spelling mistake in mnesia documentation.</p> + <p> + Own Id: OTP-12278</p> + </item> + <item> + <p> + Matching data with <c>mnesia:match_object/1</c> did not + work as expected in some cases, when data was written in + the same transaction before the matching was invoked.</p> + <p> + Own Id: OTP-12304 Aux Id: Seq12745 </p> + </item> + </list> + </section> + +</section> + +<section><title>Mnesia 4.12.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index b7d80c1370..8f14831ad3 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -1140,10 +1140,12 @@ match_object(_Tid, _Ts, Tab, Pat, _LockKind) -> add_written_match(S, Pat, Tab, Objs) -> Ops = find_ops(S, Tab, Pat), - add_match(Ops, Objs, val({Tab, setorbag})). + FixedRes = add_match(Ops, Objs, val({Tab, setorbag})), + MS = ets:match_spec_compile([{Pat, [], ['$_']}]), + ets:match_spec_run(FixedRes, MS). find_ops(S, Tab, Pat) -> - GetWritten = [{{{Tab, '_'}, Pat, write}, [], ['$_']}, + GetWritten = [{{{Tab, '_'}, '_', write}, [], ['$_']}, {{{Tab, '_'}, '_', delete}, [], ['$_']}, {{{Tab, '_'}, Pat, delete_object}, [], ['$_']}], ets:select(S, GetWritten). diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl index b6492707e2..eeb4fa0ced 100644 --- a/lib/mnesia/src/mnesia_recover.erl +++ b/lib/mnesia/src/mnesia_recover.erl @@ -689,12 +689,29 @@ handle_call({connect_nodes, Ns}, From, State) -> %% called from handle_info gen_server:reply(From, {[], AlreadyConnected}), {noreply, State}; - GoodNodes -> + ProbablyGoodNodes -> %% Now we have agreed upon a protocol with some new nodes - %% and we may use them when we recover transactions + %% and we may use them when we recover transactions. + %% + %% Just in case Mnesia was stopped on some of those nodes + %% between the protocol negotiation and now, we check one + %% more time the state of Mnesia. + %% + %% Of course, there is still a chance that mnesia_down + %% events occur during this check and we miss them. To + %% prevent it, handle_cast({mnesia_down, ...}, ...) removes + %% the down node again, in addition to mnesia_down/1. + %% + %% See a comment in handle_cast({mnesia_down, ...}, ...). + Verify = fun(N) -> + Run = mnesia_lib:is_running(N), + Run =:= yes orelse Run =:= starting + end, + GoodNodes = [N || N <- ProbablyGoodNodes, Verify(N)], + mnesia_lib:add_list(recover_nodes, GoodNodes), cast({announce_all, GoodNodes}), - case get_master_nodes(schema) of + case get_master_nodes(schema) of [] -> Context = starting_partitioned_network, mnesia_monitor:detect_inconcistency(GoodNodes, Context); @@ -842,6 +859,14 @@ handle_cast({what_decision, Node, OtherD}, State) -> {noreply, State}; handle_cast({mnesia_down, Node}, State) -> + %% The node was already removed from recover_nodes in mnesia_down/1, + %% but we do it again here in the mnesia_recover process, in case + %% another event incorrectly added it back. This can happen during + %% Mnesia startup which takes time betweenthe connection, the + %% protocol negotiation and the merge of the schema. + %% + %% See a comment in handle_call({connect_nodes, ...), ...). + mnesia_lib:del(recover_nodes, Node), case State#state.unclear_decision of undefined -> {noreply, State}; diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl index 9272211ad2..866a57e370 100644 --- a/lib/mnesia/src/mnesia_subscr.erl +++ b/lib/mnesia/src/mnesia_subscr.erl @@ -225,7 +225,7 @@ call(Msg) -> Res = gen_server:call(Pid, Msg, infinity), %% We get an exit signal if server dies receive - {'EXIT', _Pid, _Reason} -> + {'EXIT', Pid, _Reason} -> {error, {node_not_running, node()}} after 0 -> Res diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl index d57f976d1f..8468472cf2 100644 --- a/lib/mnesia/test/mnesia_isolation_test.erl +++ b/lib/mnesia/test/mnesia_isolation_test.erl @@ -1584,7 +1584,8 @@ write_shadows(Config) when is_list(Config) -> ?match([RecA2], mnesia:read({Tab, a})), ?match([RecA2], mnesia:wread({Tab, a})), - ?match([RecA2], mnesia:match_object(PatA2)), %% delete shadow old but not new write - is the new value visable + ?match([], mnesia:match_object(PatA1)), %% delete shadow old but not new write + ?match([RecA2], mnesia:match_object(PatA2)), %% is the new value visable ?match([a], mnesia:all_keys(Tab)), ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)), @@ -1643,6 +1644,7 @@ delete_shadows(Config) when is_list(Config) -> ?match([RecA2], mnesia:read({Tab, a})), ?match([RecA2], mnesia:wread({Tab, a})), + ?match([], mnesia:match_object(PatA1)), ?match([RecA2], mnesia:match_object(PatA2)), ?match([a], mnesia:all_keys(Tab)), ?match([RecA2], mnesia:index_match_object(PatA2, ValPos)), diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index d5b96c5c76..94eb360591 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.12.3 +MNESIA_VSN = 4.12.4 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index 658ac2c7cf..11729078c2 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -31,6 +31,22 @@ <p>This document describes the changes made to the Observer application.</p> +<section><title>Observer 2.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A note saying only R15B nodes can be observed is removed + from the user guide.</p> + <p> + Own Id: OTP-12078</p> + </item> + </list> + </section> + +</section> + <section><title>Observer 2.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index dbbbde1467..c8a6023b4f 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 2.0.2 +OBSERVER_VSN = 2.0.3 diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4 deleted file mode 100644 index ed492d55ff..0000000000 --- a/lib/odbc/aclocal.m4 +++ /dev/null @@ -1,1954 +0,0 @@ -dnl -dnl %CopyrightBegin% -dnl -dnl Copyright Ericsson AB 1998-2013. 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 - -AC_DEFUN(LM_PRECIOUS_VARS, -[ - -dnl ERL_TOP -AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) - -dnl Tools -AC_ARG_VAR(CC, [C compiler]) -AC_ARG_VAR(CFLAGS, [C compiler flags]) -AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) -AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) -AC_ARG_VAR(CPP, [C/C++ preprocessor]) -AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) -AC_ARG_VAR(CXX, [C++ compiler]) -AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) -AC_ARG_VAR(LD, [linker (is often overridden by configure)]) -AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) -AC_ARG_VAR(LIBS, [libraries]) -AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) -AC_ARG_VAR(RANLIB, [ranlib]) -AC_ARG_VAR(AR, [ar]) -AC_ARG_VAR(GETCONF, [getconf]) - -dnl Cross system root -AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) - -dnl Cross compilation variables -AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) - -dnl Cross compilation variables for OSE -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file]) -AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) - -]) - -AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, -[ -erl_xcomp_without_sysroot=no -if test "$cross_compiling" = "yes"; then - test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes - test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" -else - erl_xcomp_sysroot= - erl_xcomp_isysroot= -fi -]) - -AC_DEFUN(LM_CHECK_GETCONF, -[ -if test "$cross_compiling" != "yes"; then - AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) -else - dnl First check if we got a `<HOST>-getconf' in $PATH - host_getconf="$host_alias-getconf" - AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) - if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then - dnl We should perhaps give up if we have'nt found it by now, but at - dnl least in one Tilera MDE `getconf' under sysroot is a bourne - dnl shell script which we can use. We try to find `<HOST>-getconf' - dnl or `getconf' under sysconf, but only under sysconf since - dnl `getconf' in $PATH is almost guaranteed to be for the build - dnl machine. - GETCONF= - prfx="$erl_xcomp_sysroot" - AC_PATH_TOOL([GETCONF], [getconf], [false], - ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) - fi -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_WINDOWS_ENVIRONMENT -dnl -dnl -dnl Tries to determine thw windows build environment, i.e. -dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC -dnl - -AC_DEFUN(LM_WINDOWS_ENVIRONMENT, -[ -MIXED_CYGWIN=no -MIXED_MSYS=no - -AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) -if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([Cygwin and VC]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - elif test -x /usr/bin/msysinfo; then - CFLAGS="-O2" - MIXED_MSYS=yes - AC_MSG_RESULT([MSYS and VC]) - MIXED_MSYS_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no - MIXED_MSYS_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) -AC_SUBST(MIXED_MSYS_VC) - -MIXED_VC=no -if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then - MIXED_VC=yes -fi - -AC_SUBST(MIXED_VC) - -if test "x$MIXED_MSYS" != "xyes"; then - AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) - if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi - else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no - fi -else - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) - -AC_MSG_CHECKING(if we mix msys with another native compiler) -if test "X$MIXED_MSYS" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_MSYS) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_FIND_EMU_CC -dnl -dnl -dnl Tries fairly hard to find a C compiler that can handle jump tables. -dnl Defines the @EMU_CC@ variable for the makefiles and -dnl inserts NO_JUMP_TABLE in the header if one cannot be found... -dnl - -AC_DEFUN(LM_FIND_EMU_CC, - [AC_CACHE_CHECK(for a compiler that handles jumptables, - ac_cv_prog_emu_cc, - [ -AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; -lbl1: - return 1; -lbl2: - return 2; -],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - -if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc-4.2 gcc; do - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_progname; then - ac_cv_prog_emu_cc=$ac_dir/$ac_progname - break - fi - done - IFS="$ac_save_ifs" - if test $ac_cv_prog_emu_cc != no; then - break - fi - done -fi - -if test $ac_cv_prog_emu_cc != no; then - save_CC=$CC - save_CFLAGS=$CFLAGS - save_CPPFLAGS=$CPPFLAGS - CC=$ac_cv_prog_emu_cc - CFLAGS="" - CPPFLAGS="" - AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; - lbl1: - return 1; - lbl2: - return 2; - ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - CC=$save_CC - CFLAGS=$save_CFLAGS - CPPFLAGS=$save_CPPFLAGS -fi -]) -if test $ac_cv_prog_emu_cc = no; then - AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) - EMU_CC=$CC -else - EMU_CC=$ac_cv_prog_emu_cc -fi -AC_SUBST(EMU_CC) -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_INSTALL_DIR -dnl -dnl This macro may be used by any OTP application. -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 -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_PERL5 -dnl -dnl Try to find perl version 5. If found set PERL to the absolute path -dnl of the program, if not found set PERL to false. -dnl -dnl On some systems /usr/bin/perl is perl 4 and e.g. -dnl /usr/local/bin/perl is perl 5. We try to handle this case by -dnl putting a couple of -dnl Tries to handle the case that there are two programs called perl -dnl in the path and one of them is perl 5 and the other isn't. -dnl -AC_DEFUN(LM_PROG_PERL5, -[AC_PATH_PROGS(PERL, perl5 perl, false, - /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) -changequote(, )dnl -dnl[ That bracket is needed to balance the right bracket below -if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then -changequote([, ])dnl - ac_cv_path_PERL=false - PERL=false -dnl AC_MSG_WARN(perl version 5 not found) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SO_BSDCOMPAT -dnl -dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) -dnl -AC_DEFUN(LM_DECL_SO_BSDCOMPAT, -[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, -AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], - ac_cv_decl_so_bsdcompat=yes, - ac_cv_decl_so_bsdcompat=no)) - -case "${ac_cv_decl_so_bsdcompat}" in - "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], - [Define if you have SO_BSDCOMPAT flag on sockets]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_INADDR_LOOPBACK -dnl -dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default -dnl - -AC_DEFUN(LM_DECL_INADDR_LOOPBACK, -[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], - ac_cv_decl_inaddr_loopback, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], -ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) -]) - -if test ${ac_cv_decl_inaddr_loopback} = no; then - AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], - ac_cv_decl_inaddr_loopback_rpc, - AC_TRY_COMPILE([#include <rpc/types.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_rpc=yes, - ac_cv_decl_inaddr_loopback_rpc=no)) - - case "${ac_cv_decl_inaddr_loopback_rpc}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], - [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; - * ) - AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], - ac_cv_decl_inaddr_loopback_winsock2, - AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN - #include <winsock2.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_winsock2=yes, - ac_cv_decl_inaddr_loopback_winsock2=no)) - case "${ac_cv_decl_inaddr_loopback_winsock2}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], - [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; - * ) - # couldn't find it anywhere - AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], - [Define if you don't have a definition of INADDR_LOOPBACK]) ;; - esac;; - esac -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_SOCKADDR_SA_LEN -dnl -dnl Check if the sockaddr structure has the field sa_len -dnl - -AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, -[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], - ac_cv_struct_sockaddr_sa_len, -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], - ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) - -dnl FIXME convbreak -case ${ac_cv_struct_sockaddr_sa_len} in - "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; - *) ;; -esac -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_EXCEPTION -dnl -dnl Check to see whether the system supports the matherr function -dnl and its associated type "struct exception". -dnl - -AC_DEFUN(LM_STRUCT_EXCEPTION, -[AC_CACHE_CHECK([for struct exception (and matherr function)], - ac_cv_struct_exception, -AC_TRY_COMPILE([#include <math.h>], - [struct exception x; x.type = DOMAIN; x.type = SING;], - ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) - -case "${ac_cv_struct_exception}" in - "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_IPV6 -dnl -dnl Check for ipv6 support and what the in6_addr structure is called. -dnl (early linux used in_addr6 insted of in6_addr) -dnl - -AC_DEFUN(LM_SYS_IPV6, -[AC_MSG_CHECKING(for IP version 6 support) -AC_CACHE_VAL(ac_cv_sys_ipv6_support, -[ok_so_far=yes - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) - -if test $ok_so_far = yes; then - ac_cv_sys_ipv6_support=yes -else - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in_addr6 a6; struct sockaddr_in6 s6;], - ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) -fi -])dnl - -dnl -dnl Have to use old style AC_DEFINE due to BC with old autoconf. -dnl - -case ${ac_cv_sys_ipv6_support} in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - ;; - in_addr6) - AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) - ;; - *) - AC_MSG_RESULT(no) - ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_MULTICAST -dnl -dnl Check for multicast support. Only checks for multicast options in -dnl setsockopt(), no check is performed that multicasting actually works. -dnl If options are found defines HAVE_MULTICAST_SUPPORT -dnl - -AC_DEFUN(LM_SYS_MULTICAST, -[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, -[AC_EGREP_CPP(yes, -[#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) -yes -#endif -], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) -if test $ac_cv_sys_multicast_support = yes; then - AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], - [Define if setsockopt() accepts multicast options]) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SYS_ERRLIST -dnl -dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared -dnl in a system header file, stdio.h or errno.h. -dnl - -AC_DEFUN(LM_DECL_SYS_ERRLIST, -[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], - ac_cv_decl_sys_errlist, -[AC_TRY_COMPILE([#include <stdio.h> -#include <errno.h>], [char *msg = *(sys_errlist + 1);], - ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) -if test $ac_cv_decl_sys_errlist = yes; then - AC_DEFINE(SYS_ERRLIST_DECLARED,[], - [define if the variable sys_errlist is declared in a system header file]) -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes -dnl [, action-if-found [, action-if-not-found]]] ) -dnl -dnl Checks if the declaration "declaration" of "funname" conflicts -dnl with the header files idea of how the function should be -dnl declared. It is useful on systems which lack prototypes and you -dnl need to provide your own (e.g. when you want to take the address -dnl of a function). The 4'th argument is expanded if conflicting, -dnl the 5'th argument otherwise -dnl -dnl - -AC_DEFUN(LM_CHECK_FUNC_DECL, -[AC_MSG_CHECKING([for conflicting declaration of $1]) -AC_CACHE_VAL(ac_cv_func_decl_$1, -[AC_TRY_COMPILE([#include <stdio.h> -$3],[$2 -char *c = (char *)$1; -], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) -if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then - AC_MSG_RESULT(yes) - ifelse([$4], , :, [$4]) -else - AC_MSG_RESULT(no) -ifelse([$5], , , [$5 -])dnl -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl AC_DOUBLE_MIDDLE_ENDIAN -dnl -dnl Checks whether doubles are represented in "middle-endian" format. -dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly, -dnl as well as DOUBLE_MIDDLE_ENDIAN. -dnl -dnl - -AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN], -[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian, -[# It does not; compile a test program. -AC_RUN_IFELSE( -[AC_LANG_SOURCE([[#include <stdlib.h> - -int -main(void) -{ - int i = 0; - int zero = 0; - int bigendian; - int zero_index = 0; - - union - { - long int l; - char c[sizeof (long int)]; - } u; - - /* we'll use the one with 32-bit words */ - union - { - double d; - unsigned int c[2]; - } vint; - - union - { - double d; - unsigned long c[2]; - } vlong; - - union - { - double d; - unsigned short c[2]; - } vshort; - - - /* Are we little or big endian? From Harbison&Steele. */ - u.l = 1; - bigendian = (u.c[sizeof (long int) - 1] == 1); - - zero_index = bigendian ? 1 : 0; - - vint.d = 1.0; - vlong.d = 1.0; - vshort.d = 1.0; - - if (sizeof(unsigned int) == 4) - { - if (vint.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned long) == 4) - { - if (vlong.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned short) == 4) - { - if (vshort.c[zero_index] != 0) - zero = 1; - } - - exit (zero); -} -]])], - [ac_cv_c_double_middle_endian=no], - [ac_cv_c_double_middle_endian=yes], - [ac_cv_c_double_middle=unknown])]) -case $ac_cv_c_double_middle_endian in - yes) - m4_default([$1], - [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1, - [Define to 1 if your processor stores the words in a double in - middle-endian format (like some ARMs).])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_WARN([unknown double endianness -presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;; -esac -])# AC_C_DOUBLE_MIDDLE_ENDIAN - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_THR_LIB -dnl -dnl This macro may be used by any OTP application. -dnl -dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also -dnl checks for some pthread headers which will appear in DEFS or config.h. -dnl - -AC_DEFUN(LM_CHECK_THR_LIB, -[ - -NEED_NPTL_PTHREAD_H=no - -dnl win32? -AC_MSG_CHECKING([for native win32 threads]) -if test "X$host_os" = "Xwin32"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DWIN32_THREADS" - THR_LIBS= - THR_LIB_NAME=win32_threads - THR_LIB_TYPE=win32_threads -elif test "X$host_os" = "Xose"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DOSE_THREADS" - THR_LIBS= - THR_LIB_NAME=ose_threads - THR_LIB_TYPE=ose_threads -else - AC_MSG_RESULT(no) - THR_DEFS= - THR_LIBS= - THR_LIB_NAME= - THR_LIB_TYPE=posix_unknown - -dnl Try to find POSIX threads - -dnl The usual pthread lib... - AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") - -dnl Very old versions of FreeBSD have pthreads in special c library, c_r... - if test "x$THR_LIBS" = "x"; then - AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") - fi - -dnl QNX has pthreads in standard C library - if test "x$THR_LIBS" = "x"; then - AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed") - fi - -dnl On ofs1 the '-pthread' switch should be used - if test "x$THR_LIBS" = "x"; then - AC_MSG_CHECKING([if the '-pthread' switch can be used]) - saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -pthread" - AC_TRY_LINK([#include <pthread.h>], - pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, - [THR_DEFS="-pthread" - THR_LIBS="-pthread"]) - CFLAGS=$saved_cflags - if test "x$THR_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - fi - - if test "x$THR_LIBS" != "x"; then - THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" - THR_LIB_NAME=pthread - if test "x$THR_LIBS" = "xnone_needed"; then - THR_LIBS= - fi - case $host_os in - solaris*) - THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; - linux*) - THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" - - LM_CHECK_GETCONF - AC_MSG_CHECKING(for Native POSIX Thread Library) - libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` - if test $? -eq 0; then - case "$libpthr_vsn" in - *nptl*|*NPTL*) nptl=yes;; - *) nptl=no;; - esac - elif test "$cross_compiling" = "yes"; then - case "$erl_xcomp_linux_nptl" in - "") nptl=cross;; - yes|no) nptl=$erl_xcomp_linux_nptl;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; - esac - else - nptl=no - fi - AC_MSG_RESULT($nptl) - if test $nptl = cross; then - nptl=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $nptl = yes; then - THR_LIB_TYPE=posix_nptl - need_nptl_incldir=no - AC_CHECK_HEADER(nptl/pthread.h, - [need_nptl_incldir=yes - NEED_NPTL_PTHREAD_H=yes]) - if test $need_nptl_incldir = yes; then - # Ahh... - nptl_path="$C_INCLUDE_PATH:$CPATH" - if test X$cross_compiling != Xyes; then - nptl_path="$nptl_path:/usr/local/include:/usr/include" - else - IROOT="$erl_xcomp_isysroot" - test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" - test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) - nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" - fi - nptl_ws_path= - save_ifs="$IFS"; IFS=":" - for dir in $nptl_path; do - if test "x$dir" != "x"; then - nptl_ws_path="$nptl_ws_path $dir" - fi - done - IFS=$save_ifs - nptl_incldir= - for dir in $nptl_ws_path; do - AC_CHECK_HEADER($dir/nptl/pthread.h, - nptl_incldir=$dir/nptl) - if test "x$nptl_incldir" != "x"; then - THR_DEFS="$THR_DEFS -isystem $nptl_incldir" - break - fi - done - if test "x$nptl_incldir" = "x"; then - AC_MSG_ERROR(Failed to locate nptl system include directory) - fi - fi - fi - ;; - *) ;; - esac - - dnl We sometimes need THR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $THR_DEFS" - - dnl - dnl Check for headers - dnl - - AC_CHECK_HEADER(pthread.h, - AC_DEFINE(HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - fi -fi - -]) - -AC_DEFUN(ERL_INTERNAL_LIBS, -[ - -ERTS_INTERNAL_X_LIBS= - -AC_CHECK_LIB(kstat, kstat_open, -[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) -ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) - -AC_SUBST(ERTS_INTERNAL_X_LIBS) - -]) - -AC_DEFUN(ETHR_CHK_SYNC_OP, -[ - AC_MSG_CHECKING([for $3-bit $1()]) - case "$2" in - "1") sync_call="$1(&var);";; - "2") sync_call="$1(&var, ($4) 0);";; - "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; - esac - have_sync_op=no - AC_TRY_LINK([], - [ - $4 res; - volatile $4 var; - res = $sync_call - ], - [have_sync_op=yes]) - test $have_sync_op = yes && $5 - AC_MSG_RESULT([$have_sync_op]) -]) - -AC_DEFUN(ETHR_CHK_INTERLOCKED, -[ - ilckd="$1" - AC_MSG_CHECKING([for ${ilckd}()]) - case "$2" in - "1") ilckd_call="${ilckd}(var);";; - "2") ilckd_call="${ilckd}(var, ($3) 0);";; - "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; - "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; - esac - have_interlocked_op=no - AC_TRY_LINK( - [ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <intrin.h> - ], - [ - volatile $3 *var; - volatile $3 arr[2]; - - $ilckd_call - return 0; - ], - [have_interlocked_op=yes]) - test $have_interlocked_op = yes && $4 - AC_MSG_RESULT([$have_interlocked_op]) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_FIND_ETHR_LIB -dnl -dnl NOTE! This macro may be changed at any time! Should *only* be used by -dnl ERTS! -dnl -dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link -dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS -dnl except that the ethread lib itself is not included), ETHR_DEFS to -dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the -dnl thread library which the ethread library is based on, and ETHR_LIB_NAME -dnl to the name of the library where the ethread implementation is located. -dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and -dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, -dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the -dnl empty string. -dnl - -AC_DEFUN(ERL_FIND_ETHR_LIB, -[ - -AC_ARG_ENABLE(native-ethr-impls, - AS_HELP_STRING([--disable-native-ethr-impls], - [disable native ethread implementations]), -[ case "$enableval" in - no) disable_native_ethr_impls=yes ;; - *) disable_native_ethr_impls=no ;; - esac ], disable_native_ethr_impls=no) - -test "X$disable_native_ethr_impls" = "Xyes" && - AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) - -AC_ARG_ENABLE(x86-out-of-order, - AS_HELP_STRING([--enable-x86-out-of-order], - [enable x86/x84_64 out of order support (default disabled)])) - -AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, - AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [prefer gcc native ethread implementations]), -[ case "$enableval" in - yes) enable_prefer_gcc_native_ethr_impls=yes ;; - *) enable_prefer_gcc_native_ethr_impls=no ;; - esac ], enable_prefer_gcc_native_ethr_impls=no) - -test $enable_prefer_gcc_native_ethr_impls = yes && - AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) - -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [specify and prefer usage of libatomic_ops in the ethread library])) - -AC_ARG_WITH(with_sparc_memory_order, - AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], - [specify sparc memory order (defaults to RMO)])) - -LM_CHECK_THR_LIB -ERL_INTERNAL_LIBS - -ethr_have_native_atomics=no -ethr_have_native_spinlock=no -ETHR_THR_LIB_BASE="$THR_LIB_NAME" -ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" -ETHR_DEFS="$THR_DEFS" -ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" -ETHR_LIBS= -ETHR_LIB_NAME= - -ethr_modified_default_stack_size= - -dnl Name of lib where ethread implementation is located -ethr_lib_name=ethread - -case "$THR_LIB_NAME" in - - win32_threads) - ETHR_THR_LIB_BASE_DIR=win - # * _WIN32_WINNT >= 0x0400 is needed for - # TryEnterCriticalSection - # * _WIN32_WINNT >= 0x0403 is needed for - # InitializeCriticalSectionAndSpinCount - # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. - # - # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it - # and save it in ETHR_DEFS. - found_win32_winnt=no - for cppflag in $CPPFLAGS; do - case $cppflag in - -DWINVER*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - ;; - -D_WIN32_WINNT*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - found_win32_winnt=yes - ;; - *) - ;; - esac - done - if test $found_win32_winnt = no; then - AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) - fi - - AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) - - if test "X$disable_native_ethr_impls" = "Xyes"; then - have_interlocked_op=no - ethr_have_native_atomics=no - else - ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) - fi - test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes - ;; - - pthread|ose_threads) - case "$THR_LIB_NAME" in - pthread) - ETHR_THR_LIB_BASE_DIR=pthread - AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) - ;; - ose_threads) - AC_DEFINE(ETHR_OSE_THREADS, 1, - [Define if you have OSE style threads]) - ETHR_THR_LIB_BASE_DIR=ose - AC_CHECK_HEADER(ose_spi/ose_spi.h, - AC_DEFINE(HAVE_OSE_SPI_H, 1, - [Define if you have the "ose_spi/ose_spi.h" header file.])) - ;; - esac - if test "x$THR_LIB_NAME" = "xpthread"; then - case $host_os in - openbsd*) - # The default stack size is insufficient for our needs - # on OpenBSD. We increase it to 256 kilo words. - ethr_modified_default_stack_size=256;; - linux*) - ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" - - if test X$cross_compiling = Xyes; then - case X$erl_xcomp_linux_usable_sigusrx in - X) usable_sigusrx=cross;; - Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; - esac - case X$erl_xcomp_linux_usable_sigaltstack in - X) usable_sigaltstack=cross;; - Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; - esac - else - # FIXME: Test for actual problems instead of kernel versions - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) - usable_sigusrx=no - usable_sigaltstack=no;; - 2.[[2-3]]|2.[[2-3]].*) - usable_sigusrx=yes - usable_sigaltstack=no;; - *) - usable_sigusrx=yes - usable_sigaltstack=yes;; - esac - fi - - AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) - AC_MSG_RESULT($usable_sigusrx) - if test $usable_sigusrx = cross; then - usable_sigusrx=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigusrx = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" - fi - - AC_MSG_CHECKING(if sigaltstack can be used) - AC_MSG_RESULT($usable_sigaltstack) - if test $usable_sigaltstack = cross; then - usable_sigaltstack=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigaltstack = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" - fi - ;; - *) ;; - esac - - fi - dnl We sometimes need ETHR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ETHR_DEFS" - - dnl We need the thread library in order to find some functions - saved_libs="$LIBS" - LIBS="$LIBS $ETHR_X_LIBS" - - dnl - dnl Check for headers - dnl - AC_CHECK_HEADER(pthread.h, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - if test $NEED_NPTL_PTHREAD_H = yes; then - AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ -[Define if you need the <nptl/pthread.h> header file.]) - fi - - AC_CHECK_HEADER(sched.h, \ - AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ -[Define if you have the <sched.h> header file.])) - - AC_CHECK_HEADER(sys/time.h, \ - AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ -[Define if you have the <sys/time.h> header file.])) - - AC_TRY_COMPILE([#include <time.h> - #include <sys/time.h>], - [struct timeval *tv; return 0;], - AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ -[Define if you can safely include both <sys/time.h> and <time.h>.])) - - - dnl - dnl Check for functions - dnl - if test "x$THR_LIB_NAME" = "xpthread"; then - AC_CHECK_FUNC(pthread_spin_lock, \ - [ethr_have_native_spinlock=yes \ - AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ -[Define if you have the pthread_spin_lock function.])]) - - have_sched_yield=no - have_librt_sched_yield=no - AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) - if test $have_sched_yield = no; then - AC_CHECK_LIB(rt, sched_yield, - [have_librt_sched_yield=yes - ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) - fi - if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then - AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) - AC_MSG_CHECKING([whether sched_yield() returns an int]) - sched_yield_ret_int=no - AC_TRY_COMPILE([ - #ifdef ETHR_HAVE_SCHED_H - #include <sched.h> - #endif - ], - [int sched_yield();], - [sched_yield_ret_int=yes]) - AC_MSG_RESULT([$sched_yield_ret_int]) - if test $sched_yield_ret_int = yes; then - AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) - fi - fi - - have_pthread_yield=no - AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) - if test $have_pthread_yield = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) - AC_MSG_CHECKING([whether pthread_yield() returns an int]) - pthread_yield_ret_int=no - AC_TRY_COMPILE([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [int pthread_yield();], - [pthread_yield_ret_int=yes]) - AC_MSG_RESULT([$pthread_yield_ret_int]) - if test $pthread_yield_ret_int = yes; then - AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) - fi - fi - - have_pthread_rwlock_init=no - AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) - if test $have_pthread_rwlock_init = yes; then - - ethr_have_pthread_rwlockattr_setkind_np=no - AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, - [ethr_have_pthread_rwlockattr_setkind_np=yes]) - - if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ -[Define if you have the pthread_rwlockattr_setkind_np() function.]) - - AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) - ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no - AC_TRY_LINK([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [ - pthread_rwlockattr_t *attr; - return pthread_rwlockattr_setkind_np(attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - ], - [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) - AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) - if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ -[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) - fi - fi - fi - - if test "$force_pthread_rwlocks" = "yes"; then - - AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ -[Define if you want to force usage of pthread rwlocks]) - - if test $have_pthread_rwlock_init = yes; then - AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) - else - AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) - fi - fi - - AC_CHECK_FUNC(pthread_attr_setguardsize, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ -[Define if you have the pthread_attr_setguardsize function.])) - - linux_futex=no - AC_MSG_CHECKING([for Linux futexes]) - AC_TRY_LINK([ - #include <sys/syscall.h> - #include <unistd.h> - #include <linux/futex.h> - #include <sys/time.h> - ], - [ - int i = 1; - syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, - (void*)0,(void*)0, 0); - syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, - (void*)0,(void*)0, 0); - return 0; - ], - linux_futex=yes) - AC_MSG_RESULT([$linux_futex]) - test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) - - fi - - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int128_t) - - if test "$ac_cv_sizeof_int" = "4"; then - int32="int" - elif test "$ac_cv_sizeof_long" = "4"; then - int32="long" - elif test "$ac_cv_sizeof_long_long" = "4"; then - int32="long long" - else - AC_MSG_ERROR([No 32-bit type found]) - fi - - if test "$ac_cv_sizeof_int" = "8"; then - int64="int" - elif test "$ac_cv_sizeof_long" = "8"; then - int64="long" - elif test "$ac_cv_sizeof_long_long" = "8"; then - int64="long long" - else - AC_MSG_ERROR([No 64-bit type found]) - fi - - int128=no - if test "$ac_cv_sizeof___int128_t" = "16"; then - int128="__int128_t" - fi - - if test "X$disable_native_ethr_impls" = "Xyes"; then - ethr_have_native_atomics=no - else - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) - - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) - - if test $int128 != no; then - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) - fi - - AC_MSG_CHECKING([for a usable libatomic_ops implementation]) - case "x$with_libatomic_ops" in - xno | xyes | x) - libatomic_ops_include= - ;; - *) - if test -d "${with_libatomic_ops}/include"; then - libatomic_ops_include="-I$with_libatomic_ops/include" - CPPFLAGS="$CPPFLAGS $libatomic_ops_include" - else - AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) - fi;; - esac - ethr_have_libatomic_ops=no - AC_TRY_LINK([#include "atomic_ops.h"], - [ - volatile AO_t x; - AO_t y; - int z; - - AO_nop_full(); - AO_store(&x, (AO_t) 0); - z = AO_load(&x); - z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); - ], - [ethr_have_native_atomics=yes - ethr_have_libatomic_ops=yes]) - AC_MSG_RESULT([$ethr_have_libatomic_ops]) - if test $ethr_have_libatomic_ops = yes; then - AC_CHECK_SIZEOF(AO_t, , - [ - #include <stdio.h> - #include "atomic_ops.h" - ]) - AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) - - AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) - if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) - fi - ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" - elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_MSG_ERROR([No usable libatomic_ops implementation found]) - fi - - case "$host_cpu" in - sparc | sun4u | sparc64 | sun4v) - case "$with_sparc_memory_order" in - "TSO") - AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; - "PSO") - AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; - "RMO"|"") - AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; - *) - AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; - esac - ethr_have_native_atomics=yes;; - i86pc | i*86 | x86_64 | amd64) - if test "$enable_x86_out_of_order" = "yes"; then - AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) - fi - ethr_have_native_atomics=yes;; - macppc | ppc | powerpc | "Power Macintosh") - ethr_have_native_atomics=yes;; - tile) - ethr_have_native_atomics=yes;; - *) - ;; - esac - - fi - - test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes - - dnl Restore LIBS - LIBS=$saved_libs - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - ;; - *) - ;; -esac - -AC_MSG_CHECKING([whether default stack size should be modified]) -if test "x$ethr_modified_default_stack_size" != "x"; then - AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) - AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) -else - AC_MSG_RESULT([no]) -fi - -if test "x$ETHR_THR_LIB_BASE" != "x"; then - ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" - ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" - ETHR_LIB_NAME=$ethr_lib_name -fi - -AC_CHECK_SIZEOF(void *) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) - -AC_CHECK_SIZEOF(int) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) -AC_CHECK_SIZEOF(long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) -AC_CHECK_SIZEOF(long long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) -AC_CHECK_SIZEOF(__int64) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) -AC_CHECK_SIZEOF(__int128_t) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) - - -case X$erl_xcomp_bigendian in - X) ;; - Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; - *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; -esac - -AC_C_BIGENDIAN - -if test "$ac_cv_c_bigendian" = "yes"; then - AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) -fi - -case X$erl_xcomp_double_middle_endian in - X) ;; - Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;; - *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);; -esac - -AC_C_DOUBLE_MIDDLE_ENDIAN - -ETHR_X86_SSE2_ASM=no -case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in - yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) - AC_MSG_CHECKING([for gcc sse2 asm support]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -msse2" - gcc_sse2_asm=no - AC_TRY_COMPILE([], - [ - long long x, *y; - __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); - ], - [gcc_sse2_asm=yes]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$gcc_sse2_asm]) - if test "$gcc_sse2_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) - ETHR_X86_SSE2_ASM=yes - fi - ;; - *) - ;; -esac - -case "$GCC-$host_cpu" in - yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) - gcc_dw_cmpxchg_asm=no - AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; - __asm__ __volatile__( -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "pushl %%ebx\n\t" - "movl %8, %%ebx\n\t" -#endif -#if ETHR_SIZEOF_PTR == 4 - "lock; cmpxchg8b %0\n\t" -#else - "lock; cmpxchg16b %0\n\t" -#endif - "setz %3\n\t" -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "popl %%ebx\n\t" -#endif - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "r"(new[0]) -#else - "b"(new[0]) -#endif - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; -#if !defined(__PIC__) || !__PIC__ -# error nope -#endif - __asm__ __volatile__( - "pushl %%ebx\n\t" - "movl (%7), %%ebx\n\t" - "movl 4(%7), %%ecx\n\t" - "lock; cmpxchg8b %0\n\t" - "setz %3\n\t" - "popl %%ebx\n\t" - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) - fi - fi - AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) - fi;; - *) - ;; -esac - -AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ -[Define if you have all ethread defines]) - -AC_SUBST(ETHR_X_LIBS) -AC_SUBST(ETHR_LIBS) -AC_SUBST(ETHR_LIB_NAME) -AC_SUBST(ETHR_DEFS) -AC_SUBST(ETHR_THR_LIB_BASE) -AC_SUBST(ETHR_THR_LIB_BASE_DIR) -AC_SUBST(ETHR_X86_SSE2_ASM) - -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_TIME_CORRECTION -dnl -dnl In the presence of a high resolution realtime timer Erlang can adapt -dnl its view of time relative to this timer. On solaris such a timer is -dnl available with the syscall gethrtime(). On other OS's a fallback -dnl solution using times() is implemented. (However on e.g. FreeBSD times() -dnl is implemented using gettimeofday so it doesn't make much sense to -dnl use it there...) On second thought, it seems to be safer to do it the -dnl other way around. I.e. only use times() on OS's where we know it will -dnl work... -dnl - -AC_DEFUN(ERL_TIME_CORRECTION, -[if test x$ac_cv_func_gethrtime = x; then - AC_CHECK_FUNC(gethrtime) -fi -if test x$clock_gettime_correction = xunknown; then - AC_TRY_COMPILE([#include <time.h>], - [struct timespec ts; - long long result; - clock_gettime(CLOCK_MONOTONIC,&ts); - result = ((long long) ts.tv_sec) * 1000000000LL + - ((long long) ts.tv_nsec);], - clock_gettime_compiles=yes, - clock_gettime_compiles=no) -else - clock_gettime_compiles=no -fi - - -AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, -[ -case $clock_gettime_correction in - yes) - erl_cv_time_correction=clock_gettime;; - no|unknown) - case $ac_cv_func_gethrtime in - yes) - erl_cv_time_correction=hrtime ;; - no) - case $host_os in - linux*) - case $clock_gettime_correction in - unknown) - if test x$clock_gettime_compiles = xyes; then - if test X$cross_compiling != Xyes; then - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) - erl_cv_time_correction=times ;; - *) - erl_cv_time_correction=clock_gettime;; - esac - else - case X$erl_xcomp_linux_clock_gettime_correction in - X) - erl_cv_time_correction=cross;; - Xyes|Xno) - if test $erl_xcomp_linux_clock_gettime_correction = yes; then - erl_cv_time_correction=clock_gettime - else - erl_cv_time_correction=times - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; - esac - fi - else - erl_cv_time_correction=times - fi - ;; - *) - erl_cv_time_correction=times ;; - esac - ;; - *) - erl_cv_time_correction=none ;; - esac - ;; - esac - ;; -esac -]) - -xrtlib="" -case $erl_cv_time_correction in - times) - AC_DEFINE(CORRECT_USING_TIMES,[], - [Define if you do not have a high-res. timer & want to use times() instead]) - ;; - clock_gettime|cross) - if test $erl_cv_time_correction = cross; then - erl_cv_time_correction=clock_gettime - AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) - fi - xrtlib="-lrt" - AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], - [Define if you want to use clock_gettime to simulate gethrtime]) - ;; -esac -dnl -dnl Check if gethrvtime is working, and if to use procfs ioctl -dnl or (yet to be written) write to the procfs ctl file. -dnl - -AC_MSG_CHECKING([if gethrvtime works and how to use it]) -AC_TRY_RUN([ -/* gethrvtime procfs ioctl test */ -/* These need to be undef:ed to not break activation of - * micro level process accounting on /proc/self - */ -#ifdef _LARGEFILE_SOURCE -# undef _LARGEFILE_SOURCE -#endif -#ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -#endif -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/signal.h> -#include <sys/fault.h> -#include <sys/syscall.h> -#include <sys/procfs.h> -#include <fcntl.h> - -int main() { - long msacct = PR_MSACCT; - int fd; - long long start, stop; - int i; - pid_t pid = getpid(); - char proc_self[30] = "/proc/"; - - sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); - if ( (fd = open(proc_self, O_WRONLY)) == -1) - exit(1); - if (ioctl(fd, PIOCSET, &msacct) < 0) - exit(2); - if (close(fd) < 0) - exit(3); - start = gethrvtime(); - for (i = 0; i < 100; i++) - stop = gethrvtime(); - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; -} -], -erl_gethrvtime=procfs_ioctl, -erl_gethrvtime=false, -[ -case X$erl_xcomp_gethrvtime_procfs_ioctl in - X) - erl_gethrvtime=cross;; - Xyes|Xno) - if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then - erl_gethrvtime=procfs_ioctl - else - erl_gethrvtime=false - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; -esac -]) - -case $erl_gethrvtime in - procfs_ioctl) - AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], - [define if gethrvtime() works and uses ioctl() to /proc/self]) - AC_MSG_RESULT(uses ioctl to procfs) - ;; - *) - if test $erl_gethrvtime = cross; then - erl_gethrvtime=false - AC_MSG_RESULT(cross) - AC_MSG_WARN([result 'not working' guessed because of cross compilation]) - else - AC_MSG_RESULT(not working) - fi - - dnl - dnl Check if clock_gettime (linux) is working - dnl - - AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) - save_libs=$LIBS - LIBS="-lrt" - AC_TRY_RUN([ - #include <stdlib.h> - #include <unistd.h> - #include <string.h> - #include <stdio.h> - #include <time.h> - int main() { - long long start, stop; - int i; - struct timespec tp; - - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) - exit(1); - start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - for (i = 0; i < 100; i++) - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); - stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; - } - ], - erl_clock_gettime=yes, - erl_clock_gettime=no, - [ - case X$erl_xcomp_clock_gettime_cpu_time in - X) erl_clock_gettime=cross;; - Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; - *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; - esac - ]) - LIBS=$save_libs - case $host_os in - linux*) - AC_MSG_RESULT([no; not stable]) - LIBRT=$xrtlib - ;; - *) - AC_MSG_RESULT($erl_clock_gettime) - case $erl_clock_gettime in - yes) - AC_DEFINE(HAVE_CLOCK_GETTIME,[], - [define if clock_gettime() works for getting process time]) - LIBRT=-lrt - ;; - cross) - erl_clock_gettime=no - AC_MSG_WARN([result no guessed because of cross compilation]) - LIBRT=$xrtlib - ;; - *) - LIBRT=$xrtlib - ;; - esac - ;; - esac - AC_SUBST(LIBRT) - ;; -esac -])dnl - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_TRY_ENABLE_CFLAG -dnl -dnl -dnl Tries a CFLAG and sees if it can be enabled without compiler errors -dnl $1: textual cflag to add -dnl $2: variable to store the modified CFLAG in -dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS]) -dnl -dnl -AC_DEFUN([LM_TRY_ENABLE_CFLAG], [ - AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)]) - saved_CFLAGS=$CFLAGS; - CFLAGS="$1 $$2"; - AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false) - CFLAGS=$saved_CFLAGS; - if test "X$can_enable_flag" = "Xtrue"; then - AC_MSG_RESULT([yes]) - AS_VAR_SET($2, "$1 $$2") - else - AC_MSG_RESULT([no]) - fi -]) - -dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY -dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a -dnl AC_LANG_JAVA instead...) -AC_DEFUN(ERL_TRY_LINK_JAVA, -[java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(, )dnl -cat > conftest.java <<EOF -$1 -class conftest { public static void main(String[] args) { - $2 - ; return; }} -EOF -changequote([, ])dnl -if AC_TRY_EVAL(java_link) && test -s conftest.class; then - ifelse([$3], , :, [rm -rf conftest* - $3]) -else - echo "configure: failed program was:" 1>&AC_FD_CC - cat conftest.java 1>&AC_FD_CC - echo "configure: PATH was $PATH" 1>&AC_FD_CC -ifelse([$4], , , [ rm -rf conftest* - $4 -])dnl -fi -rm -f conftest*]) -#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ - - diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index 84c201a656..f4b0a5d8d0 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -564,7 +564,6 @@ static db_result_msg db_connect(byte *args, db_state *state) /* Close the connection to the database. Returns an ok or error message. */ static db_result_msg db_close_connection(db_state *state) { - int index; SQLRETURN result; diagnos diagnos; @@ -613,11 +612,7 @@ static db_result_msg db_end_tran(byte compleationtype, db_state *state) erlang term into the message buffer of the returned message-struct. */ static db_result_msg db_query(byte *sql, db_state *state) { - char *atom; - int num_of_rows, elements, update; - SQLSMALLINT num_of_columns; SQLRETURN result; - SQLINTEGER RowCountPtr; db_result_msg msg; diagnos diagnos; byte is_error[6]; @@ -701,12 +696,9 @@ static db_result_msg db_query(byte *sql, db_state *state) set. */ static db_result_msg db_select_count(byte *sql, db_state *state) { - SQLSMALLINT num_of_columns, intresult; + SQLSMALLINT num_of_columns; SQLLEN num_of_rows; - SQLRETURN result; diagnos diagnos; - db_result_msg msg; - int index; if (associated_result_set(state)) { clean_state(state); @@ -792,6 +784,9 @@ static db_result_msg db_select(byte *args, db_state *state) orientation = SQL_FETCH_NEXT; offset = atoi(strtok((char *)(args + sizeof(byte)), ";")); n = atoi(strtok(NULL, ";")); + break; + default: + DO_EXIT(EXIT_PARAM_ARRAY); } msg = encode_empty_message(); @@ -942,7 +937,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state) SQLSMALLINT num_of_columns; SQLCHAR name[MAX_NAME]; SQLSMALLINT name_len, sql_type, dec_digits, nullable; - SQLLEN size; + SQLULEN size; diagnos diagnos; int i; @@ -1294,8 +1289,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns, db_result_msg msg; SQLCHAR name[MAX_NAME]; SQLSMALLINT name_len, sql_type, dec_digits, nullable; - SQLLEN size; - SQLRETURN result; + SQLULEN size; msg = encode_empty_message(); @@ -1357,9 +1351,8 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns, static db_result_msg encode_value_list(SQLSMALLINT num_of_columns, db_state *state) { - int i, msg_len; + int i; SQLRETURN result; - db_result_msg list_result; db_result_msg msg; msg = encode_empty_message(); @@ -1402,9 +1395,8 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns, SQLINTEGER OffSet, int N, db_state *state) { - int i, j, msg_len; + int i, j; SQLRETURN result; - db_result_msg list_result; db_result_msg msg; msg = encode_empty_message(); @@ -1810,10 +1802,23 @@ static int read_exact(byte *buffer, int len) { #endif +static size_t length_buffer_to_size(byte length_buffer[LENGTH_INDICATOR_SIZE]) +{ + size_t size = 0, i; + + for (i = 0; i < LENGTH_INDICATOR_SIZE; ++i) { + size <<= 8; + size |= (unsigned char)length_buffer[i]; + } + + return size; +} + + /* Recieive (read) data from erlang on stdin */ static byte * receive_erlang_port_msg(void) { - int i, len = 0; + size_t len; byte *buffer; byte lengthstr[LENGTH_INDICATOR_SIZE]; @@ -1822,10 +1827,8 @@ static byte * receive_erlang_port_msg(void) { DO_EXIT(EXIT_STDIN_HEADER); } - for(i=0; i < LENGTH_INDICATOR_SIZE; i++) { - len <<= 8; - len |= lengthstr[i]; - } + + len = length_buffer_to_size(lengthstr); if (len <= 0 || len > 1024) { DO_EXIT(EXIT_STDIN_HEADER); @@ -1926,8 +1929,7 @@ static byte * receive_msg(int socket) #endif { byte lengthstr[LENGTH_INDICATOR_SIZE]; - size_t msg_len = 0; - int i; + size_t msg_len; byte *buffer = NULL; if(!receive_msg_part(socket, lengthstr, LENGTH_INDICATOR_SIZE)) { @@ -1935,10 +1937,7 @@ static byte * receive_msg(int socket) DO_EXIT(EXIT_SOCKET_RECV_HEADER); } - for(i = 0; i < LENGTH_INDICATOR_SIZE; i++) { - msg_len <<= 8; - msg_len |= lengthstr[i]; - } + msg_len = length_buffer_to_size(lengthstr); buffer = (byte *)safe_malloc(msg_len); @@ -2200,8 +2199,7 @@ static void init_driver(int erl_auto_commit_mode, int erl_trace_driver, static void init_param_column(param_array *params, byte *buffer, int *index, int num_param_values, db_state* state) { - int size, erl_type; - long user_type, precision, scale, length, dummy; + long user_type, precision, scale, length; long in_or_out; ei_decode_long(buffer, index, &user_type); @@ -2514,8 +2512,7 @@ static param_array * bind_parameter_arrays(byte *buffer, int *index, int cols, int num_param_values, db_state *state) { - int i, j, k, size, erl_type; - db_result_msg msg; + int i, j, size, erl_type; long dummy; void *Values; param_array *params; @@ -2601,7 +2598,6 @@ static db_column retrive_binary_data(db_column column, int column_nr, db_state *state) { char *outputptr; - char *sqlState; int blocklen, outputlen, result; diagnos diagnos; diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in index ea5c51965f..0cfcb9964b 100644 --- a/lib/odbc/configure.in +++ b/lib/odbc/configure.in @@ -136,7 +136,7 @@ AC_SUBST(THR_LIBS) odbc_lib_link_success=no AC_SUBST(TARGET_FLAGS) case $host_os in - darwin1[[0-2]].*|darwin[[0-9]].*) + darwin1[[0-4]].*|darwin[[0-9]].*) TARGET_FLAGS="-DUNIX" if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then ODBC_LIB= -L"/usr/lib" diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml index 495a675631..7a7658b092 100644 --- a/lib/odbc/doc/src/notes.xml +++ b/lib/odbc/doc/src/notes.xml @@ -31,7 +31,46 @@ <p>This document describes the changes made to the odbc application. </p> - <section><title>ODBC 2.10.21</title> + <section><title>ODBC 2.10.22</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + OS X Mavericks is based on Darwin version 13.x, and + Yosemite on 14.x. Change the ODBC configure.in script to + recognize these versions.</p> + <p> + Own Id: OTP-12260</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The commands longer than 127 chars sent to odbc server + crashed it, e.g. a connection string with driver path and + some additional parameters.</p> + <p> + Own Id: OTP-12346</p> + </item> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + </list> + </section> + +</section> + +<section><title>ODBC 2.10.21</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl index a7bb1d0ffe..d75e615ed4 100644 --- a/lib/odbc/test/odbc_start_SUITE.erl +++ b/lib/odbc/test/odbc_start_SUITE.erl @@ -109,8 +109,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> case odbc_test_lib:odbc_check() of - ok -> [app, appup, start]; - Other -> [app, appup] + ok -> [app, appup, start, long_connection_line]; + _Other -> [app, appup] end. groups() -> @@ -168,3 +168,14 @@ start_odbc(Type) -> {error, odbc_not_started} -> test_server:fail(start_failed) end. + + +long_connection_line(doc)-> + ["Test a connection line longer than 127 characters"]; +long_connection_line(suite) -> []; +long_connection_line(_Config) -> + odbc:start(), + String133 = "unknown_odbc_parameter=01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", + {error, Reason} = odbc:connect(String133, []), + odbc:stop(), + ct:pal("Driver error reason: ~p",[Reason]). diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index b374e42d15..52c84429ec 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1 +1 @@ -ODBC_VSN = 2.10.21 +ODBC_VSN = 2.10.22 diff --git a/lib/orber/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl index 36ef6ce02f..9aec64892e 100644 --- a/lib/orber/src/cdr_decode.erl +++ b/lib/orber/src/cdr_decode.erl @@ -193,7 +193,7 @@ dec_message_header(TypeCodes, Message, Bytes) -> %% Args: %% The message as a byte sequence. %% Returns: -%% A tuple {Endianess, Rest} where Endianess is big or little. +%% A tuple {Endianness, Rest} where Endianness is big or little. %% Rest is the remaining message byte sequence. %%----------------------------------------------------------------- dec_byte_order(<<0:8,T/binary>>) -> @@ -206,7 +206,7 @@ dec_byte_order(<<1:8,T/binary>>) -> %% Args: %% The message as a byte sequence. %% Returns: -%% A tuple {Endianess, Rest} where Endianess is big or little. +%% A tuple {Endianness, Rest} where Endianness is big or little. %% Rest is the remaining message byte sequence. %%----------------------------------------------------------------- dec_byte_order_list([0|T]) -> diff --git a/lib/os_mon/c_src/memsup.c b/lib/os_mon/c_src/memsup.c index 409db84aa7..5dcab07dd8 100644 --- a/lib/os_mon/c_src/memsup.c +++ b/lib/os_mon/c_src/memsup.c @@ -104,7 +104,7 @@ #if !defined (__OpenBSD__) && !defined (__NetBSD__) #include <vm/vm_param.h> #endif -#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__NetBSD__) +#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__NetBSD__) || defined(__OpenBSD__) #include <sys/vmmeter.h> #endif #endif diff --git a/lib/otp_mibs/doc/src/notes.xml b/lib/otp_mibs/doc/src/notes.xml index 391c82b1c5..c61978c99e 100644 --- a/lib/otp_mibs/doc/src/notes.xml +++ b/lib/otp_mibs/doc/src/notes.xml @@ -31,6 +31,22 @@ <p>This document describes the changes made to the OTP_Mibs application.</p> +<section><title>Otp_Mibs 1.0.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure the clean rule for ssh, ssl, eunit and otp_mibs + actually removes generated files.</p> + <p> + Own Id: OTP-12200</p> + </item> + </list> + </section> + +</section> + <section><title>Otp_Mibs 1.0.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/otp_mibs/vsn.mk b/lib/otp_mibs/vsn.mk index 98db21c132..2ff59431f4 100644 --- a/lib/otp_mibs/vsn.mk +++ b/lib/otp_mibs/vsn.mk @@ -1,4 +1,4 @@ -OTP_MIBS_VSN = 1.0.9 +OTP_MIBS_VSN = 1.0.10 # Note: The branch 'otp_mibs' is defunct as of otp_mibs-1.0.4 and # should NOT be used again. diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml index a8368740da..c8cb70b6d2 100644 --- a/lib/parsetools/doc/src/notes.xml +++ b/lib/parsetools/doc/src/notes.xml @@ -30,6 +30,24 @@ </header> <p>This document describes the changes made to the Parsetools application.</p> +<section><title>Parsetools 2.0.12</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The line counter becomes invalid when rules with linewrap + are used. This issue appears because the parsing FSM does + not roll back the line counter after attempting such a + rule.</p> + <p> + Own Id: OTP-12238</p> + </item> + </list> + </section> + +</section> + <section><title>Parsetools 2.0.11</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk index 8fd7422c1c..dd9cc2991c 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.0.11 +PARSETOOLS_VSN = 2.0.12 diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml index bae999ed1a..b51c8fcb4d 100644 --- a/lib/percept/doc/src/notes.xml +++ b/lib/percept/doc/src/notes.xml @@ -32,6 +32,21 @@ </header> <p>This document describes the changes made to the Percept application.</p> +<section><title>Percept 0.8.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure to install .hrl files when needed</p> + <p> + Own Id: OTP-12197</p> + </item> + </list> + </section> + +</section> + <section><title>Percept 0.8.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk index 935a9d1336..4451354e21 100644 --- a/lib/percept/vsn.mk +++ b/lib/percept/vsn.mk @@ -1 +1 @@ -PERCEPT_VSN = 0.8.9 +PERCEPT_VSN = 0.8.10 diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index e3473f80d7..b86d0fe0ab 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2008</year> - <year>2014</year> + <year>2015</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -127,6 +127,8 @@ affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise</code></p> + <p><code>issuer_name() = {rdnSequence,[#'AttributeTypeAndValue'{}]} </code> </p> + <p><code>ssh_file() = openssh_public_key | rfc4716_public_key | known_hosts | auth_keys</code></p> @@ -368,8 +370,8 @@ <name>pkix_is_issuer(Cert, IssuerCert) -> boolean()</name> <fsummary> Checks if <c>IssuerCert</c> issued <c>Cert</c> </fsummary> <type> - <v>Cert = der_encode() | #'OTPCertificate'{}</v> - <v>IssuerCert = der_encode() | #'OTPCertificate'{}</v> + <v>Cert = der_encoded() | #'OTPCertificate'{}</v> + <v>IssuerCert = der_encoded() | #'OTPCertificate'{}</v> </type> <desc> <p> Checks if <c>IssuerCert</c> issued <c>Cert</c> </p> @@ -380,7 +382,7 @@ <name>pkix_is_fixed_dh_cert(Cert) -> boolean()</name> <fsummary> Checks if a Certificate is a fixed Diffie-Hellman Cert.</fsummary> <type> - <v>Cert = der_encode() | #'OTPCertificate'{}</v> + <v>Cert = der_encoded() | #'OTPCertificate'{}</v> </type> <desc> <p> Checks if a Certificate is a fixed Diffie-Hellman Cert.</p> @@ -391,7 +393,7 @@ <name>pkix_is_self_signed(Cert) -> boolean()</name> <fsummary> Checks if a Certificate is self signed.</fsummary> <type> - <v>Cert = der_encode() | #'OTPCertificate'{}</v> + <v>Cert = der_encoded() | #'OTPCertificate'{}</v> </type> <desc> <p> Checks if a Certificate is self signed.</p> @@ -402,24 +404,25 @@ <name>pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason}</name> <fsummary> Returns the issuer id.</fsummary> <type> - <v>Cert = der_encode() | #'OTPCertificate'{}</v> + <v>Cert = der_encoded() | #'OTPCertificate'{}</v> <v>IssuedBy = self | other</v> - <v>IssuerID = {integer(), {rdnSequence, [#'AttributeTypeAndValue'{}]}}</v> + <v>IssuerID = {integer(), issuer_name()}</v> <d>The issuer id consists of the serial number and the issuers name.</d> <v>Reason = term()</v> - </type> - <desc> - <p> Returns the issuer id.</p> - </desc> + </type> + <desc> + <p> Returns the issuer id.</p> + </desc> </func> - + + <func> <name>pkix_normalize_name(Issuer) -> Normalized</name> <fsummary>Normalizes a issuer name so that it can be easily compared to another issuer name. </fsummary> <type> - <v>Issuer = {rdnSequence,[#'AttributeTypeAndValue'{}]}</v> - <v>Normalized = {rdnSequence, [#'AttributeTypeAndValue'{}]}</v> + <v>Issuer = issuer_name()</v> + <v>Normalized = issuer_name()</v> </type> <desc> <p>Normalizes a issuer name so that it can be easily @@ -431,13 +434,13 @@ <name>pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}} | {error, {bad_cert, Reason}} </name> <fsummary> Performs a basic path validation according to RFC 5280.</fsummary> <type> - <v> TrustedCert = #'OTPCertificate'{} | der_encode() | atom() </v> + <v> TrustedCert = #'OTPCertificate'{} | der_encoded() | atom() </v> <d>Normally a trusted certificate but it can also be a path validation error that can be discovered while constructing the input to this function and that should be run through the <c>verify_fun</c>. For example <c>unknown_ca </c> or <c>selfsigned_peer </c> </d> - <v> CertChain = [der_encode()]</v> + <v> CertChain = [der_encoded()]</v> <d>A list of DER encoded certificates in trust order ending with the peer certificate.</d> <v> Options = proplists:proplist()</v> <v>PublicKeyInfo = {?'rsaEncryption' | ?'id-dsa', @@ -527,6 +530,17 @@ fun(OtpCert :: #'OTPCertificate'{}, </desc> </func> + <func> + <name>pkix_crl_issuer(CRL) -> issuer_name()</name> + <fsummary>Returns the issuer of the <c>CRL</c>.</fsummary> + <type> + <v>CRL = der_encoded() | #'CertificateList'{} </v> + </type> + <desc> + <p>Returns the issuer of the <c>CRL</c>.</p> + </desc> + </func> + <func> <name>pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus()</name> <fsummary> Performs CRL validation.</fsummary> @@ -574,9 +588,48 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </taglist> </desc> </func> + + <func> + <name>pkix_crl_verify(CRL, Cert) -> boolean()</name> + <fsummary> Verify that <c>Cert</c> is the <c> CRL</c> signer. </fsummary> + <type> + <v>CRL = der_encoded() | #'CertificateList'{} </v> + <v>Cert = der_encoded() | #'OTPCertificate'{} </v> + </type> + <desc> + <p>Verify that <c>Cert</c> is the <c>CRL</c> signer.</p> + </desc> + </func> + <func> + <name>pkix_dist_point(Cert) -> DistPoint</name> + <fsummary>Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>.</fsummary> + <type> + <v> Cert = der_encoded() | #'OTPCertificate'{} </v> + <v> DistPoint = #'DistributionPoint'{}</v> + </type> + <desc> + <p>Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>. + Can be used as input to <seealso + marker="#pkix_crls_validate-3">pkix_crls_validate/3 </seealso> + </p> + </desc> + </func> + + <func> + <name>pkix_dist_points(Cert) -> DistPoints</name> + <fsummary> Extracts distribution points from the certificates extensions.</fsummary> + <type> + <v> Cert = der_encoded() | #'OTPCertificate'{} </v> + <v> DistPoints = [#'DistributionPoint'{}]</v> + </type> + <desc> + <p> Extracts distribution points from the certificates extensions.</p> + </desc> + </func> + <func> - <name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encode()</name> + <name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encoded()</name> <fsummary>Signs certificate.</fsummary> <type> <v>Key = rsa_public_key() | dsa_public_key()</v> @@ -606,7 +659,7 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, <name>pkix_verify(Cert, Key) -> boolean()</name> <fsummary> Verify pkix x.509 certificate signature.</fsummary> <type> - <v>Cert = der_encode()</v> + <v>Cert = der_encoded()</v> <v>Key = rsa_public_key() | dsa_public_key()</v> </type> <desc> diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl index ae517ca642..8b11538499 100644 --- a/lib/public_key/src/pubkey_cert.erl +++ b/lib/public_key/src/pubkey_cert.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2014. 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 @@ -28,8 +28,9 @@ validate_issuer/4, validate_names/6, validate_extensions/4, normalize_general_name/1, is_self_signed/1, - is_issuer/2, issuer_id/2, is_fixed_dh_cert/1, - verify_data/1, verify_fun/4, select_extension/2, match_name/3, + is_issuer/2, issuer_id/2, distribution_points/1, + is_fixed_dh_cert/1, verify_data/1, verify_fun/4, + select_extension/2, match_name/3, extensions_list/1, cert_auth_key_id/1, time_str_2_gregorian_sec/1]). -define(NULL, 0). @@ -272,6 +273,16 @@ issuer_id(Otpcert, self) -> SerialNr = TBSCert#'OTPTBSCertificate'.serialNumber, {ok, {SerialNr, normalize_general_name(Issuer)}}. +distribution_points(Otpcert) -> + TBSCert = Otpcert#'OTPCertificate'.tbsCertificate, + Extensions = extensions_list(TBSCert#'OTPTBSCertificate'.extensions), + case select_extension(?'id-ce-cRLDistributionPoints', Extensions) of + undefined -> + []; + #'Extension'{extnValue = Value} -> + Value + end. + %%-------------------------------------------------------------------- -spec is_fixed_dh_cert(#'OTPCertificate'{}) -> boolean(). %% @@ -296,7 +307,9 @@ is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate = %% -------------------------------------------------------------------- verify_fun(Otpcert, Result, UserState0, VerifyFun) -> case VerifyFun(Otpcert, Result, UserState0) of - {valid,UserState} -> + {valid, UserState} -> + UserState; + {valid_peer, UserState} -> UserState; {fail, Reason} -> case Reason of diff --git a/lib/public_key/src/pubkey_crl.erl b/lib/public_key/src/pubkey_crl.erl index f0df4bc3f2..488cc97c70 100644 --- a/lib/public_key/src/pubkey_crl.erl +++ b/lib/public_key/src/pubkey_crl.erl @@ -41,10 +41,10 @@ validate(OtpCert, OtherDPCRLs, DP, {DerCRL, CRL}, {DerDeltaCRL, DeltaCRL}, CRLIssuer = TBSCRL#'TBSCertList'.issuer, AltNames = case pubkey_cert:select_extension(?'id-ce-subjectAltName', TBSCert#'OTPTBSCertificate'.extensions) of - undefined -> - []; - Ext -> - Ext#'Extension'.extnValue + #'Extension'{extnValue = Value} -> + Value; + _ -> + [] end, revoked_status(DP, IDP, {directoryName, CRLIssuer}, [ {directoryName, CertIssuer} | AltNames], SerialNumber, Revoked, diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 1bbf4ef416..a0a87e5351 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2014. All Rights Reserved. +%% Copyright Ericsson AB 2008-2015. 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 @@ -46,7 +46,11 @@ pkix_normalize_name/1, pkix_path_validation/3, ssh_decode/2, ssh_encode/2, - pkix_crls_validate/3 + pkix_crls_validate/3, + pkix_dist_point/1, + pkix_dist_points/1, + pkix_crl_verify/2, + pkix_crl_issuer/1 ]). -export_type([public_key/0, private_key/0, pem_entry/0, @@ -470,6 +474,45 @@ verify(DigestOrPlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P crypto:verify(dss, DigestType, DigestOrPlainText, Signature, [P, Q, G, Key]). %%-------------------------------------------------------------------- +-spec pkix_dist_point(der_encoded() | #'OTPCertificate'{}) -> + #'DistributionPoint'{}. +%% Description: Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>. +%%-------------------------------------------------------------------- +pkix_dist_point(OtpCert) when is_binary(OtpCert) -> + pkix_dist_point(pkix_decode_cert(OtpCert, otp)); +pkix_dist_point(OtpCert) -> + Issuer = public_key:pkix_normalize_name( + pubkey_cert_records:transform( + OtpCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.issuer, encode)), + + TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, + Extensions = pubkey_cert:extensions_list(TBSCert#'OTPTBSCertificate'.extensions), + AltNames = case pubkey_cert:select_extension(?'id-ce-issuerAltName', Extensions) of + undefined -> + []; + #'Extension'{extnValue = Value} -> + Value + end, + Point = {fullName, [{directoryName, Issuer} | AltNames]}, + #'DistributionPoint'{cRLIssuer = asn1_NOVALUE, + reasons = asn1_NOVALUE, + distributionPoint = Point}. +%%-------------------------------------------------------------------- +-spec pkix_dist_points(der_encoded() | #'OTPCertificate'{}) -> + [#'DistributionPoint'{}]. +%% Description: Extracts distributionpoints specified in the certificates extensions. +%%-------------------------------------------------------------------- +pkix_dist_points(OtpCert) when is_binary(OtpCert) -> + pkix_dist_points(pkix_decode_cert(OtpCert, otp)); +pkix_dist_points(OtpCert) -> + Value = pubkey_cert:distribution_points(OtpCert), + lists:foldl(fun(Point, Acc0) -> + DistPoint = pubkey_cert_records:transform(Point, decode), + [DistPoint | Acc0] + end, + [], Value). + +%%-------------------------------------------------------------------- -spec pkix_sign(#'OTPTBSCertificate'{}, rsa_private_key() | dsa_private_key()) -> Der::binary(). %% @@ -511,6 +554,25 @@ pkix_verify(DerCert, Key = {#'ECPoint'{}, _}) verify(PlainText, DigestType, Signature, Key). %%-------------------------------------------------------------------- +-spec pkix_crl_verify(CRL::binary() | #'CertificateList'{}, Cert::binary() | #'OTPCertificate'{}) -> boolean(). +%% +%% Description: Verify that Cert is the CRL signer. +%%-------------------------------------------------------------------- +pkix_crl_verify(CRL, Cert) when is_binary(CRL) -> + pkix_crl_verify(der_decode('CertificateList', CRL), Cert); +pkix_crl_verify(CRL, Cert) when is_binary(Cert) -> + pkix_crl_verify(CRL, pkix_decode_cert(Cert, otp)); +pkix_crl_verify(#'CertificateList'{} = CRL, #'OTPCertificate'{} = Cert) -> + TBSCert = Cert#'OTPCertificate'.tbsCertificate, + PublicKeyInfo = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo, + PublicKey = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey, + AlgInfo = PublicKeyInfo#'OTPSubjectPublicKeyInfo'.algorithm, + PublicKeyParams = AlgInfo#'PublicKeyAlgorithm'.parameters, + pubkey_crl:verify_crl_signature(CRL, + der_encode('CertificateList', CRL), + PublicKey, PublicKeyParams). + +%%-------------------------------------------------------------------- -spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{} | #'CertificateList'{}, IssuerCert :: der_encoded()| #'OTPCertificate'{}) -> boolean(). @@ -564,15 +626,21 @@ pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) -> % %% Description: Returns the issuer id. %%-------------------------------------------------------------------- -pkix_issuer_id(#'OTPCertificate'{} = OtpCert, self) -> - pubkey_cert:issuer_id(OtpCert, self); - -pkix_issuer_id(#'OTPCertificate'{} = OtpCert, other) -> - pubkey_cert:issuer_id(OtpCert, other); +pkix_issuer_id(Cert, Signed)-> + pkix_issuer_id(Cert, Signed, decode). -pkix_issuer_id(Cert, Signed) when is_binary(Cert) -> - OtpCert = pkix_decode_cert(Cert, otp), - pkix_issuer_id(OtpCert, Signed). +%%-------------------------------------------------------------------- +-spec pkix_crl_issuer(CRL::binary()| #'CertificateList'{}) -> + {rdnSequence, + [#'AttributeTypeAndValue'{}]}. +% +%% Description: Returns the issuer. +%%-------------------------------------------------------------------- +pkix_crl_issuer(CRL) when is_binary(CRL) -> + pkix_crl_issuer(der_decode('CertificateList', CRL)); +pkix_crl_issuer(#'CertificateList'{} = CRL) -> + pubkey_cert_records:transform( + CRL#'CertificateList'.tbsCertList#'TBSCertList'.issuer, decode). %%-------------------------------------------------------------------- -spec pkix_normalize_name({rdnSequence, @@ -921,3 +989,18 @@ ec_key({PubKey, PrivateKey}, Params) -> privateKey = binary_to_list(PrivateKey), parameters = Params, publicKey = {0, PubKey}}. + +pkix_issuer_id(#'OTPCertificate'{} = OtpCert, Signed, decode) when (Signed == self) or + (Signed == other) -> + pubkey_cert:issuer_id(OtpCert, Signed); +pkix_issuer_id(#'OTPCertificate'{} = OtpCert, Signed, encode) when (Signed == self) or + (Signed == other) -> + case pubkey_cert:issuer_id(OtpCert, Signed) of + {ok, {Serial, Issuer}} -> + {ok, {Serial, pubkey_cert_records:transform(Issuer, encode)}}; + Error -> + Error + end; +pkix_issuer_id(Cert, Signed, Decode) when is_binary(Cert) -> + OtpCert = pkix_decode_cert(Cert, otp), + pkix_issuer_id(OtpCert, Signed, Decode). diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 163f5f4413..40c28e86b3 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2015. 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 @@ -42,7 +42,7 @@ all() -> encrypt_decrypt, {group, sign_verify}, pkix, pkix_countryname, pkix_emailaddress, pkix_path_validation, - pkix_iso_rsa_oid, pkix_iso_dsa_oid]. + pkix_iso_rsa_oid, pkix_iso_dsa_oid, pkix_crl]. groups() -> [{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem, @@ -712,6 +712,42 @@ pkix_iso_dsa_oid(Config) when is_list(Config) -> {_, dsa} = public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm). %%-------------------------------------------------------------------- + +pkix_crl() -> + [{doc, "test pkix_crl_* functions"}]. + +pkix_crl(Config) when is_list(Config) -> + Datadir = ?config(data_dir, Config), + {ok, PemCRL} = file:read_file(filename:join(Datadir, "idp_crl.pem")), + [{_, CRL, _}] = public_key:pem_decode(PemCRL), + + {ok, IDPPemCert} = file:read_file(filename:join(Datadir, "idp_cert.pem")), + [{_, IDPCert, _}] = public_key:pem_decode(IDPPemCert), + + {ok, SignPemCert} = file:read_file(filename:join(Datadir, "crl_signer.pem")), + [{_, SignCert, _}] = public_key:pem_decode(SignPemCert), + + OTPIDPCert = public_key:pkix_decode_cert(IDPCert, otp), + OTPSignCert = public_key:pkix_decode_cert(SignCert, otp), + ERLCRL = public_key:der_decode('CertificateList',CRL), + + {rdnSequence,_} = public_key:pkix_crl_issuer(CRL), + {rdnSequence,_} = public_key:pkix_crl_issuer(ERLCRL), + + true = public_key:pkix_crl_verify(CRL, SignCert), + true = public_key:pkix_crl_verify(ERLCRL, OTPSignCert), + + [#'DistributionPoint'{}|_] = public_key:pkix_dist_points(IDPCert), + [#'DistributionPoint'{}|_] = public_key:pkix_dist_points(OTPIDPCert), + + #'DistributionPoint'{cRLIssuer = asn1_NOVALUE, + reasons = asn1_NOVALUE, + distributionPoint = Point} = public_key:pkix_dist_point(IDPCert), + #'DistributionPoint'{cRLIssuer = asn1_NOVALUE, + reasons = asn1_NOVALUE, + distributionPoint = Point} = public_key:pkix_dist_point(OTPIDPCert). + +%%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- asn1_encode_decode({Asn1Type, Der, not_encrypted} = Entry) -> diff --git a/lib/public_key/test/public_key_SUITE_data/crl_signer.pem b/lib/public_key/test/public_key_SUITE_data/crl_signer.pem new file mode 100644 index 0000000000..d77f86b45d --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/crl_signer.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIID8zCCAtugAwIBAgIJAKU8w89SmyPyMA0GCSqGSIb3DQEBBAUAMIGGMREwDwYD +VQQDEwhlcmxhbmdDQTETMBEGA1UECxMKRXJsYW5nIE9UUDEUMBIGA1UEChMLRXJp +Y3Nzb24gQUIxEjAQBgNVBAcTCVN0b2NraG9sbTELMAkGA1UEBhMCU0UxJTAjBgkq +hkiG9w0BCQEWFnBldGVyQGVyaXguZXJpY3Nzb24uc2UwHhcNMTUwMjIzMTMyNTMx +WhcNMTUwMzI1MTMyNTMxWjCBhjERMA8GA1UEAxMIZXJsYW5nQ0ExEzARBgNVBAsT +CkVybGFuZyBPVFAxFDASBgNVBAoTC0VyaWNzc29uIEFCMRIwEAYDVQQHEwlTdG9j +a2hvbG0xCzAJBgNVBAYTAlNFMSUwIwYJKoZIhvcNAQkBFhZwZXRlckBlcml4LmVy +aWNzc29uLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyzwkmKzy +WTLOafHmgqZVENdt3OYECPA4BamVKyEdi8zgXI0S71wzPZ+XvuGbHDTBzsTHf71L +xRQgoG30tv5jqWSlfh8iyS6fO+FHxBKd+xg6hLJXk5PCUa5X1D4BO8B4aapEzev+ +T8+pTaOLeVPdfGfKp0yWF50eCpdSF/kMCCIIA8QNSahfcwuLbEEzUNZof6YPZBNm +e+XUMXCjpb/mU7krfu8nLaspG1HgxQqErEEBzGJE7mguqSVETK/xpGXEMTNIuj8N +ziFrfqAezDob3z48xHUaHKZRBb9NIxWIjVxkTYaqOtf9UNCT96CHeZ7rk9iNscQu +USabMIamFY8cNQIDAQABo2IwYDAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUm2M3f6UBEIsHI1HIvphbBz60RsAwIQYDVR0RBBowGIEWcGV0 +ZXJAZXJpeC5lcmljc3Nvbi5zZTANBgkqhkiG9w0BAQQFAAOCAQEAPmm0V36HZySF +BoV03DGyeFUSeMtO0DO058NaXXv2VNPpUXT72Mt1ovXNvVFcReggb01polF7TFFI +4NRb6qbsLPxny29Clf/9WKY4zDhbb2MIy8yueoOyyeNQtrzY+iQjo4q9U+Aa6xj1 +pxmG1URDfOmCgX33ItCrZXFGa4ic0HrbWgJMDNo4lSOiio8bl3IYN4vBcobRfhDs +pw5jochE5ZpPh4i76Pg6D99EFkNaLyQioWEu4n2OxR0EBSFLJkVJQ0alUx18AKio +bje+h5nzRgTm5HApYzcorF57KfUKPDaW1Q6tRckRyHApueDuK8p49ITQE71lmkLc +ywxoJMrNnA== +-----END CERTIFICATE----- + diff --git a/lib/public_key/test/public_key_SUITE_data/idp_cert.pem b/lib/public_key/test/public_key_SUITE_data/idp_cert.pem new file mode 100644 index 0000000000..c2afc56a3a --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/idp_cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGjCCBAKgAwIBAgIBAzANBgkqhkiG9w0BAQQFADCBgzEOMAwGA1UEAxMFb3Rw +Q0ExEzARBgNVBAsTCkVybGFuZyBPVFAxFDASBgNVBAoTC0VyaWNzc29uIEFCMQsw +CQYDVQQGEwJTRTESMBAGA1UEBxMJU3RvY2tob2xtMSUwIwYJKoZIhvcNAQkBFhZw +ZXRlckBlcml4LmVyaWNzc29uLnNlMB4XDTE1MDIyMzEzMjUzMVoXDTI1MDEwMTEz +MjUzMVowgYQxDzANBgNVBAMTBnNlcnZlcjETMBEGA1UECxMKRXJsYW5nIE9UUDEU +MBIGA1UEChMLRXJpY3Nzb24gQUIxCzAJBgNVBAYTAlNFMRIwEAYDVQQHEwlTdG9j +a2hvbG0xJTAjBgkqhkiG9w0BCQEWFnBldGVyQGVyaXguZXJpY3Nzb24uc2UwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK8EDdNZEebdfxb57e3UA8uTCq +TsFtJv5tyjnZtSFsGDrwrZYjRMOCJFh8Yv6Ddq4mZiAvUCJxMzW4zVzraMmmQC8z +Hi3xQyuIq2UCW3ESxLvchCcuSjNOWke0z+rXHzA8Yz9y1fqhhO6AF8q5lLwGo+VQ +sJkVV8QwB9UXZN4pAc3zTeqZkGCrNY/ZIgtCrk4jw7sY/gumS8BjhXCYGyFZRDvX +jzIXQx6jn7/2huNbEAiBXbYYAMd7OEwhpHHAWOVA6g+/TNydgRO3W4xVmlEhDpYs +bnMV/Tq570E1bhz1XWb642K2MnxI74g8FXmhN6x6P8d4zU/eFcs+gxO0X6KzAgMB +AAGjggGUMIIBkDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHQ4EFgQUo8dr +DDQXK25dB6qMY8dNIjAKIPEwgbMGA1UdIwSBqzCBqIAU5YMIq7A5eYQhQsHsc/XC +7GeZ+kuhgYykgYkwgYYxETAPBgNVBAMTCGVybGFuZ0NBMRMwEQYDVQQLEwpFcmxh +bmcgT1RQMRQwEgYDVQQKEwtFcmljc3NvbiBBQjESMBAGA1UEBxMJU3RvY2tob2xt +MQswCQYDVQQGEwJTRTElMCMGCSqGSIb3DQEJARYWcGV0ZXJAZXJpeC5lcmljc3Nv +bi5zZYIBATAhBgNVHREEGjAYgRZwZXRlckBlcml4LmVyaWNzc29uLnNlMCEGA1Ud +EgQaMBiBFnBldGVyQGVyaXguZXJpY3Nzb24uc2UwWwYDVR0fBFQwUjAkoCKgIIYe +aHR0cDovL2xvY2FsaG9zdC9vdHBDQS9jcmwucGVtMCqgKKAmhiRodHRwOi8vbG9j +YWxob3N0OjM3ODEzL290cENBL2NybC5wZW0wDQYJKoZIhvcNAQEEBQADggEBACwq +o4nQTTereSIL8ZLQHweJKXYstTaZrRrAaoRUe9oClY7H++zXmMa8iZvUqqdT3fXW +4KMXXyoB1o+cLxLnAPKOiFFL9rcbaeAMxZMIrTaFDQsOXAPVqJLSWWS5I5LsNvS6 +MlB6O6+0binTyilDKg683VV9nKNiNdL8WzGa5ig+HvK6xUpJwpOTmDmfdg09zQ+8 +aCbJrthXg0tNnGIorttAd2wFvmLUezoJrlfwLChB0M/qa+RVRCFMiPvkWupo5eVK +Malwpz2xp2rAUlb6qQY7eI6lV8JsVK06QxBmUHP68Y9kYT5/gy5ketjOB0Ypin05 +6+3VrZKFxrkqKaEoL50= +-----END CERTIFICATE----- diff --git a/lib/public_key/test/public_key_SUITE_data/idp_crl.pem b/lib/public_key/test/public_key_SUITE_data/idp_crl.pem new file mode 100644 index 0000000000..0872279501 --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/idp_crl.pem @@ -0,0 +1,18 @@ +-----BEGIN X509 CRL----- +MIIC3TCCAcUCAQEwDQYJKoZIhvcNAQEEBQAwgYYxETAPBgNVBAMTCGVybGFuZ0NB +MRMwEQYDVQQLEwpFcmxhbmcgT1RQMRQwEgYDVQQKEwtFcmljc3NvbiBBQjESMBAG +A1UEBxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTElMCMGCSqGSIb3DQEJARYWcGV0 +ZXJAZXJpeC5lcmljc3Nvbi5zZRcNMTUwMjIzMTMyNTMxWhcNMTUwMjI0MTMyNTMx +WqCCAQgwggEEMIG7BgNVHSMEgbMwgbCAFJtjN3+lARCLByNRyL6YWwc+tEbAoYGM +pIGJMIGGMREwDwYDVQQDEwhlcmxhbmdDQTETMBEGA1UECxMKRXJsYW5nIE9UUDEU +MBIGA1UEChMLRXJpY3Nzb24gQUIxEjAQBgNVBAcTCVN0b2NraG9sbTELMAkGA1UE +BhMCU0UxJTAjBgkqhkiG9w0BCQEWFnBldGVyQGVyaXguZXJpY3Nzb24uc2WCCQCl +PMPPUpsj8jA4BgNVHRwBAf8ELjAsoCqgKIYmaHR0cDovL2xvY2FsaG9zdDo4MDAw +L2VybGFuZ0NBL2NybC5wZW0wCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEEBQADggEB +AE9WKJhW1oivBEE91akeDcYCtSVp98F7DxzQyJTBLQJGMEXSg8G/oAp64F4qs3oV +LXS5YFYwxjD9tXByGVEJoIUUMtfMeCvZMgd2V8mBlAJiyHkTrFFA8PgBv+htrJji +nrheAhrEedqZbqwmrcU34h9fWHp0Zl6UDYyF3I/S0/5ilIz3DvNZ9SBfKKt3DYeW +hon7qpNo6YrtEzbXyOaa2mFX9c1w39LBZ1FdY0jEzUfh2eImBLxnBjZArNxzYuU8 +a+lNMjc6JUAJwITS6C1YfI4ECsqXe0K/n90pMcm/jgiGFCZhVbXq+Nrm/24qPKBA +zqoNos7aV7LEYLYOjknaIhY= +-----END X509 CRL----- diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index 9b026aee11..2877355718 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -31,6 +31,23 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> +<section><title>Runtime_Tools 1.8.15</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Add <c>nif_version</c> to <c>erlang:system_info/1</c> in + order to get the NIF API version of the runtime system in + a way similar to <c>driver_version</c>.</p> + <p> + Own Id: OTP-12298</p> + </item> + </list> + </section> + +</section> + <section><title>Runtime_Tools 1.8.14</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl index 186563ab74..c2de57d40b 100644 --- a/lib/runtime_tools/src/dbg.erl +++ b/lib/runtime_tools/src/dbg.erl @@ -778,50 +778,50 @@ tracer_init(Handler, HandlerData) -> tracer_loop(Handler, HandlerData). tracer_loop(Handler, Hdata) -> - receive - Msg -> - %% Don't match in receive to avoid giving EXIT message higher - %% priority than the trace messages. - case Msg of - {'EXIT',_Pid,_Reason} -> - ok; - Trace -> - NewData = recv_all_traces(Trace, Handler, Hdata), - tracer_loop(Handler, NewData) - end + {State, Suspended, Traces} = recv_all_traces(), + NewHdata = handle_traces(Suspended, Traces, Handler, Hdata), + case State of + done -> + exit(normal); + loop -> + tracer_loop(Handler, NewHdata) end. - -recv_all_traces(Trace, Handler, Hdata) -> - Suspended = suspend(Trace, []), - recv_all_traces(Suspended, Handler, Hdata, [Trace]). -recv_all_traces(Suspended0, Handler, Hdata, Traces) -> +recv_all_traces() -> + recv_all_traces([], [], infinity). + +recv_all_traces(Suspended0, Traces, Timeout) -> receive Trace when is_tuple(Trace), element(1, Trace) == trace -> Suspended = suspend(Trace, Suspended0), - recv_all_traces(Suspended, Handler, Hdata, [Trace|Traces]); + recv_all_traces(Suspended, [Trace|Traces], 0); Trace when is_tuple(Trace), element(1, Trace) == trace_ts -> Suspended = suspend(Trace, Suspended0), - recv_all_traces(Suspended, Handler, Hdata, [Trace|Traces]); + recv_all_traces(Suspended, [Trace|Traces], 0); Trace when is_tuple(Trace), element(1, Trace) == seq_trace -> Suspended = suspend(Trace, Suspended0), - recv_all_traces(Suspended, Handler, Hdata, [Trace|Traces]); + recv_all_traces(Suspended, [Trace|Traces], 0); Trace when is_tuple(Trace), element(1, Trace) == drop -> Suspended = suspend(Trace, Suspended0), - recv_all_traces(Suspended, Handler, Hdata, [Trace|Traces]); + recv_all_traces(Suspended, [Trace|Traces], 0); + {'EXIT', _Pid, _Reason} -> + {done, Suspended0, Traces}; Other -> %%% Is this really a good idea? io:format(user,"** tracer received garbage: ~p~n", [Other]), - recv_all_traces(Suspended0, Handler, Hdata, Traces) - after 0 -> - case catch invoke_handler(Traces, Handler, Hdata) of - {'EXIT',Reason} -> - resume(Suspended0), - exit({trace_handler_crashed,Reason}); - NewHdata -> - resume(Suspended0), - NewHdata - end + recv_all_traces(Suspended0, Traces, Timeout) + after Timeout -> + {loop, Suspended0, Traces} + end. + +handle_traces(Suspended, Traces, Handler, Hdata) -> + case catch invoke_handler(Traces, Handler, Hdata) of + {'EXIT',Reason} -> + resume(Suspended), + exit({trace_handler_crashed,Reason}); + NewHdata -> + resume(Suspended), + NewHdata end. invoke_handler([Tr|Traces], Handler, Hdata0) -> diff --git a/lib/runtime_tools/src/system_information.erl b/lib/runtime_tools/src/system_information.erl index f541d6e449..04cc33e1ad 100644 --- a/lib/runtime_tools/src/system_information.erl +++ b/lib/runtime_tools/src/system_information.erl @@ -371,6 +371,7 @@ erlang_system_info() -> logical_processors_online, logical_processors_available, driver_version, + nif_version, emu_args, ethread_info, beam_jump_table, diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl index dfae52ed1d..0bcbd67d05 100644 --- a/lib/runtime_tools/test/dbg_SUITE.erl +++ b/lib/runtime_tools/test/dbg_SUITE.erl @@ -25,7 +25,7 @@ ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1, ip_port_busy/1, wrap_port/1, wrap_port_time/1, with_seq_trace/1, dead_suspend/1, local_trace/1, - saved_patterns/1]). + saved_patterns/1, tracer_exit_on_stop/1]). -export([init_per_testcase/2, end_per_testcase/2]). -export([tracee1/1, tracee2/1]). -export([dummy/0, exported/1]). @@ -47,7 +47,7 @@ all() -> [big, tiny, simple, message, distributed, ip_port, file_port, file_port2, file_port_schedfix, ip_port_busy, wrap_port, wrap_port_time, with_seq_trace, dead_suspend, - local_trace, saved_patterns]. + local_trace, saved_patterns, tracer_exit_on_stop]. groups() -> []. @@ -742,6 +742,38 @@ run_dead_suspend() -> dummy() -> ok. +%% Test that a tracer process does not ignore an exit signal message when it has +%% received (but not handled) trace messages +tracer_exit_on_stop(_) -> + %% Tracer blocks waiting for fun to complete so that the trace message and + %% the exit signal message from the dbg process are in its message queue. + Fun = fun() -> + ?MODULE:dummy(), + Ref = erlang:trace_delivered(self()), + receive {trace_delivered, _, Ref} -> stop() end + end, + {ok, _} = dbg:tracer(process, {fun spawn_once_handler/2, {self(), Fun}}), + {ok, Tracer} = dbg:get_tracer(), + MRef = monitor(process, Tracer), + {ok, _} = dbg:p(self(), [call]), + {ok, _} = dbg:p(new, [call]), + {ok, _} = dbg:tp(?MODULE, dummy, []), + ?MODULE:dummy(), + receive {'DOWN', MRef, _, _, normal} -> ok end, + [{trace,_,call,{?MODULE, dummy,[]}}, + {trace,_,call,{?MODULE, dummy,[]}}] = flush(), + ok. + +spawn_once_handler(Event, {Pid, done} = State) -> + Pid ! Event, + State; +spawn_once_handler(Event, {Pid, Fun}) -> + {_, Ref} = spawn_monitor(Fun), + receive + {'DOWN', Ref, _, _, _} -> + Pid ! Event, + {Pid, done} + end. %% %% Support functions diff --git a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat index 18938372a3..bdc510e838 100644 --- a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat +++ b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat @@ -9720,6 +9720,7 @@ {logical_processors_online,4}, {logical_processors_available,4}, {driver_version,"2.1"}, + {nif_version,"1.1"}, {taints,[]}]}, {erts_compile_info, [{ldflags,[]}, diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 32953dfc5a..c1df23d2a2 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.8.14 +RUNTIME_TOOLS_VSN = 1.8.15 diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index bd7414fbb4..b7c5f34f58 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2014. All Rights Reserved. +%% Copyright Ericsson AB 2011-2015. 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 @@ -1802,11 +1802,17 @@ upgrade_gg(cleanup,Config) -> %%%----------------------------------------------------------------- %%% OTP-10463, Bug - release_handler could not handle regexp in appup %%% files. -otp_10463_upgrade_script_regexp(_Config) -> - %% Assuming that kernel always has a regexp in it's appup - KernelVsn = vsn(kernel,current), - {ok,KernelVsn,_} = - release_handler:upgrade_script(kernel,code:lib_dir(kernel)), +otp_10463_upgrade_script_regexp(Config) -> + DataDir = ?config(data_dir,Config), + code:add_path(filename:join([DataDir,regexp_appup,app1,ebin])), + application:start(app1), + {ok,"1.1",_} = release_handler:upgrade_script(app1,code:lib_dir(app1)), + ok. + +otp_10463_upgrade_script_regexp(cleanup,Config) -> + DataDir = ?config(data_dir,Config), + application:stop(app1), + code:del_path(filename:join([DataDir,regexp_appup,app1,ebin])), ok. no_dot_erlang(Conf) -> diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app new file mode 100644 index 0000000000..ba6d09cd42 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.app @@ -0,0 +1,29 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2015. 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% +%% +%% This is an -*- erlang -*- file. +%% +{application, app1, + [ + {description, "Test that release_handler can read appup with regexp"}, + {vsn, "1.1"}, + {modules, []}, + {registered, []}, + {applications, []} + ] +}. diff --git a/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup new file mode 100644 index 0000000000..9c657232d0 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/regexp_appup/app1/ebin/app1.appup @@ -0,0 +1,23 @@ +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2015. 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% +{"1.1", + %% Up from + [{<<"1(\\.[0-9]+)*">>,[{restart_application,app1}]}], + %% Down to + [{<<"1(\\.[0-9]+)*">>,[{restart_application,app1}]}] +}. diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index bbe6438f04..fd307ef824 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,6 +33,69 @@ </header> + <section> + <title>SNMP Development Toolkit 5.1.1</title> + <p>Version 5.1.1 supports code replacement in runtime from/to + version 5.1. </p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[compiler] Refinement of type Opaque was not allowed. </p> + <p>MIB constructs such as '<c>SYNTAX Opaque (SIZE(0..65535))</c>' + was previously not allowed, + see the standard <c>ALARM-MIB</c> for eaxmple. </p> + <p>Own Id: OTP-12066</p> + <p>Aux Id: Seq 12669</p> + </item> + + </list> + + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[agent] + see <seealso marker="snmpa#load_mibs">load_mibs</seealso> and + <seealso marker="snmpa#unload_mibs">unload_mibs</seealso>. </p> + <p>Own Id: OTP-11216</p> + </item> + + </list> +--> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[manager] The old Addr-and-Port based API functions, previously + long deprecated and marked for deletion in R16B, has now been + removed. </p> + <p>Own Id: OTP-10027</p> + </item> + + </list> +--> + </section> + </section> <!-- 5.1.1 --> + + + <section><title>SNMP 5.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 1cc1a17b1d..e7e54f5b7e 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -28,9 +28,12 @@ %% {update, snmpa_local_db, soft, soft_purge, soft_purge, []} %% {add_module, snmpm_net_if_mt} [ + {"5.1", [ % Only compiler changes + ]}, {"5.0", [{restart_application, snmp}]}, {"4.25.1", [{restart_application, snmp}]}, {"4.25.0.1", [{restart_application, snmp}]}, + {"4.25.0.0.1", [{restart_application, snmp}]}, {"4.25", [{restart_application, snmp}]}, {"4.24.2", [{restart_application, snmp}]}, {"4.24.1", [{restart_application, snmp}]}, @@ -43,9 +46,12 @@ %% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} [ + {"5.1", [ % Only compiler changes + ]}, {"5.0", [{restart_application, snmp}]}, {"4.25.1", [{restart_application, snmp}]}, {"4.25.0.1", [{restart_application, snmp}]}, + {"4.25.0.0.1", [{restart_application, snmp}]}, {"4.25", [{restart_application, snmp}]}, {"4.24.2", [{restart_application, snmp}]}, {"4.24.1", [{restart_application, snmp}]}, diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 5a661cf194..0f6393eeef 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -139,6 +139,7 @@ allow_size_rfc1902('Integer32') -> true; allow_size_rfc1902('Unsigned32') -> true; allow_size_rfc1902('OCTET STRING') -> true; allow_size_rfc1902('Gauge32') -> true; +allow_size_rfc1902('Opaque') -> true; allow_size_rfc1902(_) -> false. guess_integer_type() -> diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index cb72871177..b4cc165d2e 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -319,7 +319,7 @@ socket_open(IpPort, SocketOpts) -> Socket end. -socket_params(Domain, {IpAddr, IpPort}, BindTo, CommonSocketOpts) -> +socket_params(Domain, {IpAddr, IpPort} = Addr, BindTo, CommonSocketOpts) -> Family = snmp_conf:tdomain_to_family(Domain), SocketOpts = case Family of @@ -340,15 +340,18 @@ socket_params(Domain, {IpAddr, IpPort}, BindTo, CommonSocketOpts) -> {0, [{fd, Fd} | SocketOpts]} end; error -> - {IpPort, [{ip, IpAddr} | SocketOpts]} + socket_params(SocketOpts, Addr, BindTo) end; _ -> - case BindTo of - true -> - {IpPort, [{ip, IpAddr} | SocketOpts]}; - _ -> - {IpPort, SocketOpts} - end + socket_params(SocketOpts, Addr, BindTo) + end. +%% +socket_params(SocketOpts, {IpAddr, IpPort}, BindTo) -> + case BindTo of + true -> + {IpPort, [{ip, IpAddr} | SocketOpts]}; + _ -> + {IpPort, SocketOpts} end. common_socket_opts(Opts) -> diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl index cf62edba1c..8cb6ec588e 100644 --- a/lib/snmp/test/snmp_test_mgr.erl +++ b/lib/snmp/test/snmp_test_mgr.erl @@ -161,7 +161,7 @@ get_timeout() -> get_timeout(os:type()) end. -get_timeout(_) -> 3500. +get_timeout(_) -> 10000. % Trying to improve test results % 3500. %%---------------------------------------------------------------------- %% Receives a trap from the agent. diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index b436a79076..345cc790f2 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 5.1 +SNMP_VSN = 5.1.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 3da3ca3ec8..3aa61aa9ec 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -29,6 +29,115 @@ <file>notes.xml</file> </header> +<section><title>Ssh 3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure the clean rule for ssh, ssl, eunit and otp_mibs + actually removes generated files.</p> + <p> + Own Id: OTP-12200</p> + </item> + <item> + <p> + Improved Property Tests (Thanks to Thomas, John and + Tobias at QuviQ)</p> + <p> + Own Id: OTP-12256</p> + </item> + <item> + <p> + Correct typo of renegotiate that could cause rekeying to + fail</p> + <p> + Own Id: OTP-12277 Aux Id: seq12736 </p> + </item> + <item> + <p> + The {timeout, Timeout} option passed to + ssh_sftp:start_channel was not applied to the early + phases of the SSH protocol. This patch passes the Timeout + through to ssh:connect. In case the timeout occurs during + these phases, {error, timeout} is returned. (Thanks to + Simon Cornish)</p> + <p> + Own Id: OTP-12306</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added API functions ptty_alloc/3 and ptty_alloc/4, to + allocate a pseudo tty.</p> + <p> + Own Id: OTP-11542 Aux Id: seq12493, OTP-11631 </p> + </item> + <item> + <p> + Supports tar file creation on other media than file + systems mounted on the local machine.</p> + <p> + The <c>erl_tar</c> api is extended with + <c>erl_tar:init/3</c> that enables usage of user provided + media storage routines. A ssh-specific set of such + routines is hidden in the new function + <c>ssh_sftp:open_tar/3</c> to simplify creating a tar + archive on a remote ssh server.</p> + <p> + A chunked file reading option is added to + <c>erl_tar:add/3,4</c> to save memory on e.g small + embedded systems. The size of the slices read from a file + in that case can be specified.</p> + <p> + Own Id: OTP-12180 Aux Id: seq12715 </p> + </item> + <item> + <p> + Always send SSH_DISCONNECT protocol messages when peer + sends corrupt messages.</p> + <p> + Own Id: OTP-12185</p> + </item> + <item> + <p> + Hooks for funs that can change binaries sent to remote + sites from erl_tar for renote tar file creation are + added. See <c>ssh_sftp:open_tar/3,4</c> for details. The + hooks could also be used to read remote tar files that + need transformation before file extraction.</p> + <p> + Those hooks are intended for encryption and decryption of + tar files. Effort is put into memory, disk and network + resource economy.</p> + <p> + Own Id: OTP-12312 Aux Id: OTP-12180 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 3.0.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixes of login blocking after port scanning.</p> + <p> + Own Id: OTP-12247 Aux Id: seq12726 </p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 3.0.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index 9f5d1c003d..d481a75c9a 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -234,11 +234,11 @@ <taglist> <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag> <item> IP version to use when the host address is specified as <c>any</c>. </item> - <tag><c><![CDATA[{subsystems, [subsystem_spec()]]]></c></tag> + <tag><c><![CDATA[{subsystems, [subsystem_spec()]}]]></c></tag> <item> Provides specifications for handling of subsystems. The "sftp" subsystem spec can be retrieved by calling - ssh_sftpd:subsystem_spec/1. If the subsystems option in + ssh_sftpd:subsystem_spec/1. If the subsystems option is not present the value of <c>[ssh_sftpd:subsystem_spec([])]</c> will be used. It is of course possible to set the option to the empty list if diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml index 72e7252536..5e2926dfa6 100644 --- a/lib/ssh/doc/src/ssh_connection.xml +++ b/lib/ssh/doc/src/ssh_connection.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2008</year> - <year>2013</year> + <year>2014</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -62,6 +62,7 @@ <p><c>ssh_request_status() = success | failure</c></p> <p><c>event() = {ssh_cm, ssh_connection_ref(), ssh_event_msg()} </c></p> <p><c>ssh_event_msg() = data_events() | status_events() | terminal_events() </c></p> + <p><c>reason() = timeout | closed </c></p> <taglist> <tag><b>data_events()</b></tag> @@ -137,7 +138,7 @@ <tag><c><![CDATA[{pty, ssh_channel_id(), boolean() = WantReply, {string() = Terminal, integer() = CharWidth, - integer() = RowHeight, integer() = PixelWidth, integer() = PixelHight, + integer() = RowHeight, integer() = PixelWidth, integer() = PixelHeight, [{atom() | integer() = Opcode, integer() = Value}] = TerminalModes}}]]></c></tag> <item>A pseudo-terminal has been requested for the @@ -148,11 +149,11 @@ drawable area of the window. The <c>Opcode</c> in the <c>TerminalModes</c> list is the mnemonic name, represented as an lowercase erlang atom, defined in - <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8, - or the opcode if the mnemonic name is not listed in the + <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8. + It may also be an opcode if the mnemonic name is not listed in the RFC. Example <c>OP code: 53, mnemonic name ECHO erlang atom: - echo</c>. There is currently no API function to generate this - event.</item> + echo</c>.This event is sent as result of calling <seealso + marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso></item> <tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag> <item> This message will request that the user's default shell @@ -218,7 +219,7 @@ </func> <func> - <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() </name> + <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | {error, reason()} </name> <fsummary>Request that the server start the execution of the given command. </fsummary> <type> <v> ConnectionRef = ssh_connection_ref() </v> @@ -273,7 +274,53 @@ </desc> </func> - <func> + <func> + <name>ptty_alloc(ConnectionRef, ChannelId, Options) -> </name> + <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | {error, reason()} </name> + <fsummary>Send status replies to requests that want such replies. </fsummary> + <type> + <v> ConnectionRef = ssh_connection_ref() </v> + <v> ChannelId = ssh_channel_id()</v> + <v> Options = proplists:proplist()</v> + </type> + <desc> + <p> Sends a SSH Connection Protocol pty_req, to allocate a pseudo tty. + Should be called by a SSH client process. + Options are: + </p> + + <taglist> + <tag>{term, string()}</tag> + <item> + Defaults to os:getenv("TERM") or "vt100" if it is undefined. + </item> + <tag>{width, integer()}</tag> + <item> + Defaults to 80 if pixel_width is not defined. + </item> + <tag>{height, integer()}</tag> + <item> + Defaults to 24 if pixel_height is not defined. + </item> + <tag>{pixel_width, integer()}</tag> + <item> + Is disregarded if width is defined. + </item> + <tag>{pixel_height, integer()}</tag> + <item> + Is disregarded if height is defined. + </item> + <tag>{pty_opts, [{posix_atom(), integer()}]}</tag> + <item> + Option may be an empty list, otherwise + see possible POSIX names in section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>. + </item> + </taglist> + + </desc> + </func> + + <func> <name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name> <fsummary>Send status replies to requests that want such replies. </fsummary> <type> @@ -329,7 +376,7 @@ <func> <name>session_channel(ConnectionRef, Timeout) -> </name> <name>session_channel(ConnectionRef, InitialWindowSize, - MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, Reason}</name> + MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, reason()}</name> <fsummary>Opens a channel for a ssh session. </fsummary> <type> <v> ConnectionRef = ssh_connection_ref()</v> @@ -346,7 +393,7 @@ </func> <func> - <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status()</name> + <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | {error, reason()} </name> <fsummary> Environment variables may be passed to the shell/command to be started later.</fsummary> <type> @@ -364,7 +411,7 @@ </func> <func> - <name>shell(ConnectionRef, ChannelId) -> ssh_request_status() + <name>shell(ConnectionRef, ChannelId) -> ssh_request_status() | {error, closed} </name> <fsummary> Requests that the user's default shell (typically defined in /etc/passwd in UNIX systems) shall be executed at the server @@ -381,7 +428,7 @@ </func> <func> - <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status()</name> + <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | {error, reason()} </name> <fsummary> </fsummary> <type> <v> ConnectionRef = ssh_connection_ref() </v> diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml index f1091e9eca..ab111562f9 100644 --- a/lib/ssh/doc/src/ssh_sftp.xml +++ b/lib/ssh/doc/src/ssh_sftp.xml @@ -194,6 +194,118 @@ can be used for reading directory contents.</p> </desc> </func> + + <func> + <name>open_tar(ChannelPid, Path, Mode) -></name> + <name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Opens a tar file on the server to which <v>ChannelPid</v> is connected and returns a handle</fsummary> + <type> + <v>ChannelPid = pid()</v> + <v>Path = string()</v> + <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt] </v> + <v>EncryptOpt = {crypto,{InitFun,EncryptFun,CloseFun}}</v> + <v>DecryptOpt = {crypto,{InitFun,DecryptFun}}</v> + <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize}) </v> + <v>CryptoState = any()</v> + <v>ChunkSize = undefined | pos_integer()</v> + <v>EncryptFun = (fun(PlainBin,CryptoState) -> EncryptResult)</v> + <v>EncryptResult = {ok,EncryptedBin,CryptoState} | {ok,EncryptedBin,CryptoState,ChunkSize}</v> + <v>PlainBin = binary()</v> + <v>EncryptedBin = binary()</v> + <v>DecryptFun = (fun(EncryptedBin,CryptoState) -> DecryptResult)</v> + <v>DecryptResult = {ok,PlainBin,CryptoState} | {ok,PlainBin,CryptoState,ChunkSize}</v> + <v>CloseFun = (fun(PlainBin,CryptoState) -> {ok,EncryptedBin})</v> + <v>Timeout = timeout()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Opens a handle to a tar file on the server associated with <c>ChannelPid</c>. The handle + can be used for remote tar creation and extraction as defined by the + <seealso marker="stdlib:erl_tar#init/3">erl_tar:init/3</seealso> function. + </p> + <p>An example of writing and then reading a tar file:</p> + <code type="none"> + {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]), + ok = erl_tar:add(HandleWrite, .... ), + ok = erl_tar:add(HandleWrite, .... ), + ... + ok = erl_tar:add(HandleWrite, .... ), + ok = erl_tar:close(HandleWrite), + + %% And for reading + {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]), + {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]), + ok = erl_tar:close(HandleRead), + </code> + + <p>The <c>crypto</c> mode option is applied to the generated stream of bytes just prior to sending + them to the sftp server. This is intended for encryption but could of course be used for other + purposes. + </p> + <p>The <c>InitFun</c> is applied once + prior to any other crypto operation. The returned <c>CryptoState</c> is then folded into + repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned + from those Funs are sent further to the remote sftp server. Finally - if doing encryption + - the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is + responsible for padding (if needed) and encryption of that last piece. + </p> + <p>The <c>ChunkSize</c> defines the size of the <c>PlainBin</c>s that <c>EncodeFun</c> is applied + to. If the <c>ChunkSize</c> is <c>undefined</c> the size of the <c>PlainBin</c>s varies because + this is inteded for stream crypto while a fixed <c>ChunkSize</c> is intended for block crypto. It + is possible to change the <c>ChunkSize</c>s in the return from the <c>EncryptFun</c> or + <c>DecryptFun</c>. It is in fact possible to change the value between <c>pos_integer()</c> and + <c>undefined</c>. + </p> + <p>The write and read example above can be extended with encryption and decryption:</p> + <code type="none"> + %% First three parameters depending on which crypto type we select: + Key = <<"This is a 256 bit key. abcdefghi">>, + Ivec0 = crypto:rand_bytes(16), + DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc + + %% Initialization of the CryptoState, in this case it is the Ivector. + InitFun = fun() -> {ok, Ivec0, DataSize} end, + + %% How to encrypt: + EncryptFun = + fun(PlainBin,Ivec) -> + EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin), + {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)} + end, + + %% What to do with the very last block: + CloseFun = + fun(PlainBin, Ivec) -> + EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, + pad(16,PlainBin) %% Last chunk + ), + {ok, EncryptedBin} + end, + + Cw = {InitFun,EncryptFun,CloseFun}, + {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]), + ok = erl_tar:add(HandleWrite, .... ), + ok = erl_tar:add(HandleWrite, .... ), + ... + ok = erl_tar:add(HandleWrite, .... ), + ok = erl_tar:close(HandleWrite), + + %% And for decryption (in this crypto example we could use the same InitFun + %% as for encryption): + DecryptFun = + fun(EncryptedBin,Ivec) -> + PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin), + {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)} + end, + + Cr = {InitFun,DecryptFun}, + {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]), + {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]), + ok = erl_tar:close(HandleRead), + </code> + </desc> + </func> + <func> <name>close(ChannelPid, Handle) -> </name> <name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name> diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml index 9ab71260d3..46178d4018 100644 --- a/lib/ssh/doc/src/using_ssh.xml +++ b/lib/ssh/doc/src/using_ssh.xml @@ -79,7 +79,7 @@ <p> The option user_dir defaults to the users ~/.ssh directory</p> <p>In the following example we generate new keys and host keys as - to be able to run the example without having root privilages</p> + to be able to run the example without having root privileges</p> <code> $bash> ssh-keygen -t rsa -f /tmp/ssh_daemon/ssh_host_rsa_key diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile index 53c755d3cb..90d71107ad 100644 --- a/lib/ssh/src/Makefile +++ b/lib/ssh/src/Makefile @@ -65,6 +65,7 @@ MODULES= \ ssh_cli \ ssh_file \ ssh_io \ + ssh_info \ ssh_math \ ssh_message \ ssh_no_io \ diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src index e0a51b3574..bc01c539e0 100644 --- a/lib/ssh/src/ssh.app.src +++ b/lib/ssh/src/ssh.app.src @@ -23,6 +23,7 @@ sshd_sup, ssh_file, ssh_io, + ssh_info, ssh_math, ssh_no_io, ssh_server_key_api, @@ -39,7 +40,7 @@ {applications, [kernel, stdlib, crypto, public_key]}, {env, []}, {mod, {ssh_app, []}}, - {runtime_dependencies, ["stdlib-2.0","public_key-0.22","kernel-3.0", + {runtime_dependencies, ["stdlib-2.3","public_key-0.22","kernel-3.0", "erts-6.0","crypto-3.3"]}]}. diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 42603cc23c..b2b2994eed 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -19,7 +19,28 @@ {"%VSN%", [ + {"3.0.8", [{load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_xfer]}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_xfer, soft_purge, soft_purge, []} + ]}, + {"3.0.7", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh_info, soft_purge, soft_purge, []}, + {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]}, {"3.0.6", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh_info, soft_purge, soft_purge, []}, {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]}, {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]}, {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]}, @@ -27,7 +48,28 @@ {<<".*">>, [{restart_application, ssh}]} ], [ + {"3.0.8", [{load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_sftp, soft_purge, soft_purge, []}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh, soft_purge, soft_purge, []}, + {load_module, ssh_xfer, soft_purge, soft_purge, []} + ]}, + {"3.0.7", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh_info, soft_purge, soft_purge, []}, + {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_xfer, soft_purge, soft_purge, [ssh_connection_handler]}]}, {"3.0.6", [{load_module, ssh_auth, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_acceptor, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_channel, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection, soft_purge, soft_purge, [ssh_connection_handler]}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, + {load_module, ssh_info, soft_purge, soft_purge, []}, {load_module, ssh_message, soft_purge, soft_purge, [ssh_connection_handler]}, {load_module, ssh_io, soft_purge, soft_purge, [ssh_connection_handler]}, {load_module, ssh_sftp, soft_purge, soft_purge, [ssh_connection_handler]}, diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index de047d3c83..eae33e3683 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -194,6 +194,7 @@ shell(Host, Port, Options) -> {ok, ConnectionRef} -> case ssh_connection:session_channel(ConnectionRef, infinity) of {ok,ChannelId} -> + success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, []), Args = [{channel_cb, ssh_shell}, {init_args,[ConnectionRef, ChannelId]}, {cm, ConnectionRef}, {channel_id, ChannelId}], diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl index 7302196674..6c443eeb9c 100644 --- a/lib/ssh/src/ssh_acceptor.erl +++ b/lib/ssh/src/ssh_acceptor.erl @@ -22,7 +22,8 @@ -module(ssh_acceptor). %% Internal application API --export([start_link/5]). +-export([start_link/5, + number_of_connections/1]). %% spawn export -export([acceptor_init/6, acceptor_loop/6]). @@ -140,5 +141,6 @@ handle_error(Reason) -> number_of_connections(SystemSup) -> length([X || {R,X,supervisor,[ssh_subsystem_sup]} <- supervisor:which_children(SystemSup), + is_pid(X), is_reference(R) ]). diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index b4d406ba8d..45c4d52d7e 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -184,9 +184,8 @@ handle_userauth_request(#ssh_msg_service_request{name = handle_userauth_request(#ssh_msg_userauth_request{user = User, service = "ssh-connection", method = "password", - data = Data}, _, + data = <<?FALSE, ?UINT32(Sz), BinPwd:Sz/binary>>}, _, #ssh{opts = Opts} = Ssh) -> - <<_:8, ?UINT32(Sz), BinPwd:Sz/binary>> = Data, Password = unicode:characters_to_list(BinPwd), case check_password(User, Password, Opts) of true -> @@ -201,6 +200,27 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User, handle_userauth_request(#ssh_msg_userauth_request{user = User, service = "ssh-connection", + method = "password", + data = <<?TRUE, + _/binary + %% ?UINT32(Sz1), OldBinPwd:Sz1/binary, + %% ?UINT32(Sz2), NewBinPwd:Sz2/binary + >> + }, _, + Ssh) -> + %% Password change without us having sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ (because we never do) + %% RFC 4252 says: + %% SSH_MSG_USERAUTH_FAILURE without partial success - The password + %% has not been changed. Either password changing was not supported, + %% or the old password was bad. + + {not_authorized, {User, {error,"Password change not supported"}}, + ssh_transport:ssh_packet(#ssh_msg_userauth_failure{ + authentications = "", + partial_success = false}, Ssh)}; + +handle_userauth_request(#ssh_msg_userauth_request{user = User, + service = "ssh-connection", method = "none"}, _, #ssh{userauth_supported_methods = Methods} = Ssh) -> {not_authorized, {User, undefined}, diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl index 508ae637cf..5c24f362b1 100644 --- a/lib/ssh/src/ssh_channel.erl +++ b/lib/ssh/src/ssh_channel.erl @@ -67,7 +67,8 @@ %% Internal application API -export([cache_create/0, cache_lookup/2, cache_update/2, cache_delete/1, cache_delete/2, cache_foldl/3, - cache_find/2]). + cache_find/2, + get_print_info/1]). -record(state, { cm, @@ -190,6 +191,14 @@ init([Options]) -> %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- +handle_call(get_print_info, _From, State) -> + Reply = + {{State#state.cm, + State#state.channel_id}, + io_lib:format('CB=~p',[State#state.channel_cb]) + }, + {reply, Reply, State}; + handle_call(Request, From, #state{channel_cb = Module, channel_state = ChannelState} = State) -> try Module:handle_call(Request, From, ChannelState) of @@ -333,6 +342,9 @@ cache_find(ChannelPid, Cache) -> Channel end. +get_print_info(Pid) -> + call(Pid, get_print_info, 1000). + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl index 9307dbbad0..d14f7ce27d 100644 --- a/lib/ssh/src/ssh_connect.hrl +++ b/lib/ssh/src/ssh_connect.hrl @@ -165,6 +165,10 @@ recipient_channel }). +-define(TERMINAL_WIDTH, 80). +-define(TERMINAL_HEIGHT, 24). +-define(DEFAULT_TERMINAL, "vt100"). + -define(TTY_OP_END,0). %% Indicates end of options. -define(VINTR,1). %% Interrupt character; 255 if none. Similarly for the %% other characters. Not all of these characters are diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index 87f37b93ef..c66f810948 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2014. 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 @@ -32,11 +32,11 @@ %% API -export([session_channel/2, session_channel/4, exec/4, shell/2, subsystem/4, send/3, send/4, send/5, - send_eof/2, adjust_window/3, setenv/5, close/2, reply_request/4]). + send_eof/2, adjust_window/3, setenv/5, close/2, reply_request/4, + ptty_alloc/3, ptty_alloc/4]). %% Potential API currently unsupported and not tested --export([open_pty/3, open_pty/7, - open_pty/9, window_change/4, window_change/6, +-export([window_change/4, window_change/6, direct_tcpip/6, direct_tcpip/8, tcpip_forward/3, cancel_tcpip_forward/3, signal/3, exit_status/3]). @@ -56,8 +56,8 @@ %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- --spec session_channel(pid(), timeout()) -> {ok, channel_id()} | {error, term()}. --spec session_channel(pid(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, term()}. +-spec session_channel(pid(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}. +-spec session_channel(pid(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}. %% Description: Opens a channel for a ssh session. A session is a %% remote execution of a program. The program may be a shell, an @@ -81,7 +81,8 @@ session_channel(ConnectionHandler, InitialWindowSize, end. %%-------------------------------------------------------------------- --spec exec(pid(), channel_id(), string(), timeout()) -> success | failure. +-spec exec(pid(), channel_id(), string(), timeout()) -> + success | failure | {error, timeout | closed}. %% Description: Will request that the server start the %% execution of the given command. @@ -101,21 +102,15 @@ shell(ConnectionHandler, ChannelId) -> ssh_connection_handler:request(ConnectionHandler, self(), ChannelId, "shell", false, <<>>, 0). %%-------------------------------------------------------------------- --spec subsystem(pid(), channel_id(), string(), timeout()) -> - success | failure | {error, timeout}. +-spec subsystem(pid(), channel_id(), string(), timeout()) -> + success | failure | {error, timeout | closed}. %% %% Description: Executes a predefined subsystem. %%-------------------------------------------------------------------- subsystem(ConnectionHandler, ChannelId, SubSystem, TimeOut) -> - case ssh_connection_handler:request(ConnectionHandler, self(), - ChannelId, "subsystem", - true, [?string(SubSystem)], TimeOut) of - success -> success; - failure -> failure; - {error,timeout} -> {error,timeout}; - _ -> failure - end. - + ssh_connection_handler:request(ConnectionHandler, self(), + ChannelId, "subsystem", + true, [?string(SubSystem)], TimeOut). %%-------------------------------------------------------------------- -spec send(pid(), channel_id(), iodata()) -> ok | {error, closed}. @@ -148,7 +143,7 @@ send_eof(ConnectionHandler, Channel) -> ssh_connection_handler:send_eof(ConnectionHandler, Channel). %%-------------------------------------------------------------------- --spec adjust_window(pid(), channel_id(), integer()) -> ok. +-spec adjust_window(pid(), channel_id(), integer()) -> ok | {error, closed}. %% %% %% Description: Adjusts the ssh flowcontrol window. @@ -157,7 +152,8 @@ adjust_window(ConnectionHandler, Channel, Bytes) -> ssh_connection_handler:adjust_window(ConnectionHandler, Channel, Bytes). %%-------------------------------------------------------------------- --spec setenv(pid(), channel_id(), string(), string(), timeout()) -> success | failure. +-spec setenv(pid(), channel_id(), string(), string(), timeout()) -> + success | failure | {error, timeout | closed}. %% %% %% Description: Environment variables may be passed to the shell/command to be @@ -189,6 +185,29 @@ reply_request(_,false, _, _) -> ok. %%-------------------------------------------------------------------- +-spec ptty_alloc(pid(), channel_id(), proplists:proplist()) -> + success | failiure | {error, closed}. +-spec ptty_alloc(pid(), channel_id(), proplists:proplist(), timeout()) -> + success | failiure | {error, timeout} | {error, closed}. + +%% +%% +%% Description: Sends a ssh connection protocol pty_req. +%%-------------------------------------------------------------------- +ptty_alloc(ConnectionHandler, Channel, Options) -> + ptty_alloc(ConnectionHandler, Channel, Options, infinity). +ptty_alloc(ConnectionHandler, Channel, Options, TimeOut) -> + {Width, PixWidth} = pty_default_dimensions(width, Options), + {Hight, PixHight} = pty_default_dimensions(hight, Options), + pty_req(ConnectionHandler, Channel, + proplists:get_value(term, Options, default_term()), + proplists:get_value(width, Options, Width), + proplists:get_value(hight, Options, Hight), + proplists:get_value(pixel_widh, Options, PixWidth), + proplists:get_value(pixel_hight, Options, PixHight), + proplists:get_value(pty_opts, Options, []), TimeOut + ). +%%-------------------------------------------------------------------- %% Not yet officialy supported! The following functions are part of the %% initial contributed ssh application. They are untested. Do we want them? %% Should they be documented and tested? @@ -211,23 +230,6 @@ exit_status(ConnectionHandler, Channel, Status) -> ssh_connection_handler:request(ConnectionHandler, Channel, "exit-status", false, [?uint32(Status)], 0). -open_pty(ConnectionHandler, Channel, TimeOut) -> - open_pty(ConnectionHandler, Channel, - os:getenv("TERM"), 80, 24, [], TimeOut). - -open_pty(ConnectionHandler, Channel, Term, Width, Height, PtyOpts, TimeOut) -> - open_pty(ConnectionHandler, Channel, Term, Width, - Height, 0, 0, PtyOpts, TimeOut). - -open_pty(ConnectionHandler, Channel, Term, Width, Height, - PixWidth, PixHeight, PtyOpts, TimeOut) -> - ssh_connection_handler:request(ConnectionHandler, - Channel, "pty-req", true, - [?string(Term), - ?uint32(Width), ?uint32(Height), - ?uint32(PixWidth),?uint32(PixHeight), - encode_pty_opts(PtyOpts)], TimeOut). - direct_tcpip(ConnectionHandler, RemoteHost, RemotePort, OrigIP, OrigPort, Timeout) -> direct_tcpip(ConnectionHandler, RemoteHost, RemotePort, OrigIP, OrigPort, @@ -1080,6 +1082,27 @@ flow_control([_|_], #channel{flow_control = From, flow_control(_,_,_) -> []. +pty_req(ConnectionHandler, Channel, Term, Width, Height, + PixWidth, PixHeight, PtyOpts, TimeOut) -> + ssh_connection_handler:request(ConnectionHandler, + Channel, "pty-req", true, + [?string(Term), + ?uint32(Width), ?uint32(Height), + ?uint32(PixWidth),?uint32(PixHeight), + encode_pty_opts(PtyOpts)], TimeOut). + +pty_default_dimensions(Dimension, Options) -> + case proplists:get_value(Dimension, Options, 0) of + N when is_integer(N), N > 0 -> + {N, 0}; + _ -> + case proplists:get_value(list_to_atom("pixel_" ++ atom_to_list(Dimension)), Options, 0) of + N when is_integer(N), N > 0 -> + {0, N}; + _ -> + {?TERMINAL_WIDTH, 0} + end + end. encode_pty_opts(Opts) -> Bin = list_to_binary(encode_pty_opts2(Opts)), @@ -1277,3 +1300,10 @@ decode_ip(Addr) when is_binary(Addr) -> {ok,A} -> A end. +default_term() -> + case os:getenv("TERM") of + false -> + ?DEFAULT_TERMINAL; + Str when is_list(Str)-> + Str + end. diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index 4fbc5d0ae2..68523aa72b 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -41,11 +41,13 @@ global_request/4, send/5, send_eof/2, info/1, info/2, connection_info/2, channel_info/3, adjust_window/3, close/2, stop/1, renegotiate/1, renegotiate_data/1, - start_connection/4]). + start_connection/4, + get_print_info/1]). %% gen_fsm callbacks -export([hello/2, kexinit/2, key_exchange/2, new_keys/2, - userauth/2, connected/2]). + userauth/2, connected/2, + error/2]). -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, format_status/2, code_change/4]). @@ -171,9 +173,23 @@ init([Role, Socket, SshOpts]) -> State#state{ssh_params = Ssh}) catch _:Error -> - gen_fsm:enter_loop(?MODULE, [], error, {Error, State0}) + gen_fsm:enter_loop(?MODULE, [], error, {Error, State}) end. +%% Temporary fix for the Nessus error. SYN-> <-SYNACK ACK-> RST-> ? +error(_Event, {Error,State=#state{}}) -> + case Error of + {badmatch,{error,enotconn}} -> + %% {error,enotconn} probably from inet:peername in + %% init_ssh(server,..)/5 called from init/1 + {stop, {shutdown,"TCP connenction to server was prematurely closed by the client"}, State}; + _ -> + {stop, {shutdown,{init,Error}}, State} + end; +error(Event, State) -> + %% State deliberately not checked beeing #state. This is a panic-clause... + {stop, {shutdown,{init,{spurious_error,Event}}}, State}. + %%-------------------------------------------------------------------- -spec open_channel(pid(), string(), iodata(), integer(), integer(), timeout()) -> {open, channel_id()} | {error, term()}. @@ -240,6 +256,9 @@ send_eof(ConnectionHandler, ChannelId) -> %%-------------------------------------------------------------------- -spec connection_info(pid(), [atom()]) -> proplists:proplist(). %%-------------------------------------------------------------------- +get_print_info(ConnectionHandler) -> + sync_send_all_state_event(ConnectionHandler, get_print_info, 1000). + connection_info(ConnectionHandler, Options) -> sync_send_all_state_event(ConnectionHandler, {connection_info, Options}). @@ -270,8 +289,13 @@ renegotiate_data(ConnectionHandler) -> -spec close(pid(), channel_id()) -> ok. %%-------------------------------------------------------------------- close(ConnectionHandler, ChannelId) -> - sync_send_all_state_event(ConnectionHandler, {close, ChannelId}). - + case sync_send_all_state_event(ConnectionHandler, {close, ChannelId}) of + ok -> + ok; + {error, closed} -> + ok + end. + %%-------------------------------------------------------------------- -spec stop(pid()) -> ok | {error, term()}. %%-------------------------------------------------------------------- @@ -550,7 +574,7 @@ connected({#ssh_msg_kexinit{}, _Payload} = Event, State) -> %%-------------------------------------------------------------------- handle_event(#ssh_msg_disconnect{description = Desc} = DisconnectMsg, _StateName, #state{} = State) -> - handle_disconnect(DisconnectMsg, State), + handle_disconnect(peer, DisconnectMsg, State), {stop, {shutdown, Desc}, State}; handle_event(#ssh_msg_ignore{}, StateName, State) -> @@ -605,7 +629,7 @@ handle_event(renegotiate, connected, #state{ssh_params = Ssh0} renegotiate = true})}; handle_event(renegotiate, StateName, State) -> - timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiatie]), + timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiate]), %% Allready in keyexcahange so ignore {next_state, StateName, State}; @@ -758,6 +782,20 @@ handle_sync_event({recv_window, ChannelId}, _From, StateName, end, {reply, Reply, StateName, next_packet(State)}; +handle_sync_event(get_print_info, _From, StateName, State) -> + Reply = + try + {inet:sockname(State#state.socket), + inet:peername(State#state.socket) + } + of + {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])}; + _ -> {{"-",0},"-"} + catch + _:_ -> {{"?",0},"?"} + end, + {reply, Reply, StateName, State}; + handle_sync_event({connection_info, Options}, _From, StateName, State) -> Info = ssh_info(Options, State, []), {reply, Info, StateName, State}; @@ -936,6 +974,10 @@ terminate(normal, _, #state{transport_cb = Transport, (catch Transport:close(Socket)), ok; +terminate({shutdown,{init,Reason}}, StateName, State) -> + error_logger:info_report(io_lib:format("Erlang ssh in connection handler init: ~p~n",[Reason])), + terminate(normal, StateName, State); + %% Terminated by supervisor terminate(shutdown, StateName, #state{ssh_params = Ssh0} = State) -> DisconnectMsg = @@ -951,8 +993,10 @@ terminate({shutdown, #ssh_msg_disconnect{} = Msg}, StateName, {SshPacket, Ssh} = ssh_transport:ssh_packet(Msg, Ssh0), send_msg(SshPacket, State), terminate(normal, StateName, State#state{ssh_params = Ssh}); + terminate({shutdown, _}, StateName, State) -> terminate(normal, StateName, State); + terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid, connection_state = Connection} = State) -> terminate_subsytem(Connection), @@ -965,6 +1009,7 @@ terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid, send_msg(SshPacket, State), terminate(normal, StateName, State#state{ssh_params = Ssh}). + terminate_subsytem(#connection{system_supervisor = SysSup, sub_system_supervisor = SubSysSup}) when is_pid(SubSysSup) -> ssh_system_sup:stop_subsystem(SysSup, SubSysSup); @@ -1161,7 +1206,14 @@ send_all_state_event(FsmPid, Event) -> gen_fsm:send_all_state_event(FsmPid, Event). sync_send_all_state_event(FsmPid, Event) -> - try gen_fsm:sync_send_all_state_event(FsmPid, Event, infinity) + sync_send_all_state_event(FsmPid, Event, infinity). + +sync_send_all_state_event(FsmPid, Event, Timeout) -> + try gen_fsm:sync_send_all_state_event(FsmPid, Event, Timeout) of + {closed, _Channel} -> + {error, closed}; + Result -> + Result catch exit:{noproc, _} -> {error, closed}; @@ -1256,15 +1308,25 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName, end; generate_event(Msg, StateName, State0, EncData) -> - Event = ssh_message:decode(Msg), - State = generate_event_new_state(State0, EncData), - case Event of - #ssh_msg_kexinit{} -> - %% We need payload for verification later. - event({Event, Msg}, StateName, State); - _ -> - event(Event, StateName, State) - end. + try + Event = ssh_message:decode(Msg), + State = generate_event_new_state(State0, EncData), + case Event of + #ssh_msg_kexinit{} -> + %% We need payload for verification later. + event({Event, Msg}, StateName, State); + _ -> + event(Event, StateName, State) + end + catch + _:_ -> + DisconnectMsg = + #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR, + description = "Encountered unexpected input", + language = "en"}, + handle_disconnect(DisconnectMsg, State0) + end. + handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From, @@ -1422,37 +1484,57 @@ handle_ssh_packet(Length, StateName, #state{decoded_data_buffer = DecData0, ssh_params = Ssh0, transport_protocol = _Protocol, socket = _Socket} = State0) -> - {Ssh1, DecData, EncData, Mac} = - ssh_transport:unpack(EncData0, Length, Ssh0), - SshPacket = <<DecData0/binary, DecData/binary>>, - case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of - true -> - PacketData = ssh_transport:msg_data(SshPacket), - {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData), - generate_event(Msg, StateName, - State0#state{ssh_params = Ssh1, - %% Important to be set for - %% next_packet - decoded_data_buffer = <<>>}, EncData); - false -> - DisconnectMsg = + try + {Ssh1, DecData, EncData, Mac} = + ssh_transport:unpack(EncData0, Length, Ssh0), + SshPacket = <<DecData0/binary, DecData/binary>>, + case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of + true -> + PacketData = ssh_transport:msg_data(SshPacket), + {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData), + generate_event(Msg, StateName, + State0#state{ssh_params = Ssh1, + %% Important to be set for + %% next_packet + decoded_data_buffer = <<>>}, + EncData); + false -> + DisconnectMsg = + #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR, + description = "Bad mac", + language = "en"}, + handle_disconnect(DisconnectMsg, State0) + end + catch _:_ -> + Disconnect = #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR, - description = "Bad mac", + description = "Bad input", language = "en"}, - handle_disconnect(DisconnectMsg, State0) - end. + handle_disconnect(Disconnect, State0) + end. + + +handle_disconnect(DisconnectMsg, State) -> + handle_disconnect(own, DisconnectMsg, State). -handle_disconnect(#ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, - role = Role} = State0) -> +handle_disconnect(#ssh_msg_disconnect{} = DisconnectMsg, State, Error) -> + handle_disconnect(own, DisconnectMsg, State, Error); +handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, role = Role} = State0) -> {disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role), - State = send_replies(Replies, State0), + State = send_replies(disconnect_replies(Type, Msg, Replies), State0), {stop, {shutdown, Desc}, State#state{connection_state = Connection}}. -handle_disconnect(#ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, - role = Role} = State0, ErrorMsg) -> + +handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, + role = Role} = State0, ErrorMsg) -> {disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role), - State = send_replies(Replies, State0), + State = send_replies(disconnect_replies(Type, Msg, Replies), State0), {stop, {shutdown, {Desc, ErrorMsg}}, State#state{connection_state = Connection}}. +disconnect_replies(own, Msg, Replies) -> + [{connection_reply, Msg} | Replies]; +disconnect_replies(peer, _, Replies) -> + Replies. + counterpart_versions(NumVsn, StrVsn, #ssh{role = server} = Ssh) -> Ssh#ssh{c_vsn = NumVsn , c_version = StrVsn}; counterpart_versions(NumVsn, StrVsn, #ssh{role = client} = Ssh) -> @@ -1629,7 +1711,7 @@ handshake(Pid, Ref, Timeout) -> {error, Reason} after Timeout -> stop(Pid), - {error, Timeout} + {error, timeout} end. start_timeout(_,_, infinity) -> diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl new file mode 100644 index 0000000000..e5a8666af0 --- /dev/null +++ b/lib/ssh/src/ssh_info.erl @@ -0,0 +1,200 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2015. 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% +%% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Print some info of a running ssh aplication. +%%---------------------------------------------------------------------- + +-module(ssh_info). + +-compile(export_all). + +print() -> + try supervisor:which_children(ssh_sup) + of + _ -> + io:nl(), + print_general(), + io:nl(), + underline("Client part", $=), + print_clients(), + io:nl(), + underline("Server part", $=), + print_servers(), + io:nl(), + %% case os:type() of + %% {unix,_} -> + %% io:nl(), + %% underline("Linux part", $=), + %% underline("Listening"), + %% catch io:format(os:cmd("netstat -tpln")), + %% io:nl(), + %% underline("Other"), + %% catch io:format(os:cmd("netstat -tpn")); + %% _ -> ok + %% end, + underline("Supervisors", $=), + walk_sups(ssh_sup), + io:nl() + catch + _:_ -> + io:format("Ssh not found~n",[]) + end. + +%%%================================================================ +print_general() -> + {_Name, Slogan, Ver} = lists:keyfind(ssh,1,application:which_applications()), + underline(io_lib:format("~s ~s", [Slogan, Ver]), $=), + io:format('This printout is generated ~s. ~n',[datetime()]). + +%%%================================================================ +print_clients() -> + try + lists:foreach(fun print_client/1, supervisor:which_children(sshc_sup)) + catch + C:E -> + io:format('***FAILED: ~p:~p~n',[C,E]) + end. + +print_client({undefined,Pid,supervisor,[ssh_connection_handler]}) -> + {{Local,Remote},_Str} = ssh_connection_handler:get_print_info(Pid), + io:format(" Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]); +print_client(Other) -> + io:format(" [[Other 1: ~p]]~n",[Other]). + + +%%%================================================================ +print_servers() -> + try + lists:foreach(fun print_server/1, supervisor:which_children(sshd_sup)) + catch + C:E -> + io:format('***FAILED: ~p:~p~n',[C,E]) + end. + +print_server({{server,ssh_system_sup,LocalHost,LocalPort},Pid,supervisor,[ssh_system_sup]}) when is_pid(Pid) -> + io:format('Local=~s (~p children)~n',[fmt_host_port({LocalHost,LocalPort}), + ssh_acceptor:number_of_connections(Pid)]), + lists:foreach(fun print_system_sup/1, supervisor:which_children(Pid)); +print_server(Other) -> + io:format(" [[Other 2: ~p]]~n",[Other]). + +print_system_sup({Ref,Pid,supervisor,[ssh_subsystem_sup]}) when is_reference(Ref), + is_pid(Pid) -> + lists:foreach(fun print_channels/1, supervisor:which_children(Pid)); +print_system_sup({{ssh_acceptor_sup,LocalHost,LocalPort}, Pid,supervisor, [ssh_acceptor_sup]}) when is_pid(Pid) -> + io:format(" [Acceptor for ~s]~n",[fmt_host_port({LocalHost,LocalPort})]); +print_system_sup(Other) -> + io:format(" [[Other 3: ~p]]~n",[Other]). + +print_channels({{server,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) -> + lists:foreach(fun print_channel/1, supervisor:which_children(Pid)); +print_channels(Other) -> + io:format(" [[Other 4: ~p]]~n",[Other]). + + +print_channel({Ref,Pid,worker,[ssh_channel]}) when is_reference(Ref), + is_pid(Pid) -> + {{ConnManager,ChannelID}, Str} = ssh_channel:get_print_info(Pid), + {{Local,Remote},StrM} = ssh_connection_handler:get_print_info(ConnManager), + io:format(' ch ~p: ~s ~s',[ChannelID, StrM, Str]), + io:format(" Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]); +print_channel(Other) -> + io:format(" [[Other 5: ~p]]~n",[Other]). + +%%%================================================================ +-define(inc(N), (N+4)). + +walk_sups(StartPid) -> + io:format("Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]), + walk_sups(children(StartPid), _Indent=?inc(0)). + +walk_sups([H={_,Pid,SupOrWorker,_}|T], Indent) -> + indent(Indent), io:format('~200p ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]), + case SupOrWorker of + supervisor -> walk_sups(children(Pid), ?inc(Indent)); + _ -> ok + end, + walk_sups(T, Indent); +walk_sups([], _) -> + ok. + +dead_or_alive(Name) when is_atom(Name) -> + case whereis(Name) of + undefined -> + "**UNDEFINED**"; + Pid -> + dead_or_alive(Pid) + end; +dead_or_alive(Pid) when is_pid(Pid) -> + case process_info(Pid) of + undefined -> "**DEAD**"; + _ -> "alive" + end. + +indent(I) -> io:format('~*c',[I,$ ]). + +children(Pid) -> + Parent = self(), + Helper = spawn(fun() -> + Parent ! {self(),supervisor:which_children(Pid)} + end), + receive + {Helper,L} when is_list(L) -> + L + after + 2000 -> + catch exit(Helper, kill), + [] + end. + +%%%================================================================ +underline(Str) -> + underline(Str, $-). + +underline(Str, LineChar) -> + Len = lists:flatlength(Str), + io:format('~s~n',[Str]), + line(Len,LineChar). + +line(Len, Char) -> + io:format('~*c~n', [Len,Char]). + + +datetime() -> + %% Adapt to new OTP 18 erlang time API and be back-compatible + TimeStamp = try + erlang:timestamp() + catch + error:undef -> + erlang:now() + end, + {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(TimeStamp), + lists:flatten(io_lib:format('~4w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w UTC',[YYYY,MM,DD, H,M,S])). + + +fmt_host_port({{A,B,C,D},Port}) -> io_lib:format('~p.~p.~p.~p:~p',[A,B,C,D,Port]); +fmt_host_port({Host,Port}) -> io_lib:format('~s:~p',[Host,Port]). + + + +nyi() -> + io:format('Not yet implemented~n',[]), + nyi. diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl index 891ccec24c..66e7717095 100644 --- a/lib/ssh/src/ssh_message.erl +++ b/lib/ssh/src/ssh_message.erl @@ -505,6 +505,11 @@ erl_boolean(1) -> decode_kex_init(<<?BYTE(Bool), ?UINT32(X)>>, Acc, 0) -> list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc])); +decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) -> + %% The mandatory trailing UINT32 is missing. Assume the value it anyhow must have + %% See rfc 4253 7.1 + X = 0, + list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc])); decode_kex_init(<<?UINT32(Len), Data:Len/binary, Rest/binary>>, Acc, N) -> Names = string:tokens(unicode:characters_to_list(Data), ","), decode_kex_init(Rest, [Names | Acc], N -1). diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl index 721146c509..613f8f25b2 100644 --- a/lib/ssh/src/ssh_sftp.erl +++ b/lib/ssh/src/ssh_sftp.erl @@ -33,8 +33,8 @@ -export([start_channel/1, start_channel/2, start_channel/3, stop_channel/1]). --export([open/3, opendir/2, close/2, readdir/2, pread/4, read/3, - open/4, opendir/3, close/3, readdir/3, pread/5, read/4, +-export([open/3, open_tar/3, opendir/2, close/2, readdir/2, pread/4, read/3, + open/4, open_tar/4, opendir/3, close/3, readdir/3, pread/5, read/4, apread/4, aread/3, pwrite/4, write/3, apwrite/4, awrite/3, pwrite/5, write/4, position/3, real_path/2, read_file_info/2, get_file_info/2, @@ -69,6 +69,18 @@ mode }). +-record(bufinf, + { + mode, % read | write (=from or to buffer by user) + crypto_state, + crypto_fun, % For encode or decode depending on the mode field + size = 0, % # bytes "before" the current buffer for the postion call + + chunksize, % The size of the chunks to be sent or received + enc_text_buf = <<>>, % Encrypted text + plain_text_buf = <<>> % Decrypted text + }). + -define(FILEOP_TIMEOUT, infinity). -define(NEXT_REQID(S), @@ -112,7 +124,7 @@ start_channel(Host, Opts) -> start_channel(Host, Port, Opts) -> {SshOpts, SftpOpts} = handle_options(Opts, [], []), Timeout = proplists:get_value(timeout, SftpOpts, infinity), - case ssh_xfer:connect(Host, Port, SshOpts) of + case ssh_xfer:connect(Host, Port, SshOpts, Timeout) of {ok, ChannelId, Cm} -> case ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm, ChannelId, SftpOpts]) of @@ -162,6 +174,77 @@ open(Pid, File, Mode) -> open(Pid, File, Mode, FileOpTimeout) -> call(Pid, {open, false, File, Mode}, FileOpTimeout). +open_tar(Pid, File, Mode) -> + open_tar(Pid, File, Mode, ?FILEOP_TIMEOUT). +open_tar(Pid, File, Mode, FileOpTimeout) -> + case {lists:member(write,Mode), + lists:member(read,Mode), + Mode -- [read,write]} of + {true,false,[]} -> + {ok,Handle} = open(Pid, File, [write], FileOpTimeout), + erl_tar:init(Pid, write, + fun(write, {_,Data}) -> + write_to_remote_tar(Pid, Handle, to_bin(Data), FileOpTimeout); + (position, {_,Pos}) -> + position(Pid, Handle, Pos, FileOpTimeout); + (close, _) -> + close(Pid, Handle, FileOpTimeout) + end); + {true,false,[{crypto,{CryptoInitFun,CryptoEncryptFun,CryptoEndFun}}]} -> + {ok,SftpHandle} = open(Pid, File, [write], FileOpTimeout), + BI = #bufinf{mode = write, + crypto_fun = CryptoEncryptFun}, + {ok,BufHandle} = open_buf(Pid, CryptoInitFun, BI, FileOpTimeout), + erl_tar:init(Pid, write, + fun(write, {_,Data}) -> + write_buf(Pid, SftpHandle, BufHandle, to_bin(Data), FileOpTimeout); + (position, {_,Pos}) -> + position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout); + (close, _) -> + {ok,#bufinf{ + plain_text_buf = PlainBuf0, + enc_text_buf = EncBuf0, + crypto_state = CState0 + }} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout), + {ok,EncTextTail} = CryptoEndFun(PlainBuf0, CState0), + EncTextBuf = <<EncBuf0/binary, EncTextTail/binary>>, + case write(Pid, SftpHandle, EncTextBuf, FileOpTimeout) of + ok -> + call(Pid, {erase_bufinf,BufHandle}, FileOpTimeout), + close(Pid, SftpHandle, FileOpTimeout); + Other -> + Other + end + end); + {false,true,[]} -> + {ok,Handle} = open(Pid, File, [read,binary], FileOpTimeout), + erl_tar:init(Pid, read, + fun(read2, {_,Len}) -> + read_repeat(Pid, Handle, Len, FileOpTimeout); + (position, {_,Pos}) -> + position(Pid, Handle, Pos, FileOpTimeout); + (close, _) -> + close(Pid, Handle, FileOpTimeout) + end); + {false,true,[{crypto,{CryptoInitFun,CryptoDecryptFun}}]} -> + {ok,SftpHandle} = open(Pid, File, [read,binary], FileOpTimeout), + BI = #bufinf{mode = read, + crypto_fun = CryptoDecryptFun}, + {ok,BufHandle} = open_buf(Pid, CryptoInitFun, BI, FileOpTimeout), + erl_tar:init(Pid, read, + fun(read2, {_,Len}) -> + read_buf(Pid, SftpHandle, BufHandle, Len, FileOpTimeout); + (position, {_,Pos}) -> + position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout); + (close, _) -> + call(Pid, {erase_bufinf,BufHandle}, FileOpTimeout), + close(Pid, SftpHandle, FileOpTimeout) + end); + _ -> + {error,{illegal_mode,Mode}} + end. + + opendir(Pid, Path) -> opendir(Pid, Path, ?FILEOP_TIMEOUT). opendir(Pid, Path, FileOpTimeout) -> @@ -447,6 +530,15 @@ handle_cast(_,State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +do_handle_call({get_bufinf,BufHandle}, _From, S=#state{inf=I0}) -> + {reply, dict:find(BufHandle,I0), S}; + +do_handle_call({put_bufinf,BufHandle,B}, _From, S=#state{inf=I0}) -> + {reply, ok, S#state{inf=dict:store(BufHandle,B,I0)}}; + +do_handle_call({erase_bufinf,BufHandle}, _From, S=#state{inf=I0}) -> + {reply, ok, S#state{inf=dict:erase(BufHandle,I0)}}; + do_handle_call({open, Async,FileName,Mode}, From, #state{xf = XF} = State) -> {Access,Flags,Attrs} = open_mode(XF#ssh_xfer.vsn, Mode), ReqID = State#state.req_id, @@ -551,12 +643,7 @@ do_handle_call({read,Async,Handle,Length}, From, State) -> do_handle_call({pwrite,Async,Handle,At,Data0}, From, State) -> case lseek_position(Handle, At, State) of {ok,Offset} -> - Data = if - is_binary(Data0) -> - Data0; - is_list(Data0) -> - list_to_binary(Data0) - end, + Data = to_bin(Data0), ReqID = State#state.req_id, Size = size(Data), ssh_xfer:write(?XF(State),ReqID,Handle,Offset,Data), @@ -569,12 +656,7 @@ do_handle_call({pwrite,Async,Handle,At,Data0}, From, State) -> do_handle_call({write,Async,Handle,Data0}, From, State) -> case lseek_position(Handle, cur, State) of {ok,Offset} -> - Data = if - is_binary(Data0) -> - Data0; - is_list(Data0) -> - list_to_binary(Data0) - end, + Data = to_bin(Data0), ReqID = State#state.req_id, Size = size(Data), ssh_xfer:write(?XF(State),ReqID,Handle,Offset,Data), @@ -1126,5 +1208,207 @@ lseek_pos({eof, Offset}, _CurOffset, CurSize) end; lseek_pos(_, _, _) -> {error, einval}. - +%%%================================================================ +%%% +to_bin(Data) when is_list(Data) -> list_to_binary(Data); +to_bin(Data) when is_binary(Data) -> Data. + + +read_repeat(Pid, Handle, Len, FileOpTimeout) -> + {ok,{_WindowSz,PacketSz}} = recv_window(Pid, FileOpTimeout), + read_rpt(Pid, Handle, Len, PacketSz, FileOpTimeout, <<>>). + +read_rpt(Pid, Handle, WantedLen, PacketSz, FileOpTimeout, Acc) when WantedLen > 0 -> + case read(Pid, Handle, min(WantedLen,PacketSz), FileOpTimeout) of + {ok, Data} -> + read_rpt(Pid, Handle, WantedLen-size(Data), PacketSz, FileOpTimeout, <<Acc/binary, Data/binary>>); + eof -> + {ok, Acc}; + Error -> + Error + end; +read_rpt(_Pid, _Handle, WantedLen, _PacketSz, _FileOpTimeout, Acc) when WantedLen >= 0 -> + {ok,Acc}. + + +write_to_remote_tar(_Pid, _SftpHandle, <<>>, _FileOpTimeout) -> + ok; +write_to_remote_tar(Pid, SftpHandle, Bin, FileOpTimeout) -> + {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout), + write_file_loop(Pid, SftpHandle, 0, Bin, size(Bin), Packet, FileOpTimeout). + +position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout) -> + {ok,#bufinf{mode = Mode, + plain_text_buf = Buf0, + size = Size}} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout), + case Pos of + {cur,0} when Mode==write -> + {ok,Size+size(Buf0)}; + + {cur,0} when Mode==read -> + {ok,Size}; + + _ when Mode==read, is_integer(Pos) -> + Skip = Pos-Size, + if + Skip < 0 -> + {error, cannot_rewind}; + Skip == 0 -> + %% Optimization + {ok,Pos}; + Skip > 0 -> + case read_buf(Pid, SftpHandle, BufHandle, Skip, FileOpTimeout) of + %% A bit innefficient to fetch the bufinf again, but there are lots of + %% other more important optimizations waiting.... + {ok,_} -> + {ok,Pos}; + Other -> + Other + end + end; + + _ -> + {error,{not_yet_implemented,{pos,Pos}}} + end. + +read_buf(Pid, SftpHandle, BufHandle, WantedLen, FileOpTimeout) -> + {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout), + {ok,B0} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout), + case do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B0) of + {ok,ResultBin,B} -> + call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout), + {ok,ResultBin}; + {error,Error} -> + {error,Error}; + {eof,B} -> + call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout), + eof + end. + +do_the_read_buf(_Pid, _SftpHandle, WantedLen, _Packet, _FileOpTimeout, + B=#bufinf{plain_text_buf=PlainBuf0, + size = Size}) + when size(PlainBuf0) >= WantedLen -> + %% We already have the wanted number of bytes decoded and ready! + <<ResultBin:WantedLen/binary, PlainBuf/binary>> = PlainBuf0, + {ok,ResultBin,B#bufinf{plain_text_buf=PlainBuf, + size = Size + WantedLen}}; + +do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, + B0=#bufinf{plain_text_buf = PlainBuf0, + enc_text_buf = EncBuf0, + chunksize = undefined + }) + when size(EncBuf0) > 0 -> + %% We have (at least) one decodable byte waiting for decodeing. + {ok,DecodedBin,B} = apply_crypto(EncBuf0, B0), + do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, + B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>, + enc_text_buf = <<>> + }); + +do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, + B0=#bufinf{plain_text_buf = PlainBuf0, + enc_text_buf = EncBuf0, + chunksize = ChunkSize0 + }) + when size(EncBuf0) >= ChunkSize0 -> + %% We have (at least) one chunk of decodable bytes waiting for decodeing. + <<ToDecode:ChunkSize0/binary, EncBuf/binary>> = EncBuf0, + {ok,DecodedBin,B} = apply_crypto(ToDecode, B0), + do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, + B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>, + enc_text_buf = EncBuf + }); + +do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B=#bufinf{enc_text_buf = EncBuf0}) -> + %% We must read more bytes and append to the buffer of encoded bytes. + case read(Pid, SftpHandle, Packet, FileOpTimeout) of + {ok,EncryptedBin} -> + do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, + B#bufinf{enc_text_buf = <<EncBuf0/binary, EncryptedBin/binary>>}); + eof -> + {eof,B}; + Other -> + Other + end. + + +write_buf(Pid, SftpHandle, BufHandle, PlainBin, FileOpTimeout) -> + {ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout), + {ok,B0=#bufinf{plain_text_buf=PTB}} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout), + case do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B0#bufinf{plain_text_buf = <<PTB/binary,PlainBin/binary>>}) of + {ok, B} -> + call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout), + ok; + {error,Error} -> + {error,Error} + end. + +do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B=#bufinf{enc_text_buf = EncBuf0, + size = Size}) + when size(EncBuf0) >= Packet -> + <<BinToWrite:Packet/binary, EncBuf/binary>> = EncBuf0, + case write(Pid, SftpHandle, BinToWrite, FileOpTimeout) of + ok -> + do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B#bufinf{enc_text_buf = EncBuf, + size = Size + Packet}); + Other -> + Other + end; + +do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B0=#bufinf{plain_text_buf = PlainBuf0, + enc_text_buf = EncBuf0, + chunksize = undefined}) + when size(PlainBuf0) > 0 -> + {ok,EncodedBin,B} = apply_crypto(PlainBuf0, B0), + do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B#bufinf{plain_text_buf = <<>>, + enc_text_buf = <<EncBuf0/binary, EncodedBin/binary>>}); + +do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B0=#bufinf{plain_text_buf = PlainBuf0, + enc_text_buf = EncBuf0, + chunksize = ChunkSize0 + }) + when size(PlainBuf0) >= ChunkSize0 -> + <<ToEncode:ChunkSize0/binary, PlainBuf/binary>> = PlainBuf0, + {ok,EncodedBin,B} = apply_crypto(ToEncode, B0), + do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout, + B#bufinf{plain_text_buf = PlainBuf, + enc_text_buf = <<EncBuf0/binary, EncodedBin/binary>>}); + +do_the_write_buf(_Pid, _SftpHandle, _Packet, _FileOpTimeout, B) -> + {ok,B}. + +apply_crypto(In, B=#bufinf{crypto_state = CState0, + crypto_fun = F}) -> + case F(In,CState0) of + {ok,EncodedBin,CState} -> + {ok, EncodedBin, B#bufinf{crypto_state=CState}}; + {ok,EncodedBin,CState,ChunkSize} -> + {ok, EncodedBin, B#bufinf{crypto_state=CState, + chunksize=ChunkSize}} + end. + +open_buf(Pid, CryptoInitFun, BufInfo0, FileOpTimeout) -> + case CryptoInitFun() of + {ok,CryptoState} -> + open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, undefined); + {ok,CryptoState,ChunkSize} -> + open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize); + Other -> + Other + end. + +open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize) -> + BufInfo = BufInfo0#bufinf{crypto_state = CryptoState, + chunksize = ChunkSize}, + BufHandle = make_ref(), + call(Pid, {put_bufinf,BufHandle,BufInfo}, FileOpTimeout), + {ok,BufHandle}. diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index 52665635f0..04ae6b11e2 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2015. 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 @@ -559,56 +559,73 @@ stat(ReqId, RelPath, State0=#state{file_handler=FileMod, send_status({error, E}, ReqId, State1) end. -decode_4_open_flag(create_new) -> - [write]; -decode_4_open_flag(create_truncate) -> - [write]; -decode_4_open_flag(truncate_existing) -> - [write]; -decode_4_open_flag(open_existing) -> - [read]. - -decode_4_flags([OpenFlag | Flags]) -> - decode_4_flags(Flags, decode_4_open_flag(OpenFlag)). - -decode_4_flags([], Flags) -> - Flags; -decode_4_flags([append_data|R], _Flags) -> - decode_4_flags(R, [append]); -decode_4_flags([append_data_atomic|R], _Flags) -> - decode_4_flags(R, [append]); -decode_4_flags([_|R], Flags) -> - decode_4_flags(R, Flags). - -decode_4_access_flag(read_data) -> - [read]; -decode_4_access_flag(list_directory) -> - [read]; -decode_4_access_flag(write_data) -> - [write]; -decode_4_access_flag(add_file) -> - [write]; -decode_4_access_flag(add_subdirectory) -> - [read]; -decode_4_access_flag(append_data) -> - [append]; -decode_4_access_flag(write_attributes) -> - [write]; -decode_4_access_flag(_) -> - [read]. - -decode_4_acess([_ | _] = Flags) -> +sftp_to_erlang_flag(read, Vsn) when Vsn == 3; + Vsn == 4 -> + read; +sftp_to_erlang_flag(write, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(append, Vsn) when Vsn == 3; + Vsn == 4 -> + append; +sftp_to_erlang_flag(creat, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(trunc, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(excl, Vsn) when Vsn == 3; + Vsn == 4 -> + read; +sftp_to_erlang_flag(create_new, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(create_truncate, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(open_existing, Vsn) when Vsn > 4 -> + read; +sftp_to_erlang_flag(open_or_create, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(truncate_existing, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(append_data, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(append_data_atomic, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(_, _) -> + read. + +sftp_to_erlang_flags(Flags, Vsn) -> lists:map(fun(Flag) -> - [decode_4_access_flag(Flag)] - end, Flags); -decode_4_acess([]) -> - []. + sftp_to_erlang_flag(Flag, Vsn) + end, Flags). + +sftp_to_erlang_access_flag(read_data, _) -> + read; +sftp_to_erlang_access_flag(list_directory, _) -> + read; +sftp_to_erlang_access_flag(write_data, _) -> + write; +sftp_to_erlang_access_flag(append_data, _) -> + append; +sftp_to_erlang_access_flag(add_subdirectory, _) -> + read; +sftp_to_erlang_access_flag(add_file, _) -> + write; +sftp_to_erlang_access_flag(write_attributes, _) -> + write; +sftp_to_erlang_access_flag(_, _) -> + read. +sftp_to_erlang_access_flags(Flags, Vsn) -> + lists:map(fun(Flag) -> + sftp_to_erlang_access_flag(Flag, Vsn) + end, Flags). open(Vsn, ReqId, Data, State) when Vsn =< 3 -> <<?UINT32(BLen), BPath:BLen/binary, ?UINT32(PFlags), _Attrs/binary>> = Data, Path = unicode:characters_to_list(BPath), - Flags = ssh_xfer:decode_open_flags(Vsn, PFlags), + FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags), + Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn)), do_open(ReqId, State, Path, Flags); open(Vsn, ReqId, Data, State) when Vsn >= 4 -> <<?UINT32(BLen), BPath:BLen/binary, ?UINT32(Access), @@ -616,15 +633,12 @@ open(Vsn, ReqId, Data, State) when Vsn >= 4 -> Path = unicode:characters_to_list(BPath), FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags), AcessBits = ssh_xfer:decode_ace_mask(Access), - %% TODO: This is to make sure the Access flags are not ignored - %% but this should be thought through better. This solution should - %% be considered a hack in order to buy some time. At least - %% it works better than when the Access flags where totally ignored. - %% A better solution may need some code refactoring that we do - %% not have time for right now. - AcessFlags = decode_4_acess(AcessBits), - Flags = lists:append(lists:umerge( - [[decode_4_flags(FlagBits)] | AcessFlags])), + %% TODO: There are still flags that are not + %% fully handled as SSH_FXF_ACCESS_TEXT_MODE and + %% a lot a ACE flags, the later we may not need + %% to understand as they are NFS flags + AcessFlags = sftp_to_erlang_access_flags(AcessBits, Vsn), + Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn) ++ AcessFlags), do_open(ReqId, State, Path, Flags). do_open(ReqId, State0, Path, Flags) -> diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl index 1881392db8..2743b704f1 100644 --- a/lib/ssh/src/ssh_xfer.erl +++ b/lib/ssh/src/ssh_xfer.erl @@ -23,7 +23,7 @@ -module(ssh_xfer). --export([attach/2, connect/3]). +-export([attach/2, connect/3, connect/4]). -export([open/6, opendir/3, readdir/3, close/3, read/5, write/5, rename/5, remove/3, mkdir/4, rmdir/3, realpath/3, extended/4, stat/4, fstat/4, lstat/4, setstat/4, @@ -58,6 +58,13 @@ connect(Host, Port, Opts) -> Error -> Error end. +connect(Host, Port, Opts, Timeout) -> + case ssh:connect(Host, Port, Opts, Timeout) of + {ok, CM} -> open_xfer(CM, [{timeout, Timeout}|Opts]); + {error, Timeout} -> {error, timeout}; + Error -> Error + end. + open_xfer(CM, Opts) -> TMO = proplists:get_value(timeout, Opts, infinity), case ssh_connection:session_channel(CM, ?XFER_WINDOW_SIZE, ?XFER_PACKET_SIZE, TMO) of diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl index cf895ae85e..123b48412b 100644 --- a/lib/ssh/test/property_test/ssh_eqc_client_server.erl +++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl @@ -32,6 +32,10 @@ -else. +%% Limit the testing time on CI server... this needs to be improved in % from total budget. +-define(TESTINGTIME(Prop), eqc:testing_time(30,Prop)). + + -include_lib("eqc/include/eqc.hrl"). -include_lib("eqc/include/eqc_statem.hrl"). -eqc_group_commands(true). @@ -75,7 +79,9 @@ -define(SUBSYSTEMS, ["echo1", "echo2", "echo3", "echo4"]). --define(SERVER_ADDRESS, { {127,1,1,1}, inet_port({127,1,1,1}) }). +-define(SERVER_ADDRESS, { {127,1,0,choose(1,254)}, % IP + choose(1024,65535) % Port + }). -define(SERVER_EXTRA_OPTIONS, [{parallel_login,bool()}] ). @@ -97,7 +103,7 @@ %% To be called as eqc:quickcheck( ssh_eqc_client_server:prop_seq() ). prop_seq() -> - do_prop_seq(?SSH_DIR). + ?TESTINGTIME(do_prop_seq(?SSH_DIR)). %% To be called from a common_test test suite prop_seq(CT_Config) -> @@ -105,9 +111,10 @@ prop_seq(CT_Config) -> do_prop_seq(DataDir) -> - ?FORALL(Cmds,commands(?MODULE, #state{data_dir=DataDir}), + setup_rsa(DataDir), + ?FORALL(Cmds,commands(?MODULE), begin - {H,Sf,Result} = run_commands(?MODULE,Cmds), + {H,Sf,Result} = run_commands(?MODULE,Cmds,[{data_dir,DataDir}]), present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok) end). @@ -116,33 +123,35 @@ full_path(SSHdir, CT_Config) -> SSHdir). %%%---- prop_parallel() -> - do_prop_parallel(?SSH_DIR). + ?TESTINGTIME(do_prop_parallel(?SSH_DIR)). %% To be called from a common_test test suite prop_parallel(CT_Config) -> do_prop_parallel(full_path(?SSH_DIR, CT_Config)). do_prop_parallel(DataDir) -> - ?FORALL(Cmds,parallel_commands(?MODULE, #state{data_dir=DataDir}), + setup_rsa(DataDir), + ?FORALL(Cmds,parallel_commands(?MODULE), begin - {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds), + {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds,[{data_dir,DataDir}]), present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok) end). %%%---- prop_parallel_multi() -> - do_prop_parallel_multi(?SSH_DIR). + ?TESTINGTIME(do_prop_parallel_multi(?SSH_DIR)). %% To be called from a common_test test suite prop_parallel_multi(CT_Config) -> do_prop_parallel_multi(full_path(?SSH_DIR, CT_Config)). do_prop_parallel_multi(DataDir) -> + setup_rsa(DataDir), ?FORALL(Repetitions,?SHRINK(1,[10]), - ?FORALL(Cmds,parallel_commands(?MODULE, #state{data_dir=DataDir}), + ?FORALL(Cmds,parallel_commands(?MODULE), ?ALWAYS(Repetitions, begin - {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds), + {H,Sf,Result} = run_parallel_commands(?MODULE,Cmds,[{data_dir,DataDir}]), present_result(?MODULE, Cmds, {H,Sf,Result}, Result==ok) end))). @@ -151,14 +160,12 @@ do_prop_parallel_multi(DataDir) -> %%% called when using commands/1 initial_state() -> - S = initial_state(#state{}), - S#state{initialized=true}. + #state{}. %%% called when using commands/2 -initial_state(S) -> +initial_state(DataDir) -> application:stop(ssh), - ssh:start(), - setup_rsa(S#state.data_dir). + ssh:start(). %%%---------------- weight(S, ssh_send) -> 5*length([C || C<-S#state.channels, has_subsyst(C)]); @@ -172,7 +179,7 @@ weight(_S, _) -> 1. initial_state_pre(S) -> not S#state.initialized. -initial_state_args(S) -> [S]. +initial_state_args(_) -> [{var,data_dir}]. initial_state_next(S, _, _) -> S#state{initialized=true}. @@ -180,10 +187,17 @@ initial_state_next(S, _, _) -> S#state{initialized=true}. %%% Start a new daemon %%% Precondition: not more than ?MAX_NUM_SERVERS started +%%% This is a bit funny because we need to pick an IP address and Port to +%%% run the server on, but there is no way to atomically select a free Port! +%%% +%%% Therefore we just grab one IP-Port pair randomly and try to start the ssh server +%%% on that pair. If it fails, we just forget about it and goes on. Yes, it +%%% is a waste of cpu cycles, but at least it works! + ssh_server_pre(S) -> S#state.initialized andalso length(S#state.servers) < ?MAX_NUM_SERVERS. -ssh_server_args(S) -> [?SERVER_ADDRESS, S#state.data_dir, ?SERVER_EXTRA_OPTIONS]. +ssh_server_args(_) -> [?SERVER_ADDRESS, {var,data_dir}, ?SERVER_EXTRA_OPTIONS]. ssh_server({IP,Port}, DataDir, ExtraOptions) -> ok(ssh:daemon(IP, Port, @@ -194,8 +208,10 @@ ssh_server({IP,Port}, DataDir, ExtraOptions) -> | ExtraOptions ])). +ssh_server_post(_S, _Args, {error,eaddrinuse}) -> true; ssh_server_post(_S, _Args, Result) -> is_ok(Result). +ssh_server_next(S, {error,eaddrinuse}, _) -> S; ssh_server_next(S, Result, [{IP,Port},_,_]) -> S#state{servers=[#srvr{ref = Result, address = IP, @@ -241,15 +257,16 @@ do(Pid, Fun, Timeout) when is_function(Fun,0) -> ssh_open_connection_pre(S) -> S#state.servers /= []. -ssh_open_connection_args(S) -> [oneof(S#state.servers), S#state.data_dir]. +ssh_open_connection_args(S) -> [oneof(S#state.servers), {var,data_dir}]. ssh_open_connection(#srvr{address=Ip, port=Port}, DataDir) -> ok(ssh:connect(ensure_string(Ip), Port, [ {silently_accept_hosts, true}, {user_dir, user_dir(DataDir)}, - {user_interaction, false} - ])). + {user_interaction, false}, + {connect_timeout, 2000} + ], 2000)). ssh_open_connection_post(_S, _Args, Result) -> is_ok(Result). @@ -569,12 +586,6 @@ median(_) -> %%%================================================================ %%% The rest is taken and modified from ssh_test_lib.erl -inet_port(IpAddress)-> - {ok, Socket} = gen_tcp:listen(0, [{ip,IpAddress},{reuseaddr,true}]), - {ok, Port} = inet:port(Socket), - gen_tcp:close(Socket), - Port. - setup_rsa(Dir) -> erase_dir(system_dir(Dir)), erase_dir(user_dir(Dir)), diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl index 34630bdc91..57ea2012c1 100644 --- a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl +++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl @@ -25,8 +25,6 @@ -proptest(eqc). -proptest([triq,proper]). --include_lib("ct_property_test.hrl"). - -ifndef(EQC). -ifndef(PROPER). -ifndef(TRIQ). diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 415cb9fc9c..b449012ffc 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2014. All Rights Reserved. +%% Copyright Ericsson AB 2008-2015. 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 @@ -715,7 +715,14 @@ ssh_connect_arg4_timeout(_Config) -> %% try to connect with a timeout, but "supervise" it Client = spawn(fun() -> - T0 = now(), + %% Adapt to OTP 18 erlang time API and be back-compatible + T0 = try + erlang:monotonic_time() + catch + error:undef -> + %% Use Erlang system time as monotonic time + erlang:now() + end, Rc = ssh:connect("localhost",Port,[],Timeout), ct:log("Client ssh:connect got ~p",[Rc]), Parent ! {done,self(),Rc,T0} @@ -723,16 +730,22 @@ ssh_connect_arg4_timeout(_Config) -> %% Wait for client reaction on the connection try: receive - {done, Client, {error,_E}, T0} -> - Msp = ms_passed(T0, now()), + {done, Client, {error,timeout}, T0} -> + Msp = ms_passed(T0), exit(Server,hasta_la_vista___baby), Low = 0.9*Timeout, High = 1.1*Timeout, - ct:log("Timeout limits: ~p--~p, timeout was ~p, expected ~p",[Low,High,Msp,Timeout]), + ct:log("Timeout limits: ~.4f - ~.4f ms, timeout " + "was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]), if Low<Msp, Msp<High -> ok; true -> {fail, "timeout not within limits"} end; + + {done, Client, {error,Other}, _T0} -> + ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]), + {fail, "Unexpected error message"}; + {done, Client, {ok,_Ref}, _T0} -> {fail,"ssh-connected ???"} after @@ -743,12 +756,16 @@ ssh_connect_arg4_timeout(_Config) -> end. -%% Help function -%% N2-N1 -ms_passed(N1={_,_,M1}, N2={_,_,M2}) -> - {0,{0,Min,Sec}} = calendar:time_difference(calendar:now_to_local_time(N1), - calendar:now_to_local_time(N2)), - 1000 * (Min*60 + Sec + (M2-M1)/1000000). +%% Help function, elapsed milliseconds since T0 +ms_passed({_,_,_} = T0 ) -> + %% OTP 17 and earlier + timer:now_diff(erlang:now(), T0)/1000; + +ms_passed(T0) -> + %% OTP 18 + erlang:convert_time_resolution(erlang:monotonic_time() - T0, + erlang:time_resolution(), + 1000000)/1000. %%-------------------------------------------------------------------- ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true). diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl index 3c537d719c..e3871b3feb 100644 --- a/lib/ssh/test/ssh_connection_SUITE.erl +++ b/lib/ssh/test/ssh_connection_SUITE.erl @@ -36,8 +36,7 @@ all() -> [ - {group, openssh_payload}, - start_subsystem_on_closed_channel, + {group, openssh}, interrupted_send, start_shell, start_shell_exec, @@ -46,14 +45,23 @@ all() -> gracefull_invalid_start, gracefull_invalid_long_start, gracefull_invalid_long_start_no_nl, - stop_listener + stop_listener, + start_subsystem_on_closed_channel ]. groups() -> - [{openssh_payload, [], [simple_exec, - small_cat, - big_cat, - send_after_exit - ]}]. + [{openssh, [], payload() ++ ptty()}]. + +payload() -> + [simple_exec, + small_cat, + big_cat, + send_after_exit]. + +ptty() -> + [ptty_alloc_default, + ptty_alloc, + ptty_alloc_pixel]. + %%-------------------------------------------------------------------- init_per_suite(Config) -> case catch crypto:start() of @@ -67,7 +75,7 @@ end_per_suite(_Config) -> crypto:stop(). %%-------------------------------------------------------------------- -init_per_group(openssh_payload, _Config) -> +init_per_group(openssh, _Config) -> case gen_tcp:connect("localhost", 22, []) of {error,econnrefused} -> {skip,"No openssh deamon"}; @@ -242,32 +250,43 @@ send_after_exit(Config) when is_list(Config) -> end. %%-------------------------------------------------------------------- -start_subsystem_on_closed_channel(Config) -> - PrivDir = ?config(priv_dir, Config), - UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth - file:make_dir(UserDir), - SysDir = ?config(data_dir, Config), - {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, - {user_dir, UserDir}, - {password, "morot"}, - {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]), +ptty_alloc_default() -> + [{doc, "Test sending PTTY alloc message with only defaults."}]. - ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, - {user, "foo"}, - {password, "morot"}, - {user_interaction, false}, - {user_dir, UserDir}]), +ptty_alloc_default(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, []), + ssh:close(ConnectionRef). + +%%-------------------------------------------------------------------- +ptty_alloc() -> + [{doc, "Test sending PTTY alloc message with width,height options."}]. +ptty_alloc(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, + [{term, default_term()}, {width, 70}, {high, 20}]), + ssh:close(ConnectionRef). - ok = ssh_connection:close(ConnectionRef, ChannelId), - failure = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity), +%%-------------------------------------------------------------------- +ptty_alloc_pixel() -> + [{doc, "Test sending PTTY alloc message pixel options."}]. - ssh:close(ConnectionRef), - ssh:stop_daemon(Pid). +ptty_alloc_pixel(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, + [{term, default_term()}, {pixel_widh, 630}, {pixel_hight, 470}]), + ssh:close(ConnectionRef). %%-------------------------------------------------------------------- + interrupted_send() -> [{doc, "Use a subsystem that echos n char and then sends eof to cause a channel exit partway through a large send."}]. @@ -557,6 +576,31 @@ stop_listener(Config) when is_list(Config) -> ct:fail({unexpected, Error}) end. +start_subsystem_on_closed_channel(Config) -> + PrivDir = ?config(priv_dir, Config), + UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + SysDir = ?config(data_dir, Config), + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, UserDir}, + {password, "morot"}, + {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]), + + ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user, "foo"}, + {password, "morot"}, + {user_interaction, false}, + {user_dir, UserDir}]), + + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + + ok = ssh_connection:close(ConnectionRef, ChannelId), + + {error, closed} = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity), + + ssh:close(ConnectionRef), + ssh:stop_daemon(Pid). + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- @@ -603,3 +647,11 @@ ssh_exec(Cmd) -> spawn(fun() -> io:format(Cmd ++ "\n") end). + +default_term() -> + case os:getenv("TERM") of + false -> + "vt100"; + Str when is_list(Str)-> + Str + end. diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl index 4c46a1b1a8..cb74a27638 100644 --- a/lib/ssh/test/ssh_sftp_SUITE.erl +++ b/lib/ssh/test/ssh_sftp_SUITE.erl @@ -32,6 +32,8 @@ -define(USER, "Alladin"). -define(PASSWD, "Sesame"). +-define(tar_file_name, "sftp_tar_test.tar"). + %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- @@ -63,23 +65,37 @@ end_per_suite(Config) -> %%-------------------------------------------------------------------- groups() -> [{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir, - write_file, rename_file, mk_rm_dir, remove_file, links, + write_file, write_big_file, sftp_read_big_file, + rename_file, mk_rm_dir, remove_file, links, retrieve_attributes, set_attributes, async_read, - async_write, position, pos_read, pos_write, version_option]}, + async_write, position, pos_read, pos_write, version_option, + {group,remote_tar}]}, + {openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir, - write_file, rename_file, mk_rm_dir, remove_file, links, + write_file, write_big_file, sftp_read_big_file, + rename_file, mk_rm_dir, remove_file, links, retrieve_attributes, set_attributes, async_read, - async_write, position, pos_read, pos_write]}]. + async_write, position, pos_read, pos_write, + {group,remote_tar}]}, + + {remote_tar, [], [create_empty_tar, files_to_tar, big_file_to_tar, files_chunked_to_tar, + directory_to_tar, binaries_to_tar, null_crypto_tar, + simple_crypto_tar_small, simple_crypto_tar_big, + read_tar, read_null_crypto_tar, read_crypto_tar, + aes_cbc256_crypto_tar, aes_ctr_stream_crypto_tar + ]} + ]. + init_per_group(erlang_server, Config) -> PrivDir = ?config(priv_dir, Config), SysDir = ?config(data_dir, Config), - Sftpd = + Sftpd = {_, HostX, PortX} = ssh_test_lib:daemon([{system_dir, SysDir}, {user_dir, PrivDir}, {user_passwords, [{?USER, ?PASSWD}]}]), - [{group, erlang_server}, {sftpd, Sftpd} | Config]; + [{peer, {fmt_host(HostX),PortX}}, {group, erlang_server}, {sftpd, Sftpd} | Config]; init_per_group(openssh_server, Config) -> Host = ssh_test_lib:hostname(), @@ -87,11 +103,31 @@ init_per_group(openssh_server, Config) -> [{user_interaction, false}, {silently_accept_hosts, true}])) of {ok, _ChannelPid, Connection} -> + [{peer, {_HostName,{IPx,Portx}}}] = ssh:connection_info(Connection,[peer]), ssh:close(Connection), - [{group, openssh_server} | Config]; + [{peer, {fmt_host(IPx),Portx}}, {group, openssh_server} | Config]; _ -> {skip, "No openssh server"} - end. + end; + +init_per_group(remote_tar, Config) -> + {Host,Port} = ?config(peer, Config), + ct:log("Server (~p) at ~p:~p",[?config(group,Config),Host,Port]), + {ok, Connection} = + case ?config(group, Config) of + erlang_server -> + ssh:connect(Host, Port, + [{user, ?USER}, + {password, ?PASSWD}, + {user_interaction, false}, + {silently_accept_hosts, true}]); + openssh_server -> + ssh:connect(Host, Port, + [{user_interaction, false}, + {silently_accept_hosts, true}]) + end, + [{remote_tar, true}, + {connection, Connection} | Config]. end_per_group(erlang_server, Config) -> Config; @@ -125,34 +161,46 @@ init_per_testcase(version_option, Config) -> {user_interaction, false}, {silently_accept_hosts, true}]), Sftp = {ChannelPid, Connection}, - [{sftp, Sftp}, {watchdog, Dog} | TmpConfig]; -init_per_testcase(Case, Config) -> - prep(Config), - TmpConfig0 = lists:keydelete(watchdog, 1, Config), - TmpConfig = lists:keydelete(sftp, 1, TmpConfig0), + [{sftp,Sftp}, {watchdog, Dog} | TmpConfig]; + +init_per_testcase(Case, Config0) -> + prep(Config0), + Config1 = lists:keydelete(watchdog, 1, Config0), + Config2 = lists:keydelete(sftp, 1, Config1), Dog = ct:timetrap(?default_timeout), - case ?config(group, Config) of - erlang_server -> - {_,Host, Port} = ?config(sftpd, Config), - {ok, ChannelPid, Connection} = - ssh_sftp:start_channel(Host, Port, - [{user, ?USER}, - {password, ?PASSWD}, - {user_interaction, false}, - {silently_accept_hosts, true}]), - Sftp = {ChannelPid, Connection}, - [{sftp, Sftp}, {watchdog, Dog} | TmpConfig]; - openssh_server when Case == links -> - {skip, "known bug in openssh"}; - openssh_server -> - Host = ssh_test_lib:hostname(), - {ok, ChannelPid, Connection} = - ssh_sftp:start_channel(Host, - [{user_interaction, false}, - {silently_accept_hosts, true}]), - Sftp = {ChannelPid, Connection}, - [{sftp, Sftp}, {watchdog, Dog} | TmpConfig] + Config = + case ?config(group,Config2) of + erlang_server -> + {_,Host, Port} = ?config(sftpd, Config2), + {ok, ChannelPid, Connection} = + ssh_sftp:start_channel(Host, Port, + [{user, ?USER}, + {password, ?PASSWD}, + {user_interaction, false}, + {silently_accept_hosts, true}]), + Sftp = {ChannelPid, Connection}, + [{sftp, Sftp}, {watchdog, Dog} | Config2]; + openssh_server when Case == links -> + {skip, "known bug in openssh"}; + openssh_server -> + Host = ssh_test_lib:hostname(), + {ok, ChannelPid, Connection} = + ssh_sftp:start_channel(Host, + [{user_interaction, false}, + {silently_accept_hosts, true}]), + Sftp = {ChannelPid, Connection}, + [{sftp, Sftp}, {watchdog, Dog} | Config2] + end, + + case catch ?config(remote_tar,Config) of + %% The 'catch' is for the case of Config={skip,...} + true -> + %% Provide a ChannelPid independent of the sftp-channel already opened. + {ok,ChPid2} = ssh_sftp:start_channel(?config(connection,Config)), + [{channel_pid2,ChPid2} | Config]; + _ -> + Config end. end_per_testcase(sftp_nonexistent_subsystem, Config) -> @@ -168,6 +216,7 @@ end_per_testcase(_, Config) -> end_per_testcase(Config) -> {Sftp, Connection} = ?config(sftp, Config), ssh_sftp:stop_channel(Sftp), + catch ssh_sftp:stop_channel(?config(channel_pid2, Config)), ssh:close(Connection). %%-------------------------------------------------------------------- @@ -212,6 +261,7 @@ read_file(Config) when is_list(Config) -> FileName = filename:join(PrivDir, "sftp.txt"), {Sftp, _} = ?config(sftp, Config), {ok, Data} = ssh_sftp:read_file(Sftp, FileName), + {ok, Data} = ssh_sftp:read_file(Sftp, FileName), {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- @@ -236,6 +286,31 @@ write_file(Config) when is_list(Config) -> {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- +write_big_file() -> + [{doc, "Test API function write_file/2 with big data"}]. +write_big_file(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "sftp.txt"), + {Sftp, _} = ?config(sftp, Config), + + Data = list_to_binary(lists:duplicate(750000,"a")), + ssh_sftp:write_file(Sftp, FileName, [Data]), + {ok, Data} = file:read_file(FileName). + +%%-------------------------------------------------------------------- +sftp_read_big_file() -> + [{doc, "Test API function read_file/2 with big data"}]. +sftp_read_big_file(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "sftp.txt"), + {Sftp, _} = ?config(sftp, Config), + + Data = list_to_binary(lists:duplicate(750000,"a")), + ct:log("Data size to write is ~p bytes",[size(Data)]), + ssh_sftp:write_file(Sftp, FileName, [Data]), + {ok, Data} = ssh_sftp:read_file(Sftp, FileName). + +%%-------------------------------------------------------------------- remove_file() -> [{doc,"Test API function delete/2"}]. remove_file(Config) when is_list(Config) -> @@ -466,6 +541,249 @@ version_option() -> [{doc, "Test API option sftp_vsn"}]. version_option(Config) when is_list(Config) -> open_close_dir(Config). + +%%-------------------------------------------------------------------- +create_empty_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + erl_tar:close(Handle), + {ChPid,_} = ?config(sftp,Config), + {ok, #file_info{type=regular}} = + ssh_sftp:read_file_info(ChPid,fnp(?tar_file_name,Config)). + +%%-------------------------------------------------------------------- +files_to_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose]), + ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]), + ok = erl_tar:close(Handle), + chk_tar(["f1.txt", "f2.txt"], Config). + +%%-------------------------------------------------------------------- +big_file_to_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose]), + ok = erl_tar:close(Handle), + chk_tar(["big.txt"], Config). + + +%%-------------------------------------------------------------------- +files_chunked_to_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]), + ok = erl_tar:close(Handle), + chk_tar(["f1.txt"], Config). + +%%-------------------------------------------------------------------- +directory_to_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + ok = erl_tar:add(Handle, fn("d1",Config), "d1", [verbose]), + ok = erl_tar:close(Handle), + chk_tar(["d1"], Config). + +%%-------------------------------------------------------------------- +binaries_to_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + Bin = <<"A binary">>, + ok = erl_tar:add(Handle, Bin, "b1", [verbose]), + ok = erl_tar:close(Handle), + chk_tar([{"b1",Bin}], Config). + +%%-------------------------------------------------------------------- +null_crypto_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + Cinit = fun() -> {ok, no_state, _SendSize=5} end, + Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=5} end, + Cend = fun(Bin,_CState) -> {ok,Bin} end, + C = {Cinit,Cenc,Cend}, + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]), + Bin = <<"A binary">>, + ok = erl_tar:add(Handle, Bin, "b1", [verbose]), + ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]), + ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]), + ok = erl_tar:close(Handle), + chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config). + +%%-------------------------------------------------------------------- +simple_crypto_tar_small(Config) -> + ChPid2 = ?config(channel_pid2, Config), + Cinit = fun() -> {ok, no_state, _Size=6} end, + Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end, + Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_Size=4} end, + Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end, + C = {Cinit,Cenc,Cend}, + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]), + Bin = <<"A binary">>, + ok = erl_tar:add(Handle, Bin, "b1", [verbose]), + ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]), + ok = erl_tar:close(Handle), + chk_tar([{"b1",Bin}, "f1.txt"], Config, [{crypto,{Cinit,Cdec}}]). + +%%-------------------------------------------------------------------- +simple_crypto_tar_big(Config) -> + ChPid2 = ?config(channel_pid2, Config), + Cinit = fun() -> {ok, no_state, _SendSize=6} end, + Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end, + Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_SendSize=4} end, + Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end, + C = {Cinit,Cenc,Cend}, + {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]), + Bin = <<"A binary">>, + ok = erl_tar:add(Handle, Bin, "b1", [verbose]), + ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]), + ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]), + ok = erl_tar:close(Handle), + chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config, [{crypto,{Cinit,Cdec}}]). + +stuff(Bin) -> << <<C,C>> || <<C>> <= Bin >>. + +unstuff(Bin) -> << <<C>> || <<C,C>> <= Bin >>. + +%%-------------------------------------------------------------------- +read_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + NameBins = lists:sort( + [{"b1",<<"A binary">>}, + {"b2",list_to_binary(lists:duplicate(750000,"a"))} + ]), + {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]), + [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) + || {Name,Bin} <- NameBins], + ok = erl_tar:close(HandleWrite), + + chk_tar(NameBins, Config). + +%%-------------------------------------------------------------------- +read_null_crypto_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + NameBins = lists:sort( + [{"b1",<<"A binary">>}, + {"b2",list_to_binary(lists:duplicate(750000,"a"))} + ]), + Cinitw = fun() -> {ok, no_state, _SendSize=5} end, + Cinitr = fun() -> {ok, no_state, _FetchSize=42} end, + Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=42*42} end, + Cdec = fun(Bin,CState) -> {ok,Bin,CState,_FetchSize=19} end, + Cendw = fun(Bin,_CState) -> {ok,Bin} end, + Cw = {Cinitw,Cenc,Cendw}, + Cr = {Cinitr,Cdec}, + + {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]), + [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) + || {Name,Bin} <- NameBins], + ok = erl_tar:close(HandleWrite), + + chk_tar(NameBins, Config, [{crypto,Cr}]). + +%%-------------------------------------------------------------------- +read_crypto_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + NameBins = lists:sort( + [{"b1",<<"A binary">>}, + {"b2",list_to_binary(lists:duplicate(750000,"a"))} + ]), + Cinitw = fun() -> {ok, no_state, _SendSize=5} end, + Cinitr = fun() -> {ok, no_state, _FetchSize=42} end, + + Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=42*42} end, + Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_FetchSize=120} end, + Cendw = fun(Bin,_CState) -> {ok,stuff(Bin)} end, + Cw = {Cinitw,Cenc,Cendw}, + Cr = {Cinitr,Cdec}, + + {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]), + [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) + || {Name,Bin} <- NameBins], + ok = erl_tar:close(HandleWrite), + + chk_tar(NameBins, Config, [{crypto,Cr}]). + +%%-------------------------------------------------------------------- +aes_cbc256_crypto_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + NameBins = lists:sort( + [{"b1",<<"A binary">>}, + {"b2",list_to_binary(lists:duplicate(750000,"a"))}, + {"d1",fn("d1",Config)} % Dir + ]), + Key = <<"This is a 256 bit key. Boring...">>, + Ivec0 = crypto:rand_bytes(16), + DataSize = 1024, % data_size rem 16 = 0 for aes_cbc + + Cinitw = fun() -> {ok, Ivec0, DataSize} end, + Cinitr = fun() -> {ok, Ivec0, DataSize} end, + + Cenc = fun(PlainBin,Ivec) -> + CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin), + {ok, CipherBin, crypto:next_iv(aes_cbc,CipherBin), DataSize} + end, + Cdec = fun(CipherBin,Ivec) -> + PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, CipherBin), + {ok, PlainBin, crypto:next_iv(aes_cbc,CipherBin), DataSize} + end, + + Cendw = fun(PlainBin, _) when PlainBin == <<>> -> {ok, <<>>}; + (PlainBin, Ivec) -> + CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, + pad(16,PlainBin)), %% Last chunk + {ok, CipherBin} + end, + + Cw = {Cinitw,Cenc,Cendw}, + {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]), + [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], + ok = erl_tar:close(HandleWrite), + + Cr = {Cinitr,Cdec}, + chk_tar(NameBins, Config, [{crypto,Cr}]). + + +pad(BlockSize, Bin) -> + PadSize = (BlockSize - (size(Bin) rem BlockSize)) rem BlockSize, + list_to_binary( lists:duplicate(PadSize,0) ). + +%%-------------------------------------------------------------------- +aes_ctr_stream_crypto_tar(Config) -> + ChPid2 = ?config(channel_pid2, Config), + NameBins = lists:sort( + [{"b1",<<"A binary">>}, + {"b2",list_to_binary(lists:duplicate(750000,"a"))}, + {"d1",fn("d1",Config)} % Dir + ]), + Key = <<"This is a 256 bit key. Boring...">>, + Ivec0 = crypto:rand_bytes(16), + + Cinitw = Cinitr = fun() -> {ok, crypto:stream_init(aes_ctr,Key,Ivec0)} end, + + Cenc = fun(PlainBin,State) -> + {NewState,CipherBin} = crypto:stream_encrypt(State, PlainBin), + {ok, CipherBin, NewState} + end, + Cdec = fun(CipherBin,State) -> + {NewState,PlainBin} = crypto:stream_decrypt(State, CipherBin), + {ok, PlainBin, NewState} + end, + + Cendw = fun(PlainBin, _) when PlainBin == <<>> -> {ok, <<>>}; + (PlainBin, Ivec) -> + CipherBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, + pad(16,PlainBin)), %% Last chunk + {ok, CipherBin} + end, + + Cw = {Cinitw,Cenc,Cendw}, + {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]), + [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], + ok = erl_tar:close(HandleWrite), + + Cr = {Cinitr,Cdec}, + chk_tar(NameBins, Config, [{crypto,Cr}]). + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- @@ -478,6 +796,7 @@ prep(Config) -> file:delete(TestFile), file:delete(TestFile1), file:delete(TestLink), + file:delete(fnp(?tar_file_name,Config)), %% Initial config DataDir = ?config(data_dir, Config), @@ -487,3 +806,94 @@ prep(Config) -> {ok, FileInfo} = file:read_file_info(TestFile), ok = file:write_file_info(TestFile, FileInfo#file_info{mode = Mode}). + + + +chk_tar(Items, Config) -> + chk_tar(Items, Config, []). + +chk_tar(Items, Config, Opts) -> + chk_tar(Items, fnp(?tar_file_name,Config), Config, Opts). + +chk_tar(Items, TarFileName, Config, Opts) when is_list(Opts) -> + tar_size(TarFileName, Config), + {ChPid,_} = ?config(sftp,Config), + {ok,HandleRead} = ssh_sftp:open_tar(ChPid, TarFileName, [read|Opts]), + {ok,NameValueList} = erl_tar:extract(HandleRead,[memory,verbose]), + ok = erl_tar:close(HandleRead), + case {lists:sort(expand_items(Items,Config)), lists:sort(NameValueList)} of + {L,L} -> + true; + {Expect,Actual} -> + ct:log("Expect: ~p",[Expect]), ct:log("Actual: ~p",[Actual]), + case erl_tar:table(TarFileName) of + {ok,Names} -> ct:log("names: ~p",[Names]); + Other -> ct:log("~p",[Other]) + end, + ct:log("~s",[analyze_report(Expect, Actual)]), + ct:fail(bad_tar_contents) + end. + +analyze_report([E={NameE,BinE}|Es], [A={NameA,BinA}|As]) -> + if + NameE == NameA, + BinE =/= BinA-> + [["Component ",NameE," differs. \n Expected: ",BinE,"\n Actual: ",BinA,"\n\n"] + | analyze_report(Es,As)]; + + NameE < NameA -> + [["Component ",NameE," is missing.\n\n"] + | analyze_report(Es,[A|As])]; + + NameE > NameA -> + [["Component ",NameA," is not expected.\n\n"] + | analyze_report([E|Es],As)]; + true -> + analyze_report(Es, As) + end; +analyze_report([{NameE,_BinE}|Es], []) -> + [["Component ",NameE," missing.\n\n"] | analyze_report(Es,[])]; +analyze_report([], [{NameA,_BinA}|As]) -> + [["Component ",NameA," not expected.\n\n"] | analyze_report([],As)]; +analyze_report([], []) -> + "". + +tar_size(TarFileName, Config) -> + {ChPid,_} = ?config(sftp,Config), + {ok,Data} = ssh_sftp:read_file(ChPid, TarFileName), + io:format('Tar file ~p is~n ~p bytes.~n',[TarFileName, size(Data)]). + +expand_items(Items, Config) -> + lists:flatten( + [case Item of + {_Name,Bin} when is_binary(Bin) -> + Item; + {Name,FileName} when is_list(FileName) -> + read_item_contents(Name, fn(FileName,Config)); + FileName when is_list(FileName) -> + read_item_contents(FileName, fn(FileName,Config)) + end || Item <- Items]). + +read_item_contents(ItemName, FileName) -> + case file:read_file(FileName) of + {ok,Bin} -> + {ItemName, Bin}; + {error,eisdir} -> + {ok,FileNames} = file:list_dir(FileName), + [read_item_contents(filename:join(ItemName,Name), + filename:join(FileName,Name)) + || Name<-FileNames] + end. + +fn(Name, Config) -> + Dir = ?config(data_dir, Config), + filename:join([Dir,"sftp_tar_test_data",Name]). + +fnp(Name, Config) -> + Dir = ?config(priv_dir, Config), + filename:join([Dir,Name]). + + +fmt_host({A,B,C,D}) -> lists:concat([A,".",B,".",C,".",D]); +fmt_host(S) -> S. + diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt new file mode 100644 index 0000000000..f597b69d4c --- /dev/null +++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/big.txt @@ -0,0 +1,16384 @@ +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. +All work and no play makes Jack a dull boy. diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1 new file mode 100644 index 0000000000..1bafa9761e --- /dev/null +++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f1 @@ -0,0 +1 @@ +And hi from the subdirectory too! diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2 new file mode 100644 index 0000000000..8566adaeef --- /dev/null +++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/d1/f2 @@ -0,0 +1 @@ +one more file diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt new file mode 100644 index 0000000000..137d409d7b --- /dev/null +++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f1.txt @@ -0,0 +1 @@ +Hi there! diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt new file mode 100644 index 0000000000..d18c6b11fc --- /dev/null +++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data/f2.txt @@ -0,0 +1 @@ +How are you? diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl index 7b22e45d5e..0ce8eec906 100644 --- a/lib/ssh/test/ssh_sftpd_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2013. All Rights Reserved. +%% Copyright Ericsson AB 2006-2015. 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 @@ -56,7 +56,8 @@ all() -> retrieve_attributes, set_attributes, links, - ver3_rename, + ver3_rename, + ver3_open_flags, relpath, sshd_read_file, ver6_basic]. @@ -193,6 +194,39 @@ open_close_file(Config) when is_list(Config) -> ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, ?SSH_FXF_OPEN_EXISTING). +ver3_open_flags() -> + [{doc, "Test open flags"}]. +ver3_open_flags(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "not_exist.txt"), + {Cm, Channel} = ?config(sftp, Config), + ReqId = 0, + + {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), Handle/binary>>, _} = + open_file_v3(FileName, Cm, Channel, ReqId, + ?SSH_FXF_CREAT bor ?SSH_FXF_TRUNC), + {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId), + ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(Handle, ReqId, + Cm, Channel), + + NewFileName = filename:join(PrivDir, "not_exist2.txt"), + NewReqId = ReqId + 1, + {ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId), NewHandle/binary>>, _} = + open_file_v3(NewFileName, Cm, Channel, NewReqId, + ?SSH_FXF_CREAT bor ?SSH_FXF_EXCL), + {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId), + ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(NewHandle, NewReqId, + Cm, Channel), + + NewFileName1 = filename:join(PrivDir, "test.txt"), + NewReqId1 = NewReqId + 1, + {ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId1), NewHandle1/binary>>, _} = + open_file_v3(NewFileName1, Cm, Channel, NewReqId1, + ?SSH_FXF_READ bor ?SSH_FXF_WRITE bor ?SSH_FXF_APPEND), + {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId1), + ?UINT32(?SSH_FX_OK), _/binary>>, _} = close(NewHandle1, NewReqId1, + Cm, Channel). + %%-------------------------------------------------------------------- open_close_dir() -> [{doc,"Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"}]. @@ -662,6 +696,16 @@ open_file(File, Cm, Channel, ReqId, Access, Flags) -> ?SSH_FXP_OPEN, Data/binary>>), reply(Cm, Channel). +open_file_v3(File, Cm, Channel, ReqId, Flags) -> + + Data = list_to_binary([?uint32(ReqId), + ?binary(list_to_binary(File)), + ?uint32(Flags), + ?REG_ATTERS]), + Size = 1 + size(Data), + ssh_connection:send(Cm, Channel, <<?UINT32(Size), + ?SSH_FXP_OPEN, Data/binary>>), + reply(Cm, Channel). close(Handle, ReqId, Cm , Channel) -> diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl index 41fbd324c4..af70eeb46c 100644 --- a/lib/ssh/test/ssh_to_openssh_SUITE.erl +++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl @@ -120,13 +120,8 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) -> receive_hej(), IO ! {input, self(), "exit\n"}, receive_logout(), - receive - {'EXIT', Shell, normal} -> - ok; - Other1 -> - ct:fail({unexpected_msg, Other1}) - end. - + receive_normal_exit(Shell). + %-------------------------------------------------------------------- erlang_client_openssh_server_exec() -> [{doc, "Test api function ssh_connection:exec"}]. @@ -529,11 +524,22 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config) %%-------------------------------------------------------------------- receive_hej() -> receive - <<"Hej\n">> = Hej-> + <<"Hej", _binary>> = Hej -> + ct:pal("Expected result: ~p~n", [Hej]); + <<"Hej\n", _binary>> = Hej -> + ct:pal("Expected result: ~p~n", [Hej]); + <<"Hej\r\n", _/binary>> = Hej -> ct:pal("Expected result: ~p~n", [Hej]); Info -> - ct:pal("Extra info: ~p~n", [Info]), - receive_hej() + Lines = binary:split(Info, [<<"\r\n">>], [global]), + case lists:member(<<"Hej">>, Lines) of + true -> + ct:pal("Expected result found in lines: ~p~n", [Lines]), + ok; + false -> + ct:pal("Extra info: ~p~n", [Info]), + receive_hej() + end end. receive_logout() -> @@ -543,13 +549,20 @@ receive_logout() -> <<"Connection closed">> -> ok end; - <<"TERM environment variable not set.\n">> -> %% Windows work around - receive_logout(); - Other0 -> - ct:fail({unexpected_msg, Other0}) - end. - + Info -> + ct:pal("Extra info when logging out: ~p~n", [Info]), + receive_logout() + end. +receive_normal_exit(Shell) -> + receive + {'EXIT', Shell, normal} -> + ok; + <<"\r\n">> -> + receive_normal_exit(Shell); + Other -> + ct:fail({unexpected_msg, Other}) + end. %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 866b192101..c8cac3e852 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 3.0.7 +SSH_VSN = 3.1 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 62e9bd0165..4349e5a456 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -25,7 +25,36 @@ <file>notes.xml</file> </header> <p>This document describes the changes made to the SSL application.</p> - <section><title>SSL 5.3.7</title> + <section><title>SSL 5.3.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Make sure the clean rule for ssh, ssl, eunit and otp_mibs + actually removes generated files.</p> + <p> + Own Id: OTP-12200</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Change code to reflect that state data may be secret to + avoid breaking dialyzer contracts.</p> + <p> + Own Id: OTP-12341</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 5.3.7</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index b53344e381..0c042f8571 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1999</year><year>2014</year> + <year>1999</year><year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -163,7 +163,7 @@ is supplied it will override the certfile option.</item> <tag>{certfile, path()}</tag> - <item>Path to a file containing the user's certificate.</item> + <item>Path to a file containing the user's PEM encoded certificate.</item> <tag>{key, {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', der_encoded()}}</tag> <item> The DER encoded users private key. If this option @@ -348,11 +348,23 @@ fun(srp, Username :: string(), UserState :: term()) -> </p> </item> + <tag>{padding_check, boolean()}</tag> + <item> + <p> This option only affects TLS-1.0 connections. + If set to false it disables the block cipher padding check + to be able to interoperate with legacy software. + </p> + + <warning><p> Using this option makes TLS vulnerable to + the Poodle attack</p></warning> + + </item> + </taglist> - + </section> - - <section> + + <section> <title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title> <p>Options described here are client specific or has a slightly different @@ -413,6 +425,23 @@ fun(srp, Username :: string(), UserState :: term()) -> Indication extension will be sent if possible, this option may also be used to disable that behavior.</p> </item> + <tag>{fallback, boolean()}</tag> + <item> + <p> Send special cipher suite TLS_FALLBACK_SCSV to avoid undesired TLS version downgrade. + Defaults to false</p> + <warning><p>Note this option is not needed in normal TLS usage and should not be used + to implement new clients. But legacy clients that that retries connections in the following manner</p> + + <p><c> ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1', 'sslv3']}])</c></p> + <p><c> ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1', 'sslv3']}, {fallback, true}])</c></p> + <p><c> ssl:connect(Host, Port, [...{versions, ['tlsv1', 'sslv3']}, {fallback, true}]) </c></p> + <p><c> ssl:connect(Host, Port, [...{versions, ['sslv3']}, {fallback, true}]) </c></p> + + <p>may use it to avoid undesired TLS version downgrade. Note that TLS_FALLBACK_SCSV must also + be supported by the server for the prevention to work. + </p></warning> + </item> + </taglist> </section> @@ -538,7 +567,19 @@ fun(srp, Username :: string(), UserState :: term()) -> </p> </desc> </func> - + + <func> + <name>clear_pem_cache() -> ok </name> + <fsummary> Clears the pem cache</fsummary> + + <desc><p>PEM files, used by ssl API-functions, are cached. The + cache is regularly checked to see if any cache entries should be + invalidated, however this function provides a way to + unconditionally clear the whole cache. + </p> + </desc> + </func> + <func> <name>connect(Socket, SslOptions) -> </name> <name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket} diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml index 43cb3934f7..f1377cabda 100644 --- a/lib/ssl/doc/src/ssl_app.xml +++ b/lib/ssl/doc/src/ssl_app.xml @@ -4,7 +4,7 @@ <appref> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2015</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -82,7 +82,16 @@ callback module, defaults to []. </p> </item> - + + <tag><c><![CDATA[ssl_pem_cache_clean = integer() <optional>]]></c></tag> + <item> + <p> + Number of milliseconds between PEM cache validations. + </p> + <seealso + marker="ssl#clear_pem_cache-0">ssl:clear_pem_cache/0</seealso> + + </item> </taglist> </section> diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl index a7bbb6bc40..ae35dd7ea4 100644 --- a/lib/ssl/src/dtls_record.erl +++ b/lib/ssl/src/dtls_record.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2015. 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 @@ -146,7 +146,7 @@ decode_cipher_text(#ssl_tls{type = Type, version = Version, = ConnnectionStates0) -> CompressAlg = SecParams#security_parameters.compression_algorithm, {PlainFragment, Mac, ReadState1} = ssl_record:decipher(dtls_v1:corresponding_tls_version(Version), - CipherFragment, ReadState0), + CipherFragment, ReadState0, true), MacHash = calc_mac_hash(ReadState1, Type, Version, Epoch, Seq, PlainFragment), case ssl_record:is_correct_mac(Mac, MacHash) of true -> diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index 9d692379b4..7986722094 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,25 +1,13 @@ %% -*- erlang -*- {"%VSN%", [ - {"5.3.6", [{load_module, ssl_handshake, soft_purge, soft_purge, [ssl_connection]}]}, - {"5.3.5", [{load_module, ssl, soft_purge, soft_purge, [ssl_connection]}, - {load_module, ssl_handshake, soft_purge, soft_purge, [ssl_certificate]}, - {load_module, ssl_certificate, soft_purge, soft_purge, []}, - {load_module, ssl_connection, soft_purge, soft_purge, [tls_connection]}, - {update, tls_connection, {advanced, {up, "5.3.5", "5.3.6"}}, [ssl_handshake]}]}, - {<<"5\\.3\\.[1-4]($|\\..*)">>, [{restart_application, ssl}]}, + {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]}, {<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]}, {<<"4\\..*">>, [{restart_application, ssl}]}, {<<"3\\..*">>, [{restart_application, ssl}]} ], [ - {"5.3.6", [{load_module, ssl_handshake, soft_purge, soft_purge, [ssl_connection]}]}, - {"5.3.5", [{load_module, ssl, soft_purge, soft_purge,[ssl_certificate]}, - {load_module, ssl_handshake, soft_purge, soft_purge,[ssl_certificate]}, - {load_module, ssl_certificate, soft_purge, soft_purge,[]}, - {load_module, ssl_connection, soft_purge, soft_purge,[tls_connection]}, - {update, tls_connection, {advanced, {down, "5.3.6", "5.3.5"}}, [ssl_handshake]}]}, - {<<"5\\.3\\.[1-4]($|\\..*)">>, [{restart_application, ssl}]}, + {<<"5\\.3\\.[1-7]($|\\..*)">>, [{restart_application, ssl}]}, {<<"5\\.[0-2]($|\\..*)">>, [{restart_application, ssl}]}, {<<"4\\..*">>, [{restart_application, ssl}]}, {<<"3\\..*">>, [{restart_application, ssl}]} diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index b4bea25942..5f4ad7f013 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2014. All Rights Reserved. +%% Copyright Ericsson AB 1999-2015. 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 @@ -656,7 +656,9 @@ handle_options(Opts0) -> log_alert = handle_option(log_alert, Opts, true), server_name_indication = handle_option(server_name_indication, Opts, undefined), honor_cipher_order = handle_option(honor_cipher_order, Opts, false), - protocol = proplists:get_value(protocol, Opts, tls) + protocol = proplists:get_value(protocol, Opts, tls), + padding_check = proplists:get_value(padding_check, Opts, true), + fallback = proplists:get_value(fallback, Opts, false) }, CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}), @@ -669,7 +671,8 @@ handle_options(Opts0) -> cb_info, renegotiate_at, secure_renegotiate, hibernate_after, erl_dist, next_protocols_advertised, client_preferred_next_protocols, log_alert, - server_name_indication, honor_cipher_order], + server_name_indication, honor_cipher_order, padding_check, + fallback], SockOpts = lists:foldl(fun(Key, PropList) -> proplists:delete(Key, PropList) @@ -847,6 +850,10 @@ validate_option(server_name_indication, undefined) -> undefined; validate_option(honor_cipher_order, Value) when is_boolean(Value) -> Value; +validate_option(padding_check, Value) when is_boolean(Value) -> + Value; +validate_option(fallback, Value) when is_boolean(Value) -> + Value; validate_option(Opt, Value) -> throw({error, {options, {Opt, Value}}}). diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl index 78dc98bc25..9e372f739a 100644 --- a/lib/ssl/src/ssl_alert.erl +++ b/lib/ssl/src/ssl_alert.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -161,5 +161,7 @@ description_txt(?BAD_CERTIFICATE_HASH_VALUE) -> "bad certificate hash value"; description_txt(?UNKNOWN_PSK_IDENTITY) -> "unknown psk identity"; +description_txt(?INAPPROPRIATE_FALLBACK) -> + "inappropriate fallback"; description_txt(Enum) -> lists:flatten(io_lib:format("unsupported/unknown alert: ~p", [Enum])). diff --git a/lib/ssl/src/ssl_alert.hrl b/lib/ssl/src/ssl_alert.hrl index f4f1d74264..a3619e4a35 100644 --- a/lib/ssl/src/ssl_alert.hrl +++ b/lib/ssl/src/ssl_alert.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -58,6 +58,7 @@ %% protocol_version(70), %% insufficient_security(71), %% internal_error(80), +%% inappropriate_fallback(86), %% user_canceled(90), %% no_renegotiation(100), %% RFC 4366 @@ -93,6 +94,7 @@ -define(PROTOCOL_VERSION, 70). -define(INSUFFICIENT_SECURITY, 71). -define(INTERNAL_ERROR, 80). +-define(INAPPROPRIATE_FALLBACK, 86). -define(USER_CANCELED, 90). -define(NO_RENEGOTIATION, 100). -define(UNSUPPORTED_EXTENSION, 110). diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 9c0ed181fe..30d224fee2 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -282,7 +282,7 @@ other_issuer(OtpCert, CertDbHandle) -> handle_path({BinCert, OTPCert}, Path, PartialChainHandler) -> case public_key:pkix_is_self_signed(OTPCert) of true -> - {BinCert, Path}; + {BinCert, lists:delete(BinCert, Path)}; false -> handle_incomplete_chain(Path, PartialChainHandler) end. diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 72467ea2a0..bec0055353 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -33,11 +33,10 @@ -include_lib("public_key/include/public_key.hrl"). -export([security_parameters/2, security_parameters/3, suite_definition/1, - decipher/5, cipher/5, - suite/1, suites/1, all_suites/1, + decipher/6, cipher/5, suite/1, suites/1, all_suites/1, ec_keyed_suites/0, anonymous_suites/0, psk_suites/1, srp_suites/0, openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1, - hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2]). + hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2, is_fallback/1]). -export_type([cipher_suite/0, erl_cipher_suite/0, openssl_cipher_suite/0, @@ -143,17 +142,18 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, {T, CS0#cipher_state{iv=NextIV}}. %%-------------------------------------------------------------------- --spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(), ssl_record:ssl_version()) -> +-spec decipher(cipher_enum(), integer(), #cipher_state{}, binary(), + ssl_record:ssl_version(), boolean()) -> {binary(), binary(), #cipher_state{}} | #alert{}. %% %% Description: Decrypts the data and the MAC using cipher described %% by cipher_enum() and updating the cipher state. %%------------------------------------------------------------------- -decipher(?NULL, _HashSz, CipherState, Fragment, _) -> +decipher(?NULL, _HashSz, CipherState, Fragment, _, _) -> {Fragment, <<>>, CipherState}; -decipher(?RC4, HashSz, CipherState, Fragment, _) -> +decipher(?RC4, HashSz, CipherState, Fragment, _, _) -> State0 = case CipherState#cipher_state.state of - undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key); + undefined -> crypto:stream_init(rc4, CipherState#cipher_state.key); S -> S end, try crypto:stream_decrypt(State0, Fragment) of @@ -171,23 +171,23 @@ decipher(?RC4, HashSz, CipherState, Fragment, _) -> ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) end; -decipher(?DES, HashSz, CipherState, Fragment, Version) -> +decipher(?DES, HashSz, CipherState, Fragment, Version, PaddingCheck) -> block_decipher(fun(Key, IV, T) -> crypto:block_decrypt(des_cbc, Key, IV, T) - end, CipherState, HashSz, Fragment, Version); -decipher(?'3DES', HashSz, CipherState, Fragment, Version) -> + end, CipherState, HashSz, Fragment, Version, PaddingCheck); +decipher(?'3DES', HashSz, CipherState, Fragment, Version, PaddingCheck) -> block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) -> crypto:block_decrypt(des3_cbc, [K1, K2, K3], IV, T) - end, CipherState, HashSz, Fragment, Version); -decipher(?AES, HashSz, CipherState, Fragment, Version) -> + end, CipherState, HashSz, Fragment, Version, PaddingCheck); +decipher(?AES, HashSz, CipherState, Fragment, Version, PaddingCheck) -> block_decipher(fun(Key, IV, T) when byte_size(Key) =:= 16 -> crypto:block_decrypt(aes_cbc128, Key, IV, T); (Key, IV, T) when byte_size(Key) =:= 32 -> crypto:block_decrypt(aes_cbc256, Key, IV, T) - end, CipherState, HashSz, Fragment, Version). + end, CipherState, HashSz, Fragment, Version, PaddingCheck). block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, - HashSz, Fragment, Version) -> + HashSz, Fragment, Version, PaddingCheck) -> try Text = Fun(Key, IV, Fragment), NextIV = next_iv(Fragment, IV), @@ -195,7 +195,7 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, Content = GBC#generic_block_cipher.content, Mac = GBC#generic_block_cipher.mac, CipherState1 = CipherState0#cipher_state{iv=GBC#generic_block_cipher.next_iv}, - case is_correct_padding(GBC, Version) of + case is_correct_padding(GBC, Version, PaddingCheck) of true -> {Content, Mac, CipherState1}; false -> @@ -1108,6 +1108,9 @@ is_acceptable_prf(default_prf, _) -> is_acceptable_prf(Prf, Algos) -> proplists:get_bool(Prf, Algos). +is_fallback(CipherSuites)-> + lists:member(?TLS_FALLBACK_SCSV, CipherSuites). + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -1288,16 +1291,18 @@ generic_stream_cipher_from_bin(T, HashSz) -> #generic_stream_cipher{content=Content, mac=Mac}. -%% For interoperability reasons we do not check the padding content in -%% SSL 3.0 and TLS 1.0 as it is not strictly required and breaks -%% interopability with for instance Google. is_correct_padding(#generic_block_cipher{padding_length = Len, - padding = Padding}, {3, N}) - when N == 0; N == 1 -> - Len == byte_size(Padding); -%% Padding must be check in TLS 1.1 and after + padding = Padding}, {3, 0}, _) -> + Len == byte_size(Padding); %% Only length check is done in SSL 3.0 spec +%% For interoperability reasons it is possible to disable +%% the padding check when using TLS 1.0, as it is not strictly required +%% in the spec (only recommended), howerver this makes TLS 1.0 vunrable to the Poodle attack +%% so by default this clause will not match +is_correct_padding(GenBlockCipher, {3, 1}, false) -> + is_correct_padding(GenBlockCipher, {3, 0}, false); +%% Padding must be checked in TLS 1.1 and after is_correct_padding(#generic_block_cipher{padding_length = Len, - padding = Padding}, _) -> + padding = Padding}, _, _) -> Len == byte_size(Padding) andalso list_to_binary(lists:duplicate(Len, Len)) == Padding. diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl index 3ce9c19aa9..3e50563f0a 100644 --- a/lib/ssl/src/ssl_cipher.hrl +++ b/lib/ssl/src/ssl_cipher.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -355,6 +355,10 @@ %% hello extension data as they should. -define(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, <<?BYTE(16#00), ?BYTE(16#FF)>>). +%% TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol +%% Downgrade Attacks +-define(TLS_FALLBACK_SCSV, <<?BYTE(16#56), ?BYTE(16#00)>>). + %%% PSK Cipher Suites RFC 4279 %% TLS_PSK_WITH_RC4_128_SHA = { 0x00, 0x8A }; diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 8ff9913cee..b6059eac58 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -937,27 +937,27 @@ terminate(_Reason, _StateName, #state{transport_cb = Transport, Transport:close(Socket). format_status(normal, [_, State]) -> - [{data, [{"StateData", State}]}]; + [{data, [{"StateData", State}]}]; format_status(terminate, [_, State]) -> SslOptions = (State#state.ssl_options), - NewOptions = SslOptions#ssl_options{password = "***", - cert = "***", - cacerts = "***", - key = "***", - dh = "***", - psk_identity = "***", - srp_identity = "***"}, - [{data, [{"StateData", State#state{connection_states = "***", - protocol_buffers = "***", - user_data_buffer = "***", - tls_handshake_history = "***", - session = "***", - private_key = "***", - diffie_hellman_params = "***", - diffie_hellman_keys = "***", - srp_params = "***", - srp_keys = "***", - premaster_secret = "***", + NewOptions = SslOptions#ssl_options{password = ?SECRET_PRINTOUT, + cert = ?SECRET_PRINTOUT, + cacerts = ?SECRET_PRINTOUT, + key = ?SECRET_PRINTOUT, + dh = ?SECRET_PRINTOUT, + psk_identity = ?SECRET_PRINTOUT, + srp_identity = ?SECRET_PRINTOUT}, + [{data, [{"StateData", State#state{connection_states = ?SECRET_PRINTOUT, + protocol_buffers = ?SECRET_PRINTOUT, + user_data_buffer = ?SECRET_PRINTOUT, + tls_handshake_history = ?SECRET_PRINTOUT, + session = ?SECRET_PRINTOUT, + private_key = ?SECRET_PRINTOUT, + diffie_hellman_params = ?SECRET_PRINTOUT, + diffie_hellman_keys = ?SECRET_PRINTOUT, + srp_params = ?SECRET_PRINTOUT, + srp_keys = ?SECRET_PRINTOUT, + premaster_secret = ?SECRET_PRINTOUT, ssl_options = NewOptions }}]}]. %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl index c544a0591f..b9a1ef3a84 100644 --- a/lib/ssl/src/ssl_connection.hrl +++ b/lib/ssl/src/ssl_connection.hrl @@ -46,11 +46,11 @@ socket :: port(), ssl_options :: #ssl_options{}, socket_options :: #socket_options{}, - connection_states :: #connection_states{}, - protocol_buffers :: term(), %% #protocol_buffers{} from tls_record.hrl or dtls_recor.hrl - tls_handshake_history :: ssl_handshake:ssl_handshake_history(), + connection_states :: #connection_states{} | secret_printout(), + protocol_buffers :: term() | secret_printout() , %% #protocol_buffers{} from tls_record.hrl or dtls_recor.hrl + tls_handshake_history :: ssl_handshake:ssl_handshake_history() | secret_printout(), cert_db :: reference(), - session :: #session{}, + session :: #session{} | secret_printout(), session_cache :: db_handle(), session_cache_cb :: atom(), negotiated_version :: ssl_record:ssl_version(), @@ -58,18 +58,18 @@ key_algorithm :: ssl_cipher:key_algo(), hashsign_algorithm = {undefined, undefined}, cert_hashsign_algorithm, - public_key_info ::ssl_handshake:public_key_info(), - private_key ::public_key:private_key(), - diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side - diffie_hellman_keys, % {PublicKey, PrivateKey} + public_key_info :: ssl_handshake:public_key_info(), + private_key :: public_key:private_key() | secret_printout(), + diffie_hellman_params:: #'DHParameter'{} | undefined | secret_printout(), + diffie_hellman_keys :: {PublicKey :: binary(), PrivateKey :: binary()} | #'ECPrivateKey'{} | undefined | secret_printout(), psk_identity :: binary(), % server psk identity hint - srp_params :: #srp_user{}, - srp_keys ::{PublicKey :: binary(), PrivateKey :: binary()}, - premaster_secret :: binary(), + srp_params :: #srp_user{} | secret_printout(), + srp_keys ::{PublicKey :: binary(), PrivateKey :: binary()} | secret_printout(), + premaster_secret :: binary() | secret_printout() , file_ref_db :: db_handle(), cert_db_ref :: certdb_ref(), bytes_to_read :: undefined | integer(), %% bytes to read in passive mode - user_data_buffer :: undefined | binary(), + user_data_buffer :: undefined | binary() | secret_printout(), renegotiation :: undefined | {boolean(), From::term() | internal | peer}, start_or_recv_from :: term(), timer :: undefined | reference(), % start_or_recive_timer diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 85724de4bd..88105cac5a 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -24,6 +24,8 @@ -include_lib("public_key/include/public_key.hrl"). +-define(SECRET_PRINTOUT, "***"). + -type reason() :: term(). -type reply() :: term(). -type msg() :: term(). @@ -36,6 +38,7 @@ -type issuer() :: tuple(). -type serialnumber() :: integer(). -type cert_key() :: {reference(), integer(), issuer()}. +-type secret_printout() :: list(). %% basic binary constructors -define(BOOLEAN(X), X:8/unsigned-big-integer). @@ -81,16 +84,16 @@ validate_extensions_fun, depth :: integer(), certfile :: binary(), - cert :: public_key:der_encoded(), + cert :: public_key:der_encoded() | secret_printout(), keyfile :: binary(), - key :: {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()}, - password :: string(), - cacerts :: [public_key:der_encoded()], + key :: {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()} | secret_printout(), + password :: string() | secret_printout(), + cacerts :: [public_key:der_encoded()] | secret_printout(), cacertfile :: binary(), - dh :: public_key:der_encoded(), - dhfile :: binary(), + dh :: public_key:der_encoded() | secret_printout(), + dhfile :: binary() | secret_printout(), user_lookup_fun, % server option, fun to lookup the user - psk_identity :: binary(), + psk_identity :: binary() | secret_printout() , srp_identity, % client option {User, Password} ciphers, % %% Local policy for the server if it want's to reuse the session @@ -114,7 +117,9 @@ server_name_indication = undefined, %% Should the server prefer its own cipher order over the one provided by %% the client? - honor_cipher_order = false + honor_cipher_order = false, + padding_check = true, + fallback = false }). -record(socket_options, diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index d6e5064c39..c4f1f7f193 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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,10 +30,10 @@ lookup_trusted_cert/4, new_session_id/1, clean_cert_db/2, register_session/2, register_session/3, invalidate_session/2, - invalidate_session/3, clear_pem_cache/0, manager_name/1]). + invalidate_session/3, invalidate_pem/1, clear_pem_cache/0, manager_name/1]). % Spawn export --export([init_session_validator/1]). +-export([init_session_validator/1, init_pem_cache_validator/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -49,7 +49,9 @@ session_lifetime, certificate_db, session_validation_timer, - last_delay_timer = {undefined, undefined}%% Keep for testing purposes + last_delay_timer = {undefined, undefined},%% Keep for testing purposes + last_pem_check, + clear_pem_cache }). -define('24H_in_msec', 86400000). @@ -117,14 +119,13 @@ connection_init(Trustedcerts, Role) -> %% Description: Cache a pem file and return its content. %%-------------------------------------------------------------------- cache_pem_file(File, DbHandle) -> - MD5 = crypto:hash(md5, File), - case ssl_pkix_db:lookup_cached_pem(DbHandle, MD5) of + case ssl_pkix_db:lookup_cached_pem(DbHandle, File) of [{Content,_}] -> {ok, Content}; [Content] -> {ok, Content}; undefined -> - call({cache_pem, {MD5, File}}) + call({cache_pem, File}) end. %%-------------------------------------------------------------------- @@ -191,6 +192,11 @@ invalidate_session(Host, Port, Session) -> invalidate_session(Port, Session) -> cast({invalidate_session, Port, Session}). + +-spec invalidate_pem(File::binary()) -> ok. +invalidate_pem(File) -> + cast({invalidate_pem, File}). + %%==================================================================== %% gen_server callbacks %%==================================================================== @@ -212,12 +218,16 @@ init([Name, Opts]) -> SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])), Timer = erlang:send_after(SessionLifeTime * 1000 + 5000, self(), validate_sessions), - erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache), + Interval = pem_check_interval(), + erlang:send_after(Interval, self(), clear_pem_cache), {ok, #state{certificate_db = CertDb, session_cache = SessionCache, session_cache_cb = CacheCb, session_lifetime = SessionLifeTime, - session_validation_timer = Timer}}. + session_validation_timer = Timer, + last_pem_check = os:timestamp(), + clear_pem_cache = Interval + }}. %%-------------------------------------------------------------------- -spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}}. @@ -256,7 +266,7 @@ handle_call({{new_session_id,Port}, _}, {reply, Id, State}; -handle_call({{cache_pem, File}, _Pid}, _, +handle_call({{cache_pem,File}, _Pid}, _, #state{certificate_db = Db} = State) -> try ssl_pkix_db:cache_pem_file(File, Db) of Result -> @@ -303,7 +313,12 @@ handle_cast({invalidate_session, Host, Port, handle_cast({invalidate_session, Port, #session{session_id = ID} = Session}, #state{session_cache = Cache, session_cache_cb = CacheCb} = State) -> - invalidate_session(Cache, CacheCb, {Port, ID}, Session, State). + invalidate_session(Cache, CacheCb, {Port, ID}, Session, State); + +handle_cast({invalidate_pem, File}, + #state{certificate_db = [_, _, PemCache]} = State) -> + ssl_pkix_db:remove(File, PemCache), + {noreply, State}. %%-------------------------------------------------------------------- -spec handle_info(msg(), #state{}) -> {noreply, #state{}}. @@ -328,15 +343,13 @@ handle_info({delayed_clean_session, Key}, #state{session_cache = Cache, CacheCb:delete(Cache, Key), {noreply, State}; -handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace]} = State) -> - case ssl_pkix_db:db_size(PemChace) of - N when N < ?NOT_TO_BIG -> - ok; - _ -> - ssl_pkix_db:clear(PemChace) - end, - erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache), - {noreply, State}; +handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace], + clear_pem_cache = Interval, + last_pem_check = CheckPoint} = State) -> + NewCheckPoint = os:timestamp(), + start_pem_cache_validator(PemChace, CheckPoint), + erlang:send_after(Interval, self(), clear_pem_cache), + {noreply, State#state{last_pem_check = NewCheckPoint}}; handle_info({clean_cert_db, Ref, File}, @@ -482,10 +495,9 @@ new_id(Port, Tries, Cache, CacheCb) -> clean_cert_db(Ref, CertDb, RefDb, PemCache, File) -> case ssl_pkix_db:ref_count(Ref, RefDb, 0) of 0 -> - MD5 = crypto:hash(md5, File), - case ssl_pkix_db:lookup_cached_pem(PemCache, MD5) of + case ssl_pkix_db:lookup_cached_pem(PemCache, File) of [{Content, Ref}] -> - ssl_pkix_db:insert(MD5, Content, PemCache); + ssl_pkix_db:insert(File, Content, PemCache); _ -> ok end, @@ -494,3 +506,39 @@ clean_cert_db(Ref, CertDb, RefDb, PemCache, File) -> _ -> ok end. + +start_pem_cache_validator(PemCache, CheckPoint) -> + spawn_link(?MODULE, init_pem_cache_validator, + [[get(ssl_manager), PemCache, CheckPoint]]). + +init_pem_cache_validator([SslManagerName, PemCache, CheckPoint]) -> + put(ssl_manager, SslManagerName), + ssl_pkix_db:foldl(fun pem_cache_validate/2, + CheckPoint, PemCache). + +pem_cache_validate({File, _}, CheckPoint) -> + case file:read_file_info(File, []) of + {ok, #file_info{mtime = Time}} -> + case is_before_checkpoint(Time, CheckPoint) of + true -> + ok; + false -> + invalidate_pem(File) + end; + _ -> + invalidate_pem(File) + end, + CheckPoint. + +pem_check_interval() -> + case application:get_env(ssl, ssl_pem_cache_clean) of + {ok, Interval} when is_integer(Interval) -> + Interval; + _ -> + ?CLEAR_PEM_CACHE + end. + +is_before_checkpoint(Time, CheckPoint) -> + calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(CheckPoint)) - + calendar:datetime_to_gregorian_seconds(Time) > 0. + diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl index e59aba0618..8531445ba4 100644 --- a/lib/ssl/src/ssl_pkix_db.erl +++ b/lib/ssl/src/ssl_pkix_db.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -81,10 +81,10 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) -> {ok, Certs} end. -lookup_cached_pem([_, _, PemChache], MD5) -> - lookup_cached_pem(PemChache, MD5); -lookup_cached_pem(PemChache, MD5) -> - lookup(MD5, PemChache). +lookup_cached_pem([_, _, PemChache], File) -> + lookup_cached_pem(PemChache, File); +lookup_cached_pem(PemChache, File) -> + lookup(File, PemChache). %%-------------------------------------------------------------------- -spec add_trusted_certs(pid(), {erlang:timestamp(), string()} | @@ -100,36 +100,35 @@ add_trusted_certs(_Pid, {der, DerList}, [CerDb, _,_]) -> {ok, NewRef}; add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) -> - MD5 = crypto:hash(md5, File), - case lookup_cached_pem(Db, MD5) of + case lookup_cached_pem(Db, File) of [{_Content, Ref}] -> ref_count(Ref, RefDb, 1), {ok, Ref}; [Content] -> Ref = make_ref(), update_counter(Ref, 1, RefDb), - insert(MD5, {Content, Ref}, PemChache), + insert(File, {Content, Ref}, PemChache), add_certs_from_pem(Content, Ref, CertsDb), {ok, Ref}; undefined -> - new_trusted_cert_entry({MD5, File}, Db) + new_trusted_cert_entry(File, Db) end. %%-------------------------------------------------------------------- %% %% Description: Cache file as binary in DB %%-------------------------------------------------------------------- --spec cache_pem_file({binary(), binary()}, [db_handle()]) -> {ok, term()}. -cache_pem_file({MD5, File}, [_CertsDb, _RefDb, PemChache]) -> +-spec cache_pem_file(binary(), [db_handle()]) -> {ok, term()}. +cache_pem_file(File, [_CertsDb, _RefDb, PemChache]) -> {ok, PemBin} = file:read_file(File), Content = public_key:pem_decode(PemBin), - insert(MD5, Content, PemChache), + insert(File, Content, PemChache), {ok, Content}. --spec cache_pem_file(reference(), {binary(), binary()}, [db_handle()]) -> {ok, term()}. -cache_pem_file(Ref, {MD5, File}, [_CertsDb, _RefDb, PemChache]) -> +-spec cache_pem_file(reference(), binary(), [db_handle()]) -> {ok, term()}. +cache_pem_file(Ref, File, [_CertsDb, _RefDb, PemChache]) -> {ok, PemBin} = file:read_file(File), Content = public_key:pem_decode(PemBin), - insert(MD5, {Content, Ref}, PemChache), + insert(File, {Content, Ref}, PemChache), {ok, Content}. %%-------------------------------------------------------------------- @@ -245,9 +244,9 @@ add_certs(Cert, Ref, CertsDb) -> error_logger:info_report(Report) end. -new_trusted_cert_entry(FileRef, [CertsDb, RefDb, _] = Db) -> +new_trusted_cert_entry(File, [CertsDb, RefDb, _] = Db) -> Ref = make_ref(), update_counter(Ref, 1, RefDb), - {ok, Content} = cache_pem_file(Ref, FileRef, Db), + {ok, Content} = cache_pem_file(Ref, File, Db), add_certs_from_pem(Content, Ref, CertsDb), {ok, Ref}. diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index 7337225bc4..025a46bf65 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2014. All Rights Reserved. +%% Copyright Ericsson AB 2013-2015. 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 @@ -48,7 +48,7 @@ -export([compress/3, uncompress/3, compressions/0]). %% Payload encryption/decryption --export([cipher/4, decipher/3, is_correct_mac/2]). +-export([cipher/4, decipher/4, is_correct_mac/2]). -export_type([ssl_version/0, ssl_atom_version/0]). @@ -376,8 +376,9 @@ cipher(Version, Fragment, {CipherFragment, CipherS1} = ssl_cipher:cipher(BulkCipherAlgo, CipherS0, MacHash, Fragment, Version), {CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}. + %%-------------------------------------------------------------------- --spec decipher(ssl_version(), binary(), #connection_state{}) -> {binary(), binary(), #connection_state{}} | #alert{}. +-spec decipher(ssl_version(), binary(), #connection_state{}, boolean()) -> {binary(), binary(), #connection_state{}} | #alert{}. %% %% Description: Payload decryption %%-------------------------------------------------------------------- @@ -387,8 +388,8 @@ decipher(Version, CipherFragment, BulkCipherAlgo, hash_size = HashSz}, cipher_state = CipherS0 - } = ReadState) -> - case ssl_cipher:decipher(BulkCipherAlgo, HashSz, CipherS0, CipherFragment, Version) of + } = ReadState, PaddingCheck) -> + case ssl_cipher:decipher(BulkCipherAlgo, HashSz, CipherS0, CipherFragment, Version, PaddingCheck) of {PlainFragment, Mac, CipherS1} -> CS1 = ReadState#connection_state{cipher_state = CipherS1}, {PlainFragment, Mac, CS1}; diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 7df73fb581..77d3aa7889 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -482,8 +482,9 @@ next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_ci next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_cipher_texts = [CT | Rest]} = Buffers, - connection_states = ConnStates0} = State) -> - case tls_record:decode_cipher_text(CT, ConnStates0) of + connection_states = ConnStates0, + ssl_options = #ssl_options{padding_check = Check}} = State) -> + case tls_record:decode_cipher_text(CT, ConnStates0, Check) of {Plain, ConnStates} -> {Plain, State#state{protocol_buffers = Buffers#protocol_buffers{tls_cipher_texts = Rest}, diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl index 183cabcfcd..b0b6d5a8e3 100644 --- a/lib/ssl/src/tls_handshake.erl +++ b/lib/ssl/src/tls_handshake.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -28,6 +28,7 @@ -include("tls_record.hrl"). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). +-include("ssl_cipher.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([client_hello/8, hello/4, @@ -47,22 +48,28 @@ %%-------------------------------------------------------------------- client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, - ciphers = UserSuites + ciphers = UserSuites, + fallback = Fallback } = SslOpts, Cache, CacheCb, Renegotiation, OwnCert) -> Version = tls_record:highest_protocol_version(Versions), Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, - CipherSuites = ssl_handshake:available_suites(UserSuites, Version), + AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version), Extensions = ssl_handshake:client_hello_extensions(Host, Version, - CipherSuites, + AvailableCipherSuites, SslOpts, ConnectionStates, Renegotiation), - - Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), - + CipherSuites = + case Fallback of + true -> + [?TLS_FALLBACK_SCSV | ssl_handshake:cipher_suites(AvailableCipherSuites, Renegotiation)]; + false -> + ssl_handshake:cipher_suites(AvailableCipherSuites, Renegotiation) + end, + Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), #client_hello{session_id = Id, client_version = Version, - cipher_suites = ssl_handshake:cipher_suites(CipherSuites, Renegotiation), + cipher_suites = CipherSuites, compression_methods = ssl_record:compressions(), random = SecParams#security_parameters.client_random, extensions = Extensions @@ -96,33 +103,22 @@ hello(#server_hello{server_version = Version, random = Random, end; hello(#client_hello{client_version = ClientVersion, - session_id = SugesstedId, - cipher_suites = CipherSuites, - compression_methods = Compressions, - random = Random, - extensions = #hello_extensions{elliptic_curves = Curves} = HelloExt}, + cipher_suites = CipherSuites} = Hello, #ssl_options{versions = Versions} = SslOpts, - {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> + Info, Renegotiation) -> Version = ssl_handshake:select_version(tls_record, ClientVersion, Versions), - case tls_record:is_acceptable_version(Version, Versions) of - true -> - ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)), - {Type, #session{cipher_suite = CipherSuite} = Session1} - = ssl_handshake:select_session(SugesstedId, CipherSuites, Compressions, - Port, Session0#session{ecc = ECCCurve}, Version, - SslOpts, Cache, CacheCb, Cert), - case CipherSuite of - no_suite -> - ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY); - _ -> - handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt, - SslOpts, Session1, ConnectionStates0, - Renegotiation) + case ssl_cipher:is_fallback(CipherSuites) of + true -> + Highest = tls_record:highest_protocol_version(Versions), + case tls_record:is_higher(Highest, Version) of + true -> + ?ALERT_REC(?FATAL, ?INAPPROPRIATE_FALLBACK); + false -> + handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation) end; false -> - ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) + handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation) end. - %%-------------------------------------------------------------------- -spec encode_handshake(tls_handshake(), tls_record:tls_version()) -> iolist(). %% @@ -149,6 +145,32 @@ get_tls_handshake(Version, Data, Buffer) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +handle_client_hello(Version, #client_hello{session_id = SugesstedId, + cipher_suites = CipherSuites, + compression_methods = Compressions, + random = Random, + extensions = #hello_extensions{elliptic_curves = Curves} = HelloExt}, + #ssl_options{versions = Versions} = SslOpts, + {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> + case tls_record:is_acceptable_version(Version, Versions) of + true -> + ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)), + {Type, #session{cipher_suite = CipherSuite} = Session1} + = ssl_handshake:select_session(SugesstedId, CipherSuites, Compressions, + Port, Session0#session{ecc = ECCCurve}, Version, + SslOpts, Cache, CacheCb, Cert), + case CipherSuite of + no_suite -> + ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY); + _ -> + handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt, + SslOpts, Session1, ConnectionStates0, + Renegotiation) + end; + false -> + ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION) + end. + get_tls_handshake_aux(Version, <<?BYTE(Type), ?UINT24(Length), Body:Length/binary,Rest/binary>>, Acc) -> Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>, diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl index f50ea22f39..168b2c8fd3 100644 --- a/lib/ssl/src/tls_record.erl +++ b/lib/ssl/src/tls_record.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -34,14 +34,14 @@ -export([get_tls_records/2]). %% Decoding --export([decode_cipher_text/2]). +-export([decode_cipher_text/3]). %% Encoding -export([encode_plain_text/4]). %% Protocol version handling -export([protocol_version/1, lowest_protocol_version/2, - highest_protocol_version/1, supported_protocol_versions/0, + highest_protocol_version/1, is_higher/2, supported_protocol_versions/0, is_acceptable_version/1, is_acceptable_version/2]). -export_type([tls_version/0, tls_atom_version/0]). @@ -142,19 +142,21 @@ encode_plain_text(Type, Version, Data, {CipherText, ConnectionStates#connection_states{current_write = WriteState#connection_state{sequence_number = Seq +1}}}. %%-------------------------------------------------------------------- --spec decode_cipher_text(#ssl_tls{}, #connection_states{}) -> +-spec decode_cipher_text(#ssl_tls{}, #connection_states{}, boolean()) -> {#ssl_tls{}, #connection_states{}}| #alert{}. %% %% Description: Decode cipher text %%-------------------------------------------------------------------- decode_cipher_text(#ssl_tls{type = Type, version = Version, - fragment = CipherFragment} = CipherText, ConnnectionStates0) -> - ReadState0 = ConnnectionStates0#connection_states.current_read, - #connection_state{compression_state = CompressionS0, - sequence_number = Seq, - security_parameters = SecParams} = ReadState0, - CompressAlg = SecParams#security_parameters.compression_algorithm, - case ssl_record:decipher(Version, CipherFragment, ReadState0) of + fragment = CipherFragment} = CipherText, + #connection_states{current_read = + #connection_state{ + compression_state = CompressionS0, + sequence_number = Seq, + security_parameters= + #security_parameters{compression_algorithm = CompressAlg} + } = ReadState0} = ConnnectionStates0, PaddingCheck) -> + case ssl_record:decipher(Version, CipherFragment, ReadState0, PaddingCheck) of {PlainFragment, Mac, ReadState1} -> MacHash = calc_mac_hash(Type, Version, PlainFragment, ReadState1), case ssl_record:is_correct_mac(Mac, MacHash) of @@ -234,6 +236,13 @@ highest_protocol_version(Version = {M,_}, [{N,_} | Rest]) when M > N -> highest_protocol_version(_, [Version | Rest]) -> highest_protocol_version(Version, Rest). +is_higher({M, N}, {M, O}) when N > O -> + true; +is_higher({M, _}, {N, _}) when M > N -> + true; +is_higher(_, _) -> + false. + %%-------------------------------------------------------------------- -spec supported_protocol_versions() -> [tls_version()]. %% diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 2f8ff6f04e..0d241707d9 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1999-2013. All Rights Reserved. +# Copyright Ericsson AB 1999-2015. 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 @@ -46,6 +46,7 @@ MODULES = \ ssl_npn_handshake_SUITE \ ssl_packet_SUITE \ ssl_payload_SUITE \ + ssl_pem_cache_SUITE \ ssl_session_cache_SUITE \ ssl_to_openssl_SUITE \ ssl_ECC_SUITE \ diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 1da4e88077..df9432a43b 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2015. 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 @@ -90,7 +90,8 @@ basic_tests() -> version_option, connect_twice, connect_dist, - clear_pem_cache + clear_pem_cache, + fallback ]. options_tests() -> @@ -256,11 +257,6 @@ init_per_testcase(Case, Config) when Case == unordered_protocol_versions_client _ -> {skip, "TLS 1.2 need but not supported on this platform"} end; -init_per_testcase(no_authority_key_identifier, Config) -> - %% Clear cach so that root cert will not - %% be found. - ssl:clear_pem_cache(), - Config; init_per_testcase(protocol_versions, Config) -> ssl:stop(), @@ -286,6 +282,14 @@ init_per_testcase(empty_protocol_versions, Config) -> ssl:start(), Config; +init_per_testcase(fallback, Config) -> + case tls_record:highest_protocol_version([]) of + {3, N} when N > 1 -> + Config; + _ -> + {skip, "Not relevant if highest supported version is less than 3.2"} + end; + %% init_per_testcase(different_ca_peer_sign, Config0) -> %% ssl_test_lib:make_mix_cert(Config0); @@ -648,6 +652,34 @@ clear_pem_cache(Config) when is_list(Config) -> 0 = ets:info(FilRefDb, size). %%-------------------------------------------------------------------- + +fallback() -> + [{doc, "Test TLS_FALLBACK_SCSV downgrade prevention"}]. + +fallback(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = + ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, ServerOpts}]), + + Port = ssl_test_lib:inet_port(Server), + + Client = + ssl_test_lib:start_client_error([{node, ClientNode}, + {port, Port}, {host, Hostname}, + {from, self()}, {options, + [{fallback, true}, + {versions, ['tlsv1']} + | ClientOpts]}]), + + ssl_test_lib:check_result(Server, {error,{tls_alert,"inappropriate fallback"}}, + Client, {error,{tls_alert,"inappropriate fallback"}}). + +%%-------------------------------------------------------------------- peername() -> [{doc,"Test API function peername/1"}]. diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl index b7864ba6e7..dab7a941db 100644 --- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl +++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl @@ -443,7 +443,7 @@ verify_fun_always_run_client(Config) when is_list(Config) -> {unknown, UserState}; (_, valid, [ChainLen]) -> {valid, [ChainLen + 1]}; - (_, valid_peer, [2]) -> + (_, valid_peer, [1]) -> {fail, "verify_fun_was_always_run"}; (_, valid_peer, UserState) -> {valid, UserState} @@ -482,7 +482,7 @@ verify_fun_always_run_server(Config) when is_list(Config) -> {unknown, UserState}; (_, valid, [ChainLen]) -> {valid, [ChainLen + 1]}; - (_, valid_peer, [2]) -> + (_, valid_peer, [1]) -> {fail, "verify_fun_was_always_run"}; (_, valid_peer, UserState) -> {valid, UserState} diff --git a/lib/ssl/test/ssl_cipher_SUITE.erl b/lib/ssl/test/ssl_cipher_SUITE.erl index 45e91786d4..0e48b674e0 100644 --- a/lib/ssl/test/ssl_cipher_SUITE.erl +++ b/lib/ssl/test/ssl_cipher_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2015. 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 @@ -38,7 +38,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [aes_decipher_good, aes_decipher_good_tls11, aes_decipher_fail, aes_decipher_fail_tls11]. + [aes_decipher_good, aes_decipher_fail, padding_test]. groups() -> []. @@ -73,93 +73,123 @@ end_per_testcase(_TestCase, Config) -> %% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- aes_decipher_good() -> - [{doc,"Decipher a known cryptotext."}]. + [{doc,"Decipher a known cryptotext using a correct key"}]. aes_decipher_good(Config) when is_list(Config) -> HashSz = 32, - CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, - key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>}, - Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8, - 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160, - 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, - 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>, - Content = <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56, "HELLO\n">>, - Mac = <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>, - Version = {3,0}, - {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version), - Version1 = {3,1}, - {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1), - ok. - -%%-------------------------------------------------------------------- - -aes_decipher_good_tls11() -> - [{doc,"Decipher a known TLS 1.1 cryptotext."}]. - -%% the fragment is actuall a TLS 1.1 record, with -%% Version = TLS 1.1, we get the correct NextIV in #cipher_state -aes_decipher_good_tls11(Config) when is_list(Config) -> - HashSz = 32, - CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, - key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>}, - Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8, - 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160, - 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, - 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>, - Content = <<"HELLO\n">>, - NextIV = <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>, - Mac = <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>, - Version = {3,2}, - {Content, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version), - Version1 = {3,2}, - {Content, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1), - ok. + CipherState = correct_cipher_state(), + decipher_check_good(HashSz, CipherState, {3,0}), + decipher_check_good(HashSz, CipherState, {3,1}), + decipher_check_good(HashSz, CipherState, {3,2}), + decipher_check_good(HashSz, CipherState, {3,3}). %%-------------------------------------------------------------------- aes_decipher_fail() -> - [{doc,"Decipher a known cryptotext."}]. + [{doc,"Decipher a known cryptotext using a incorrect key"}]. -%% same as above, last byte of key replaced aes_decipher_fail(Config) when is_list(Config) -> HashSz = 32, - CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, - key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}, - Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8, - 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160, - 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, - 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>, - Version = {3,0}, - {Content, Mac, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version), - 32 = byte_size(Content), - 32 = byte_size(Mac), - Version1 = {3,1}, - {Content1, Mac1, _} = ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1), - 32 = byte_size(Content1), - 32 = byte_size(Mac1), - ok. -%%-------------------------------------------------------------------- - -aes_decipher_fail_tls11() -> - [{doc,"Decipher a known TLS 1.1 cryptotext."}]. - -%% same as above, last byte of key replaced -%% stricter padding checks in TLS 1.1 mean we get an alert instead -aes_decipher_fail_tls11(Config) when is_list(Config) -> - HashSz = 32, - CipherState = #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, - key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}, - Fragment = <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8, - 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160, - 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, - 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>, - Version = {3,2}, - #alert{level = ?FATAL, description = ?BAD_RECORD_MAC} = - ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version), - Version1 = {3,3}, - #alert{level = ?FATAL, description = ?BAD_RECORD_MAC} = - ssl_cipher:decipher(?AES, HashSz, CipherState, Fragment, Version1), - ok. + CipherState = incorrect_cipher_state(), + decipher_check_fail(HashSz, CipherState, {3,0}), + decipher_check_fail(HashSz, CipherState, {3,1}), + decipher_check_fail(HashSz, CipherState, {3,2}), + decipher_check_fail(HashSz, CipherState, {3,3}). %%-------------------------------------------------------------------- +padding_test(Config) when is_list(Config) -> + HashSz = 16, + CipherState = correct_cipher_state(), + pad_test(HashSz, CipherState, {3,0}), + pad_test(HashSz, CipherState, {3,1}), + pad_test(HashSz, CipherState, {3,2}), + pad_test(HashSz, CipherState, {3,3}). + +%%-------------------------------------------------------------------- +% Internal functions -------------------------------------------------------- +%%-------------------------------------------------------------------- +decipher_check_good(HashSz, CipherState, Version) -> + {Content, NextIV, Mac} = content_nextiv_mac(Version), + {Content, Mac, #cipher_state{iv = NextIV}} = + ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true). + +decipher_check_fail(HashSz, CipherState, Version) -> + {Content, NextIV, Mac} = content_nextiv_mac(Version), + true = {Content, Mac, #cipher_state{iv = NextIV}} =/= + ssl_cipher:decipher(?AES, HashSz, CipherState, aes_fragment(Version), Version, true). + +pad_test(HashSz, CipherState, {3,0} = Version) -> + %% 3.0 does not have padding test + {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), + {Content, Mac, #cipher_state{iv = NextIV}} = + ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true), + {Content, Mac, #cipher_state{iv = NextIV}} = + ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false); +pad_test(HashSz, CipherState, {3,1} = Version) -> + %% 3.1 should have padding test, but may be disabled + {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), + BadCont = badpad_content(Content), + {Content, Mac, #cipher_state{iv = NextIV}} = + ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false), + {BadCont, Mac, #cipher_state{iv = NextIV}} = + ssl_cipher:decipher(?AES, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true); +pad_test(HashSz, CipherState, Version) -> + %% 3.2 and 3.3 must have padding test + {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version), + BadCont = badpad_content(Content), + {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, + badpad_aes_fragment(Version), Version, false), + {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES, HashSz, CipherState, + badpad_aes_fragment(Version), Version, true). + +aes_fragment({3,N}) when N == 0; N == 1-> + <<197,9,6,109,242,87,80,154,85,250,110,81,119,95,65,185,53,206,216,153,246,169, + 119,177,178,238,248,174,253,220,242,81,33,0,177,251,91,44,247,53,183,198,165, + 63,20,194,159,107>>; + +aes_fragment(_) -> + <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8, + 190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160, + 198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122, + 108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>. + +badpad_aes_fragment({3,N}) when N == 0; N == 1 -> + <<186,139,125,10,118,21,26,248,120,108,193,104,87,118,145,79,225,55,228,10,105, + 30,190,37,1,88,139,243,210,99,65,41>>; +badpad_aes_fragment(_) -> + <<137,31,14,77,228,80,76,103,183,125,55,250,68,190,123,131,117,23,229,180,207, + 94,121,137,117,157,109,99,113,61,190,138,131,229,201,120,142,179,172,48,77, + 234,19,240,33,38,91,93>>. + +content_nextiv_mac({3,N}) when N == 0; N == 1 -> + {<<"HELLO\n">>, + <<33,0, 177,251, 91,44, 247,53, 183,198, 165,63, 20,194, 159,107>>, + <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}; +content_nextiv_mac(_) -> + {<<"HELLO\n">>, + <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>, + <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}. + +badpad_content_nextiv_mac({3,N}) when N == 0; N == 1 -> + {<<"HELLO\n">>, + <<225,55,228,10,105,30,190,37,1,88,139,243,210,99,65,41>>, + <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>> + }; +badpad_content_nextiv_mac(_) -> + {<<"HELLO\n">>, + <<133,211,45,189,179,229,56,86,11,178,239,159,14,160,253,140>>, + <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>> + }. + +badpad_content(Content) -> + %% BadContent will fail mac test + <<16#F0, Content/binary>>. + +correct_cipher_state() -> + #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, + key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>}. + +incorrect_cipher_state() -> + #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>, + key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}. diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl new file mode 100644 index 0000000000..843079e2fe --- /dev/null +++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl @@ -0,0 +1,127 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2015-2015. 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/.2 +%% +%% 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% +%% + +%% + +-module(ssl_pem_cache_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("kernel/include/file.hrl"). + +-define(CLEANUP_INTERVAL, 5000). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- +all() -> + [pem_cleanup]. + +groups() -> + []. + +init_per_suite(Config0) -> + catch crypto:stop(), + try crypto:start() of + ok -> + ssl:start(), + %% make rsa certs using oppenssl + Result = + (catch make_certs:all(?config(data_dir, Config0), + ?config(priv_dir, Config0))), + ct:log("Make certs ~p~n", [Result]), + + Config1 = ssl_test_lib:make_dsa_cert(Config0), + ssl_test_lib:cert_options(Config1) + catch _:_ -> + {skip, "Crypto did not start"} + end. + +end_per_suite(_Config) -> + application:stop(crypto). + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +init_per_testcase(pem_cleanup, Config) -> + ssl:stop(), + application:load(ssl), + application:set_env(ssl, ssl_pem_cache_clean, ?CLEANUP_INTERVAL), + ssl:start(), + Config. + +end_per_testcase(_TestCase, Config) -> + %%ssl:stop(), + Config. + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +pem_cleanup() -> + [{doc, "Test pem cache invalidate mechanism"}]. +pem_cleanup(Config)when is_list(Config) -> + process_flag(trap_exit, true), + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = + ssl_test_lib:start_client([{node, ClientNode}, + {port, Port}, {host, Hostname}, + {mfa, {ssl_test_lib, no_result, []}}, + {from, self()}, {options, ClientOpts}]), + + Size = ssl_pkix_db:db_size(get_pem_cache()), + Certfile = proplists:get_value(certfile, ServerOpts), + {ok, FileInfo} = file:read_file_info(Certfile), + Time = later(), + ok = file:write_file_info(Certfile, FileInfo#file_info{mtime = Time}), + ct:sleep(2 * ?CLEANUP_INTERVAL), + Size1 = ssl_pkix_db:db_size(get_pem_cache()), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client), + false = Size == Size1. + +get_pem_cache() -> + {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)), + [_, _,_, _, Prop] = StatusInfo, + State = ssl_test_lib:state(Prop), + case element(5, State) of + [_CertDb, _FileRefDb, PemChace] -> + PemChace; + _ -> + undefined + end. + +later()-> + DateTime = calendar:now_to_local_time(os:timestamp()), + Gregorian = calendar:datetime_to_gregorian_seconds(DateTime), + calendar:gregorian_seconds_to_datetime(Gregorian + (2 * ?CLEANUP_INTERVAL)). + diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index da20ed8593..bda974da0e 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 5.3.7 +SSL_VSN = 5.3.8 diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml index 942fd1f45e..0771682a25 100644 --- a/lib/stdlib/doc/src/dict.xml +++ b/lib/stdlib/doc/src/dict.xml @@ -121,7 +121,7 @@ <c><anno>Dict</anno></c> together with an extra argument <c>Acc</c> (short for accumulator). <c><anno>Fun</anno></c> must return a new accumulator which is passed to the next call. <c><anno>Acc0</anno></c> is - returned if the list is empty. The evaluation order is + returned if the dict is empty. The evaluation order is undefined.</p> </desc> </func> diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml index 7f25f5b7bc..95eefb8f9b 100644 --- a/lib/stdlib/doc/src/erl_tar.xml +++ b/lib/stdlib/doc/src/erl_tar.xml @@ -80,6 +80,12 @@ </section> <section> + <title>OTHER STORAGE MEDIA</title> + <p>The <c>erl_ftp</c> module normally accesses the tar-file on disk using the <seealso marker="kernel:file">file module</seealso>. When other needs arise, there is a way to define your own low-level Erlang functions to perform the writing and reading on the storage media. See <seealso marker="#init/3">init/3</seealso> for usage.</p> + <p>An example of this is the sftp support in <seealso marker="ssh:ssh_sftp#open_tar/3">ssh_sftp:open_tar/3</seealso>. That function opens a tar file on a remote machine using an sftp channel.</p> + </section> + + <section> <title>LIMITATIONS</title> <p>For maximum compatibility, it is safe to archive files with names up to 100 characters in length. Such tar files can generally be @@ -99,7 +105,8 @@ <v>TarDescriptor = term()</v> <v>Filename = filename()</v> <v>Options = [Option]</v> - <v>Option = dereference|verbose</v> + <v>Option = dereference|verbose|{chunks,ChunkSize}</v> + <v>ChunkSize = positive_integer()</v> <v>RetValue = ok|{error,{Filename,Reason}}</v> <v>Reason = term()</v> </type> @@ -119,6 +126,12 @@ <item> <p>Print an informational message about the file being added.</p> </item> + <tag><c>{chunks,ChunkSize}</c></tag> + <item> + <p>Read data in parts from the file. This is intended for memory-limited + machines that for example builds a tar file on a remote machine over + <seealso marker="ssh:ssh_sftp#open_tar/3">sftp</seealso>.</p> + </item> </taglist> </desc> </func> @@ -389,6 +402,101 @@ </warning> </desc> </func> + + <func> + <name>init(UserPrivate, AccessMode, Fun) -> {ok,TarDescriptor} | {error,Reason} +</name> + <fsummary>Creates a TarDescriptor used in subsequent tar operations when + defining own low-level storage access functions + </fsummary> + <type> + <v>UserPrivate = term()</v> + <v>AccessMode = [write] | [read]</v> + <v>Fun when AccessMode is [write] = fun(write, {UserPrivate,DataToWrite})->...; + (position,{UserPrivate,Position})->...; + (close, UserPrivate)->... + end + </v> + <v>Fun when AccessMode is [read] = fun(read2, {UserPrivate,Size})->...; + (position,{UserPrivate,Position})->...; + (close, UserPrivate)->... + end + </v> + <v>TarDescriptor = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>The <c>Fun</c> is the definition of what to do when the different + storage operations functions are to be called from the higher tar + handling functions (<c>add/3</c>, <c>add/4</c>, <c>close/1</c>...). + </p> + <p>The <c>Fun</c> will be called when the tar function wants to do + a low-level operation, like writing a block to a file. The Fun is called + as <c>Fun(Op,{UserPrivate,Parameters...})</c> where <c>Op</c> is the operation name, + <c>UserPrivate</c> is the term passed as the first argument to <c>init/1</c> and + <c>Parameters...</c> are the data added by the tar function to be passed down to + the storage handling function. + </p> + <p>The parameter <c>UserPrivate</c> is typically the result of opening a low level + structure like a file descriptor, a sftp channel id or such. The different <c>Fun</c> + clauses operates on that very term. + </p> + <p>The fun clauses parameter lists are: + <taglist> + <tag><c>(write, {UserPrivate,DataToWrite})</c></tag> + <item>Write the term <c>DataToWrite</c> using <c>UserPrivate</c></item> + <tag><c>(close, UserPrivate)</c></tag> + <item>Close the access.</item> + <tag><c>(read2, {UserPrivate,Size})</c></tag> + <item>Read using <c>UserPrivate</c> but only <c>Size</c> bytes. Note that there is + only an arity-2 read function, not an arity-1 + </item> + <tag><c> (position,{UserPrivate,Position})</c></tag> + <item>Sets the position of <c>UserPrivate</c> as defined for files in <seealso marker="kernel:file#position-2">file:position/2</seealso></item> + <tag><c></c></tag> + <item></item> + </taglist> + </p> + <p>A complete <c>Fun</c> parameter for reading and writing on files using the + <seealso marker="kernel:file">file module</seealso> could be: + </p> + <code type="none"> + ExampleFun = + fun(write, {Fd,Data}) -> file:write(Fd, Data); + (position, {Fd,Pos}) -> file:position(Fd, Pos); + (read2, {Fd,Size}) -> file:read(Fd,Size); + (close, Fd) -> file:close(Fd) + end + </code> + <p>where <c>Fd</c> was given to the <c>init/3</c> function as:</p> + <code> + {ok,Fd} = file:open(Name,...). + {ok,TarDesc} = erl_tar:init(Fd, [write], ExampleFun), + </code> + <p>The <c>TarDesc</c> is then used:</p> + <code> + erl_tar:add(TarDesc, SomeValueIwantToAdd, FileNameInTarFile), + ...., + erl_tar:close(TarDesc) + </code> + <p>When the erl_tar core wants to e.g. write a piece of Data, it would call + <c>ExampleFun(write,{UserPrivate,Data})</c>. + </p> + <note> + <p>The example above with <c>file</c> module operations is not necessary to + use directly since that is what the <seealso marker="#open">open</seealso> function + in principle does. + </p> + </note> + <warning> + <p>The <c>TarDescriptor</c> term is not a file descriptor. + You should not rely on the specific contents of the <c>TarDescriptor</c> + term, as it may change in future versions as more features are added + to the <c>erl_tar</c> module.</p> + </warning> + </desc> + </func> + <func> <name>table(Name) -> RetValue</name> <fsummary>Retrieve the name of all files in a tar file</fsummary> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index 9328704e11..21da404c35 100644 --- a/lib/stdlib/doc/src/io_protocol.xml +++ b/lib/stdlib/doc/src/io_protocol.xml @@ -49,7 +49,7 @@ current I/O-protocol.</p> <p>The original I/O-protocol was simple and flexible. Demands for spacial and execution time efficiency has triggered extensions to the protocol over the years, making the protocol larger and somewhat less easy to -implement than the original. It can certainly be argumented that the +implement than the original. It can certainly be argued that the current protocol is too complex, but this text describes how it looks today, not how it should have looked.</p> @@ -76,10 +76,11 @@ the server eventually sends a corresponding <c>io_reply</c> tuple.</p> the I/O server sends the IO reply to.</item> <item><c>ReplyAs</c> can be any datum and is returned in the corresponding -<c>io_reply</c>. The <seealso marker="stdlib:io">io</seealso> module simply uses the pid() -of the I/O server as the <c>ReplyAs</c> datum, but a more complicated client +<c>io_reply</c>. The <seealso marker="stdlib:io">io</seealso> module monitors +the I/O server, and uses the monitor reference as the <c>ReplyAs</c> datum. +A more complicated client could have several outstanding I/O requests to the same I/O server and -would then use i.e. a <c>reference()</c> or something else to differentiate among +would then use different references (or something else) to differentiate among the incoming IO replies. The <c>ReplyAs</c> element should be considered opaque by the I/O server. Note that the <c>pid()</c> of the I/O server is not explicitly present in the <c>io_reply</c> tuple. The reply can be sent from any diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml index 64229fa8d3..f766c843be 100644 --- a/lib/stdlib/doc/src/maps.xml +++ b/lib/stdlib/doc/src/maps.xml @@ -330,7 +330,7 @@ false</code> <code type="none"> > Map = #{42 => value_three,1337 => "value two","a" => 1}, Ks = ["a",42,"other key"], - maps:without(Ks,Map). + maps:with(Ks,Map). #{42 => value_three,"a" => 1}</code> </desc> </func> diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index ebc750a399..8582bfc9f9 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -30,6 +30,109 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 2.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The documentation of string:tokens/2 now explicitly + specifies that adjacent separator characters do not give + any empty strings in the resulting list of tokens.</p> + <p> + Own Id: OTP-12036</p> + </item> + <item> + <p> + Fix broken deprecation warnings in ssh application</p> + <p> + Own Id: OTP-12187</p> + </item> + <item> + <p> + Maps: Properly align union typed assoc values in + documentation</p> + <p> + Own Id: OTP-12190</p> + </item> + <item> + <p> + Fix filelib:wildcard/2 when 'Cwd' ends with a dot</p> + <p> + Own Id: OTP-12212</p> + </item> + <item> + <p> + Allow <c>Name/Arity</c> syntax in maps values inside + attributes.</p> + <p> + Own Id: OTP-12213</p> + </item> + <item> + <p> + Fix edlin to correctly save text killed with ctrl-u. + Prior to this fix, entering text into the Erlang shell + and then killing it with ctrl-u followed by yanking it + back with ctrl-y would result in the yanked text being + the reverse of the original killed text.</p> + <p> + Own Id: OTP-12224</p> + </item> + <item> + <p> + If a callback function was terminated with exit/1, there + would be no stack trace in the ERROR REPORT produced by + gen_server. This has been corrected.</p> + <p> + To keep the backwards compatibility, the actual exit + reason for the process is not changed.</p> + <p> + Own Id: OTP-12263 Aux Id: seq12733 </p> + </item> + <item> + <p> + Warnings produced by <c>ms_transform</c> could point out + the wrong line number.</p> + <p> + Own Id: OTP-12264</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Supports tar file creation on other media than file + systems mounted on the local machine.</p> + <p> + The <c>erl_tar</c> api is extended with + <c>erl_tar:init/3</c> that enables usage of user provided + media storage routines. A ssh-specific set of such + routines is hidden in the new function + <c>ssh_sftp:open_tar/3</c> to simplify creating a tar + archive on a remote ssh server.</p> + <p> + A chunked file reading option is added to + <c>erl_tar:add/3,4</c> to save memory on e.g small + embedded systems. The size of the slices read from a file + in that case can be specified.</p> + <p> + Own Id: OTP-12180 Aux Id: seq12715 </p> + </item> + <item> + <p> + I/O requests are optimized for long message queues in the + calling process.</p> + <p> + Own Id: OTP-12315</p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 2.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index a1833f6a51..5af1468e9b 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -150,7 +150,11 @@ This option makes it possible to include comments inside complicated patterns. N <tag><c>no_start_optimize</c></tag> <item>This option disables optimization that may malfunction if "Special start-of-pattern items" are present in the regular expression. A typical example would be when matching "DEFABC" against "(*COMMIT)ABC", where the start optimization of PCRE would skip the subject up to the "A" and would never realize that the (*COMMIT) instruction should have made the matching fail. This option is only relevant if you use "start-of-pattern items", as discussed in the section "PCRE regular expression details" below.</item> <tag><c>ucp</c></tag> - <item>Specifies that Unicode Character Properties should be used when resolving \B, \b, \D, \d, \S, \s, \Wand \w. Without this flag, only ISO-Latin-1 properties are used. Using Unicode properties hurts performance, but is semantically correct when working with Unicode characters beyond the ISO-Latin-1 range.</item> + <item>Specifies that Unicode Character Properties should be used when + resolving \B, \b, \D, \d, \S, \s, \W and \w. Without this flag, only + ISO-Latin-1 properties are used. Using Unicode properties hurts + performance, but is semantically correct when working with Unicode + characters beyond the ISO-Latin-1 range.</item> <tag><c>never_utf</c></tag> <item>Specifies that the (*UTF) and/or (*UTF8) "start-of-pattern items" are forbidden. This flag can not be combined with <c>unicode</c>. Useful if ISO-Latin-1 patterns from an external source are to be compiled.</item> </taglist> @@ -966,7 +970,7 @@ appearance causes an error. </quote> <p>This has the same effect as setting the <c>ucp</c> option: it causes sequences such as \d and \w to use Unicode properties to determine character types, -instead of recognizing only characters with codes less than 128 via a lookup +instead of recognizing only characters with codes less than 256 via a lookup table. </p> @@ -1307,7 +1311,8 @@ By default, the definition of letters and digits is controlled by PCRE's low-valued character tables, in Erlang's case (and without the <c>unicode</c> option), the ISO-Latin-1 character set.</p> -<p>By default, in <c>unicode</c> mode, characters with values greater than 128 never match +<p>By default, in <c>unicode</c> mode, characters with values greater than 255, +i.e. all characters outside the ISO-Latin-1 character set, never match \d, \s, or \w, and always match \D, \S, and \W. These sequences retain their original meanings from before UTF support was available, mainly for efficiency reasons. However, if the <c>ucp</c> option is set, the behaviour is changed so that Unicode @@ -1954,10 +1959,10 @@ can be included in a class as a literal string of data units, or by using the upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a caseful version would. In a UTF mode, PCRE always understands the concept of -case for characters whose values are less than 128, so caseless matching is +case for characters whose values are less than 256, so caseless matching is always possible. For characters with higher values, the concept of case is supported if PCRE is compiled with Unicode property support, but not otherwise. -If you want to use caseless matching in a UTF mode for characters 128 and +If you want to use caseless matching in a UTF mode for characters 256 and above, you must ensure that PCRE is compiled with Unicode property support as well as with UTF support.</p> @@ -1989,7 +1994,7 @@ matches the letters in either case. For example, [W-c] is equivalent to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\xc8-\xcb] matches accented E characters in both cases. In UTF modes, PCRE supports the concept of case for -characters with values greater than 128 only when it is compiled with Unicode +characters with values greater than 255 only when it is compiled with Unicode property support.</p> <p>The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, @@ -2062,7 +2067,7 @@ by a ^ character after the colon. For example,</p> syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered.</p> -<p>By default, in UTF modes, characters with values greater than 128 do not match +<p>By default, in UTF modes, characters with values greater than 255 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to <b>pcre_compile()</b>, some of the classes are changed so that Unicode character properties are used. This is achieved by replacing the POSIX classes @@ -2081,7 +2086,7 @@ by other sequences, as follows:</p> <p>Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX classes are unchanged, and match only characters with code points less than -128.</p> +256.</p> </section> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index bebfbd4514..29b8940c62 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -50,12 +50,8 @@ encoded files in several circumstances. Most notable is the support for UTF-8 in files read by <c>file:consult/1</c>, release handler support for UTF-8 and more support for Unicode character sets in the - I/O-system.</p> - - <p>In Erlang/OTP 17.0, the encoding default for Erlang source files was - switched to UTF-8 and in Erlang/OTP 18.0 Erlang will support atoms in the full - Unicode range, meaning full Unicode function and module - names</p> + I/O-system. In Erlang/OTP 17.0, the encoding default for Erlang source files was + switched to UTF-8.</p> <p>This guide outlines the current Unicode support and gives a couple of recipes for working with Unicode data.</p> @@ -289,8 +285,8 @@ <tag>The language</tag> <item>Having the source code in UTF-8 also allows you to write string literals containing Unicode characters with code points > - 255, although atoms, module names and function names will be - restricted to the ISO-Latin-1 range until the Erlang/OTP 18.0 release. Binary + 255, although atoms, module names and function names are + restricted to the ISO-Latin-1 range. Binary literals where you use the <c>/utf8</c> type, can also be expressed using Unicode characters > 255. Having module names using characters other than 7-bit ASCII can cause trouble on @@ -385,8 +381,7 @@ external_charlist() = maybe_improper_list(char() | using characters from the ISO-latin-1 character set and atoms are restricted to the same ISO-latin-1 range. These restrictions in the language are of course independent of the encoding of the source - file. Erlang/OTP 18.0 is expected to handle functions named in - Unicode as well as Unicode atoms.</p> + file.</p> <section> <title>Bit-syntax</title> <p>The bit-syntax contains types for coping with binary data in the diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl index 4850a59eb6..8d07a356dd 100644 --- a/lib/stdlib/src/binary.erl +++ b/lib/stdlib/src/binary.erl @@ -89,9 +89,9 @@ copy(_, _) -> decode_unsigned(_) -> erlang:nif_error(undef). --spec decode_unsigned(Subject, Endianess) -> Unsigned when +-spec decode_unsigned(Subject, Endianness) -> Unsigned when Subject :: binary(), - Endianess :: big | little, + Endianness :: big | little, Unsigned :: non_neg_integer(). decode_unsigned(_, _) -> @@ -103,9 +103,9 @@ decode_unsigned(_, _) -> encode_unsigned(_) -> erlang:nif_error(undef). --spec encode_unsigned(Unsigned, Endianess) -> binary() when +-spec encode_unsigned(Unsigned, Endianness) -> binary() when Unsigned :: non_neg_integer(), - Endianess :: big | little. + Endianness :: big | little. encode_unsigned(_, _) -> erlang:nif_error(undef). diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index c2256c0cf9..9860adf04d 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -509,9 +509,12 @@ m(M) -> {exports,E} = lists:keyfind(exports, 1, L), Time = get_compile_time(L), COpts = get_compile_options(L), - format("Module ~w compiled: ",[M]), print_time(Time), - format("Compiler options: ~p~n", [COpts]), + format("Module: ~w~n", [M]), + print_md5(L), + format("Compiled: "), + print_time(Time), print_object_file(M), + format("Compiler options: ~p~n", [COpts]), format("Exports: ~n",[]), print_exports(keysort(1, E)). print_object_file(Mod) -> @@ -522,6 +525,12 @@ print_object_file(Mod) -> ignore end. +print_md5(L) -> + case lists:keyfind(md5, 1, L) of + {md5,<<MD5:128>>} -> io:format("MD5: ~.16b~n",[MD5]); + _ -> ok + end. + get_compile_time(L) -> case get_compile_info(L, time) of {ok,Val} -> Val; @@ -569,8 +578,8 @@ split_print_exports([{F1, A1}|T1], [{F2, A2} | T2]) -> split_print_exports([], []) -> ok. print_time({Year,Month,Day,Hour,Min,_Secs}) -> - format("Date: ~s ~w ~w, ", [month(Month),Day,Year]), - format("Time: ~.2.0w.~.2.0w~n", [Hour,Min]); + format("~s ~w ~w, ", [month(Month),Day,Year]), + format("~.2.0w:~.2.0w~n", [Hour,Min]); print_time(notime) -> format("No compile time info available~n",[]). diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl index 76e03bbfaa..a4bd45ea19 100644 --- a/lib/stdlib/src/dets.erl +++ b/lib/stdlib/src/dets.erl @@ -2839,17 +2839,22 @@ fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) -> tempfile(Fname) -> Tmp = lists:concat([Fname, ".TMP"]), - tempfile(Tmp, 10). - -tempfile(Tmp, 0) -> - Tmp; -tempfile(Tmp, N) -> case file:delete(Tmp) of - {error, eacces} -> % 'dets_process_died' happened anyway... (W-nd-ws) - timer:sleep(1000), - tempfile(Tmp, N-1); - _ -> - Tmp + {error, _Reason} -> % typically enoent + ok; + ok -> + assure_no_file(Tmp) + end, + Tmp. + +assure_no_file(File) -> + case file:read_file_info(File) of + {ok, _FileInfo} -> + %% Wait for some other process to close the file: + timer:sleep(100), + assure_no_file(File); + {error, _} -> + ok end. %% -> {ok, NewHead} | {try_again, integer()} | Error diff --git a/lib/stdlib/src/dets_server.erl b/lib/stdlib/src/dets_server.erl index 268c201047..3164d40f35 100644 --- a/lib/stdlib/src/dets_server.erl +++ b/lib/stdlib/src/dets_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2013. All Rights Reserved. +%% Copyright Ericsson AB 2001-2014. 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 @@ -171,9 +171,15 @@ handle_info({pending_reply, {Ref, Result0}}, State) -> link(Pid), do_link(Store, FromPid), true = ets:insert(Store, {FromPid, Tab}), - true = ets:insert(?REGISTRY, {Tab, 1, Pid}), - true = ets:insert(?OWNERS, {Pid, Tab}), + %% do_internal_open() has already done the following: + %% true = ets:insert(?REGISTRY, {Tab, 1, Pid}), + %% true = ets:insert(?OWNERS, {Pid, Tab}), {ok, Tab}; + {Reply, internal_open} -> + %% Clean up what do_internal_open() did: + true = ets:delete(?REGISTRY, Tab), + true = ets:delete(?OWNERS, Pid), + Reply; {Reply, _} -> % ok or Error Reply end, @@ -309,6 +315,12 @@ do_internal_open(State, From, Args) -> [T, _, _] -> T; [_, _] -> Ref end, + %% Pretend the table is open. If someone else tries to + %% open the file it will always become a pending + %% 'add_user' request. If someone tries to use the table + %% there will be a delay, but that is OK. + true = ets:insert(?REGISTRY, {Tab, 1, Pid}), + true = ets:insert(?OWNERS, {Pid, Tab}), pending_call(Tab, Pid, Ref, From, Args, internal_open, State); Error -> {Error, State} diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl index c74f68647f..64a00acd88 100644 --- a/lib/stdlib/src/erl_expand_records.erl +++ b/lib/stdlib/src/erl_expand_records.erl @@ -702,9 +702,10 @@ record_update(R, Name, Fs, Us0, St0) -> record_match(R, Name, Lr, Fs, Us, St0) -> {Ps,News,St1} = record_upd_fs(Fs, Us, St0), NLr = neg_line(Lr), + RLine = record_offset(Lr, St1), {{'case',Lr,R, - [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Ps]}],[], - [{tuple,Lr,[{atom,Lr,Name} | News]}]}, + [{clause,Lr,[{tuple,RLine,[{atom,Lr,Name} | Ps]}],[], + [{tuple,RLine,[{atom,Lr,Name} | News]}]}, {clause,NLr,[{var,NLr,'_'}],[], [call_error(NLr, {tuple,NLr,[{atom,NLr,badrecord},{atom,NLr,Name}]})]} ]}, @@ -733,6 +734,10 @@ record_setel(R, Name, Fs, Us0) -> Lr = element(2, hd(Us)), Wildcards = duplicate(length(Fs), {var,Lr,'_'}), NLr = neg_line(Lr), + %% Note: calling record_offset() here is not necessary since it is + %% targeted at Dialyzer which always calls the compiler with + %% 'strict_record_updates' meaning that record_setel() will never + %% be called. {'case',Lr,R, [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Wildcards]}],[], [foldr(fun ({I,Lf,Val}, Acc) -> diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl index acf7a5cd40..caa3276d09 100644 --- a/lib/stdlib/src/erl_tar.erl +++ b/lib/stdlib/src/erl_tar.erl @@ -22,7 +22,7 @@ %% Purpose: Unix tar (tape archive) utility. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([create/2, create/3, extract/1, extract/2, table/1, table/2, +-export([init/3, create/2, create/3, extract/1, extract/2, table/1, table/2, open/2, close/1, add/3, add/4, t/1, tt/1, format_error/1]). @@ -30,10 +30,16 @@ -record(add_opts, {read_info, % Fun to use for read file/link info. + chunk_size = 0, % For file reading when sending to sftp. 0=do not chunk verbose = false :: boolean()}). % Verbose on/off. %% Opens a tar archive. +init(UsrHandle, AccessMode, Fun) when is_function(Fun,2) -> + {ok, {AccessMode,{tar_descriptor,UsrHandle,Fun}}}. + +%%%================================================================ +%%% The open function with friends is to keep the file and binary api of this module open(Name, Mode) -> case open_mode(Mode) of {ok, Access, Raw, Opts} -> @@ -46,27 +52,37 @@ open1({binary,Bin}, read, _Raw, Opts) -> case file:open(Bin, [ram,binary,read]) of {ok,File} -> _ = [ram_file:uncompress(File) || Opts =:= [compressed]], - {ok,{read,File}}; + init(File,read,file_fun()); Error -> Error end; open1({file, Fd}, read, _Raw, _Opts) -> - {ok, {read, Fd}}; + init(Fd, read, file_fun()); open1(Name, Access, Raw, Opts) -> case file:open(Name, Raw ++ [binary, Access|Opts]) of {ok, File} -> - {ok, {Access, File}}; + init(File, Access, file_fun()); {error, Reason} -> {error, {Name, Reason}} end. +file_fun() -> + fun(write, {Fd,Data}) -> file:write(Fd, Data); + (position, {Fd,Pos}) -> file:position(Fd, Pos); + (read2, {Fd,Size}) -> file:read(Fd,Size); + (close, Fd) -> file:close(Fd) + end. + +%%% End of file and binary api (except for open_mode/1 downwards +%%%================================================================ + %% Closes a tar archive. close({read, File}) -> - ok = file:close(File); + ok = do_close(File); close({write, File}) -> PadResult = pad_file(File), - ok = file:close(File), + ok = do_close(File), PadResult; close(_) -> {error, einval}. @@ -75,7 +91,6 @@ close(_) -> add(File, Name, Options) -> add(File, Name, Name, Options). - add({write, File}, Name, NameInArchive, Options) -> Opts = #add_opts{read_info=fun(F) -> file:read_link_info(F) end}, add1(File, Name, NameInArchive, add_opts(Options, Opts)); @@ -88,6 +103,8 @@ add_opts([dereference|T], Opts) -> add_opts(T, Opts#add_opts{read_info=fun(F) -> file:read_file_info(F) end}); add_opts([verbose|T], Opts) -> add_opts(T, Opts#add_opts{verbose=true}); +add_opts([{chunks,N}|T], Opts) -> + add_opts(T, Opts#add_opts{chunk_size=N}); add_opts([_|T], Opts) -> add_opts(T, Opts); add_opts([], Opts) -> @@ -321,16 +338,46 @@ add1(TarFile, Name, NameInArchive, Opts) -> {error, {Name, Reason}} end. +add1(Tar, Name, Header, chunked, Options) -> + add_verbose(Options, "a ~ts [chunked ", [Name]), + try + ok = do_write(Tar, Header), + {ok,D} = file:open(Name, [read,binary]), + {ok,NumBytes} = add_read_write_chunks(D, Tar, Options#add_opts.chunk_size, 0, Options), + _ = file:close(D), + ok = do_write(Tar, padding(NumBytes,?record_size)) + of + ok -> + add_verbose(Options, "~n", []), + ok + catch + error:{badmatch,{error,Error}} -> + add_verbose(Options, "~n", []), + {error,{Name,Error}} + end; add1(Tar, Name, Header, Bin, Options) -> add_verbose(Options, "a ~ts~n", [Name]), - file:write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]). + do_write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]). + +add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes, Options) -> + case file:read(D, ChunkSize) of + {ok,Bin} -> + ok = do_write(Tar, Bin), + add_verbose(Options, ".", []), + add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes+byte_size(Bin), Options); + eof -> + add_verbose(Options, "]", []), + {ok,SumNumBytes}; + Other -> + Other + end. add_directory(TarFile, DirName, NameInArchive, Info, Options) -> case file:list_dir(DirName) of {ok, []} -> add_verbose(Options, "a ~ts~n", [DirName]), Header = create_header(NameInArchive, Info), - file:write(TarFile, Header); + do_write(TarFile, Header); {ok, Files} -> Add = fun (File) -> add1(TarFile, @@ -396,7 +443,7 @@ to_string(Str0, Count) -> %% Pads out end of file. pad_file(File) -> - {ok,Position} = file:position(File, {cur,0}), + {ok,Position} = do_position(File, {cur,0}), %% There must be at least two zero records at the end. Fill = case ?block_size - (Position rem ?block_size) of Fill0 when Fill0 < 2*?record_size -> @@ -407,7 +454,7 @@ pad_file(File) -> %% Large enough. Fill0 end, - file:write(File, zeroes(Fill)). + do_write(File, zeroes(Fill)). split_filename(Name) when length(Name) =< ?th_name_len -> {"", Name}; @@ -485,27 +532,36 @@ read_opts([_|Rest], Opts) -> read_opts([], Opts) -> Opts. +foldl_read({AccessMode,TD={tar_descriptor,_UsrHandle,_AccessFun}}, Fun, Accu, Opts) -> + case AccessMode of + read -> + foldl_read0(TD, Fun, Accu, Opts); + _ -> + {error,{read_mode_expected,AccessMode}} + end; foldl_read(TarName, Fun, Accu, Opts) -> case open(TarName, [read|Opts#read_opts.open_mode]) of {ok, {read, File}} -> - Result = - case catch foldl_read1(Fun, Accu, File, Opts) of - {'EXIT', Reason} -> - exit(Reason); - {error, {Reason, Format, Args}} -> - read_verbose(Opts, Format, Args), - {error, Reason}; - {error, Reason} -> - {error, Reason}; - Ok -> - Ok - end, - ok = file:close(File), + Result = foldl_read0(File, Fun, Accu, Opts), + ok = do_close(File), Result; Error -> Error end. +foldl_read0(File, Fun, Accu, Opts) -> + case catch foldl_read1(Fun, Accu, File, Opts) of + {'EXIT', Reason} -> + exit(Reason); + {error, {Reason, Format, Args}} -> + read_verbose(Opts, Format, Args), + {error, Reason}; + {error, Reason} -> + {error, Reason}; + Ok -> + Ok + end. + foldl_read1(Fun, Accu0, File, Opts) -> case get_header(File) of eof -> @@ -559,7 +615,7 @@ check_extract(Name, #read_opts{files=Files}) -> ordsets:is_element(Name, Files). get_header(File) -> - case file:read(File, ?record_size) of + case do_read(File, ?record_size) of eof -> throw({error,eof}); {ok, Bin} when is_binary(Bin) -> @@ -690,7 +746,7 @@ get_element(File, #tar_header{size = 0}) -> skip_to_next(File), {ok,<<>>}; get_element(File, #tar_header{size = Size}) -> - case file:read(File, Size) of + case do_read(File, Size) of {ok,Bin}=Res when byte_size(Bin) =:= Size -> skip_to_next(File), Res; @@ -880,7 +936,7 @@ skip(File, Size) -> %% Note: There is no point in handling failure to get the current position %% in the file. If it doesn't work, something serious is wrong. Amount = ((Size + ?record_size - 1) div ?record_size) * ?record_size, - {ok,_} = file:position(File, {cur, Amount}), + {ok,_} = do_position(File, {cur, Amount}), ok. %% Skips to the next record in the file. @@ -888,9 +944,9 @@ skip(File, Size) -> skip_to_next(File) -> %% Note: There is no point in handling failure to get the current position %% in the file. If it doesn't work, something serious is wrong. - {ok, Position} = file:position(File, {cur, 0}), + {ok, Position} = do_position(File, {cur, 0}), NewPosition = ((Position + ?record_size - 1) div ?record_size) * ?record_size, - {ok,NewPosition} = file:position(File, NewPosition), + {ok,NewPosition} = do_position(File, NewPosition), ok. %% Prints the message on if the verbose option is given. @@ -916,6 +972,9 @@ posix_to_erlang_time(Sec) -> read_file_and_info(Name, Opts) -> ReadInfo = Opts#add_opts.read_info, case ReadInfo(Name) of + {ok,Info} when Info#file_info.type =:= regular, + Opts#add_opts.chunk_size>0 -> + {ok,chunked,Info}; {ok,Info} when Info#file_info.type =:= regular -> case file:read_file(Name) of {ok,Bin} -> @@ -962,3 +1021,12 @@ open_mode([], Access, Raw, Opts) -> {ok, Access, Raw, Opts}; open_mode(_, _, _, _) -> {error, einval}. + +%%%================================================================ +do_write({tar_descriptor,UsrHandle,Fun}, Data) -> Fun(write,{UsrHandle,Data}). + +do_position({tar_descriptor,UsrHandle,Fun}, Pos) -> Fun(position,{UsrHandle,Pos}). + +do_read({tar_descriptor,UsrHandle,Fun}, Len) -> Fun(read2,{UsrHandle,Len}). + +do_close({tar_descriptor,UsrHandle,Fun}) -> Fun(close,UsrHandle). diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index dadfe56b3d..18ef4a2507 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -567,28 +567,88 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) -> end end. +%% --------------------------------------------------- +%% Helper functions for try-catch of callbacks. +%% Returns the return value of the callback, or +%% {'EXIT', ExitReason, ReportReason} (if an exception occurs) +%% +%% ExitReason is the reason that shall be used when the process +%% terminates. +%% +%% ReportReason is the reason that shall be printed in the error +%% report. +%% +%% These functions are introduced in order to add the stack trace in +%% the error report produced when a callback is terminated with +%% erlang:exit/1 (OTP-12263). +%% --------------------------------------------------- + +try_dispatch({'$gen_cast', Msg}, Mod, State) -> + try_dispatch(Mod, handle_cast, Msg, State); +try_dispatch(Info, Mod, State) -> + try_dispatch(Mod, handle_info, Info, State). + +try_dispatch(Mod, Func, Msg, State) -> + try + {ok, Mod:Func(Msg, State)} + catch + throw:R -> + {ok, R}; + error:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', {R, Stacktrace}, {R, Stacktrace}}; + exit:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', R, {R, Stacktrace}} + end. + +try_handle_call(Mod, Msg, From, State) -> + try + {ok, Mod:handle_call(Msg, From, State)} + catch + throw:R -> + {ok, R}; + error:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', {R, Stacktrace}, {R, Stacktrace}}; + exit:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', R, {R, Stacktrace}} + end. + +try_terminate(Mod, Reason, State) -> + try + {ok, Mod:terminate(Reason, State)} + catch + throw:R -> + {ok, R}; + error:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', {R, Stacktrace}, {R, Stacktrace}}; + exit:R -> + Stacktrace = erlang:get_stacktrace(), + {'EXIT', R, {R, Stacktrace}} + end. + + %%% --------------------------------------------------- %%% Message handling functions %%% --------------------------------------------------- -dispatch({'$gen_cast', Msg}, Mod, State) -> - Mod:handle_cast(Msg, State); -dispatch(Info, Mod, State) -> - Mod:handle_info(Info, State). - handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) -> - case catch Mod:handle_call(Msg, From, State) of - {reply, Reply, NState} -> + Result = try_handle_call(Mod, Msg, From, State), + case Result of + {ok, {reply, Reply, NState}} -> reply(From, Reply), loop(Parent, Name, NState, Mod, infinity, []); - {reply, Reply, NState, Time1} -> + {ok, {reply, Reply, NState, Time1}} -> reply(From, Reply), loop(Parent, Name, NState, Mod, Time1, []); - {noreply, NState} -> + {ok, {noreply, NState}} -> loop(Parent, Name, NState, Mod, infinity, []); - {noreply, NState, Time1} -> + {ok, {noreply, NState, Time1}} -> loop(Parent, Name, NState, Mod, Time1, []); - {stop, Reason, Reply, NState} -> + {ok, {stop, Reason, Reply, NState}} -> {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, NState, [])), reply(From, Reply), @@ -596,26 +656,27 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) -> Other -> handle_common_reply(Other, Parent, Name, Msg, Mod, State) end; handle_msg(Msg, Parent, Name, State, Mod) -> - Reply = (catch dispatch(Msg, Mod, State)), + Reply = try_dispatch(Msg, Mod, State), handle_common_reply(Reply, Parent, Name, Msg, Mod, State). handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> - case catch Mod:handle_call(Msg, From, State) of - {reply, Reply, NState} -> + Result = try_handle_call(Mod, Msg, From, State), + case Result of + {ok, {reply, Reply, NState}} -> Debug1 = reply(Name, From, Reply, NState, Debug), loop(Parent, Name, NState, Mod, infinity, Debug1); - {reply, Reply, NState, Time1} -> + {ok, {reply, Reply, NState, Time1}} -> Debug1 = reply(Name, From, Reply, NState, Debug), loop(Parent, Name, NState, Mod, Time1, Debug1); - {noreply, NState} -> + {ok, {noreply, NState}} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); - {noreply, NState, Time1} -> + {ok, {noreply, NState, Time1}} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); - {stop, Reason, Reply, NState} -> + {ok, {stop, Reason, Reply, NState}} -> {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, NState, Debug)), _ = reply(Name, From, Reply, NState, Debug), @@ -624,39 +685,39 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> handle_common_reply(Other, Parent, Name, Msg, Mod, State, Debug) end; handle_msg(Msg, Parent, Name, State, Mod, Debug) -> - Reply = (catch dispatch(Msg, Mod, State)), + Reply = try_dispatch(Msg, Mod, State), handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug). handle_common_reply(Reply, Parent, Name, Msg, Mod, State) -> case Reply of - {noreply, NState} -> + {ok, {noreply, NState}} -> loop(Parent, Name, NState, Mod, infinity, []); - {noreply, NState, Time1} -> + {ok, {noreply, NState, Time1}} -> loop(Parent, Name, NState, Mod, Time1, []); - {stop, Reason, NState} -> + {ok, {stop, Reason, NState}} -> terminate(Reason, Name, Msg, Mod, NState, []); - {'EXIT', What} -> - terminate(What, Name, Msg, Mod, State, []); - _ -> - terminate({bad_return_value, Reply}, Name, Msg, Mod, State, []) + {'EXIT', ExitReason, ReportReason} -> + terminate(ExitReason, ReportReason, Name, Msg, Mod, State, []); + {ok, BadReply} -> + terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, []) end. handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) -> case Reply of - {noreply, NState} -> + {ok, {noreply, NState}} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, infinity, Debug1); - {noreply, NState, Time1} -> + {ok, {noreply, NState, Time1}} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}), loop(Parent, Name, NState, Mod, Time1, Debug1); - {stop, Reason, NState} -> + {ok, {stop, Reason, NState}} -> terminate(Reason, Name, Msg, Mod, NState, Debug); - {'EXIT', What} -> - terminate(What, Name, Msg, Mod, State, Debug); - _ -> - terminate({bad_return_value, Reply}, Name, Msg, Mod, State, Debug) + {'EXIT', ExitReason, ReportReason} -> + terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug); + {ok, BadReply} -> + terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, Debug) end. reply(Name, {To, Tag}, Reply, State, Debug) -> @@ -717,14 +778,20 @@ print_event(Dev, Event, Name) -> %%% Terminate the server. %%% --------------------------------------------------- +-spec terminate(_, _, _, _, _, _) -> no_return(). terminate(Reason, Name, Msg, Mod, State, Debug) -> - case catch Mod:terminate(Reason, State) of - {'EXIT', R} -> + terminate(Reason, Reason, Name, Msg, Mod, State, Debug). + +-spec terminate(_, _, _, _, _, _, _) -> no_return(). +terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug) -> + Reply = try_terminate(Mod, ExitReason, State), + case Reply of + {'EXIT', ExitReason1, ReportReason1} -> FmtState = format_status(terminate, Mod, get(), State), - error_info(R, Name, Msg, FmtState, Debug), - exit(R); + error_info(ReportReason1, Name, Msg, FmtState, Debug), + exit(ExitReason1); _ -> - case Reason of + case ExitReason of normal -> exit(normal); shutdown -> @@ -733,8 +800,8 @@ terminate(Reason, Name, Msg, Mod, State, Debug) -> exit(Shutdown); _ -> FmtState = format_status(terminate, Mod, get(), State), - error_info(Reason, Name, Msg, FmtState, Debug), - exit(Reason) + error_info(ReportReason, Name, Msg, FmtState, Debug), + exit(ExitReason) end end. diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl index 27e2a82b41..b9ace2f442 100644 --- a/lib/stdlib/src/io.erl +++ b/lib/stdlib/src/io.erl @@ -566,12 +566,23 @@ request(Name, Request) when is_atom(Name) -> execute_request(Pid, {Convert,Converted}) -> Mref = erlang:monitor(process, Pid), - Pid ! {io_request,self(),Pid,Converted}, - if - Convert -> - convert_binaries(wait_io_mon_reply(Pid, Mref)); - true -> - wait_io_mon_reply(Pid, Mref) + Pid ! {io_request,self(),Mref,Converted}, + + receive + {io_reply, Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + if + Convert -> + convert_binaries(Reply); + true -> + Reply + end; + {'DOWN', Mref, _, _, _} -> + receive + {'EXIT', Pid, _What} -> true + after 0 -> true + end, + {error,terminated} end. requests(Requests) -> %Requests as atomic action @@ -597,26 +608,6 @@ default_input() -> default_output() -> group_leader(). -wait_io_mon_reply(From, Mref) -> - receive - {io_reply, From, Reply} -> - erlang:demonitor(Mref, [flush]), - Reply; - {'EXIT', From, _What} -> - receive - {'DOWN', Mref, _, _, _} -> true - after 0 -> true - end, - {error,terminated}; - {'DOWN', Mref, _, _, _} -> - receive - {'EXIT', From, _What} -> true - after 0 -> true - end, - {error,terminated} - end. - - %% io_requests(Requests) %% Transform requests into correct i/o server messages. Only handle the %% one we KNOW must be changed, others, including incorrect ones, are diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl index 27dfcf52e1..97564e2e44 100644 --- a/lib/stdlib/src/ms_transform.erl +++ b/lib/stdlib/src/ms_transform.erl @@ -725,10 +725,10 @@ transform_head([V],OuterBound) -> th(NewV,NewBind,OuterBound). -toplevel_head_match({match,Line,{var,_,VName},Expr},B,OB) -> +toplevel_head_match({match,_,{var,Line,VName},Expr},B,OB) -> warn_var_clash(Line,VName,OB), {Expr,new_bind({VName,'$_'},B)}; -toplevel_head_match({match,Line,Expr,{var,_,VName}},B,OB) -> +toplevel_head_match({match,_,Expr,{var,Line,VName}},B,OB) -> warn_var_clash(Line,VName,OB), {Expr,new_bind({VName,'$_'},B)}; toplevel_head_match(Other,B,_OB) -> diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl index 119b4dc7cb..3b08ac165e 100644 --- a/lib/stdlib/test/dets_SUITE.erl +++ b/lib/stdlib/test/dets_SUITE.erl @@ -223,8 +223,7 @@ open(Config, Version) -> ?format("Crashing dets server \n", []), process_flag(trap_exit, true), - Procs = [whereis(?DETS_SERVER) | map(fun(Tab) -> dets:info(Tab, pid) end, - Tabs)], + Procs = [whereis(?DETS_SERVER) | [dets:info(Tab, pid) || Tab <- Tabs]], foreach(fun(Pid) -> exit(Pid, kill) end, Procs), timer:sleep(100), c:flush(), %% flush all the EXIT sigs @@ -235,18 +234,32 @@ open(Config, Version) -> open_files(1, All, Version), ?format("Checking contents of repaired files \n", []), check(Tabs, Data), - - close_all(Tabs), + close_all(Tabs), delete_files(All), - P1 = pps(), + {Ports0, Procs0} = P0, - {Ports1, Procs1} = P1, - true = Ports1 =:= Ports0, - %% The dets_server process has been restarted: - [_] = Procs0 -- Procs1, - [_] = Procs1 -- Procs0, - ok. + Test = fun() -> + P1 = pps(), + {Ports1, Procs1} = P1, + show("Old port", Ports0 -- Ports1), + show("New port", Ports1 -- Ports0), + show("Old procs", Procs0 -- Procs1), + show("New procs", Procs1 -- Procs0), + io:format("Remaining Dets-pids (should be nil): ~p~n", + [find_dets_pids()]), + true = Ports1 =:= Ports0, + %% The dets_server process has been restarted: + [_] = Procs0 -- Procs1, + [_] = Procs1 -- Procs0, + ok + end, + case catch Test() of + ok -> ok; + _ -> + timer:sleep(500), + ok = Test() + end. check(Tabs, Data) -> foreach(fun(Tab) -> @@ -3275,12 +3288,22 @@ simultaneous_open(Config) -> File = filename(Tab, Config), ok = monit(Tab, File), - ok = kill_while_repairing(Tab, File), - ok = kill_while_init(Tab, File), - ok = open_ro(Tab, File), - ok = open_w(Tab, File, 0, Config), - ok = open_w(Tab, File, 100, Config), - ok. + case feasible() of + false -> {comment, "OK, but did not run all of the test"}; + true -> + ok = kill_while_repairing(Tab, File), + ok = kill_while_init(Tab, File), + ok = open_ro(Tab, File), + ok = open_w(Tab, File, 0, Config), + ok = open_w(Tab, File, 100, Config) + end. + +feasible() -> + LP = erlang:system_info(logical_processors), + (is_integer(LP) + andalso LP >= erlang:system_info(schedulers_online) + andalso not erlang:system_info(debug_compiled) + andalso not erlang:system_info(lock_checking)). %% One process logs and another process closes the log. Before %% monitors were used, this would make the client never return. @@ -3307,7 +3330,6 @@ kill_while_repairing(Tab, File) -> Delay = 1000, dets:start(), Parent = self(), - Ps = processes(), F = fun() -> R = (catch dets:open_file(Tab, [{file,File}])), timer:sleep(Delay), @@ -3318,7 +3340,7 @@ kill_while_repairing(Tab, File) -> P1 = spawn(F), P2 = spawn(F), P3 = spawn(F), - DetsPid = find_dets_pid([P1, P2, P3 | Ps]), + DetsPid = find_dets_pid(), exit(DetsPid, kill), receive {P1,R1} -> R1 end, @@ -3342,12 +3364,6 @@ kill_while_repairing(Tab, File) -> file:delete(File), ok. -find_dets_pid(P0) -> - case lists:sort(processes() -- P0) of - [P, _] -> P; - _ -> timer:sleep(100), find_dets_pid(P0) - end. - find_dets_pid() -> case find_dets_pids() of [] -> @@ -3421,6 +3437,13 @@ open_ro(Tab, File) -> open_w(Tab, File, Delay, Config) -> create_opened_log(File), + + Tab2 = t2, + File2 = filename(Tab2, Config), + file:delete(File2), + {ok,Tab2} = dets:open_file(Tab2, [{file,File2}]), + ok = dets:close(Tab2), + Parent = self(), F = fun() -> R = dets:open_file(Tab, [{file,File}]), @@ -3430,16 +3453,16 @@ open_w(Tab, File, Delay, Config) -> Pid1 = spawn(F), Pid2 = spawn(F), Pid3 = spawn(F), - undefined = dets:info(Tab), % is repairing now - 0 = qlen(), - Tab2 = t2, - File2 = filename(Tab2, Config), - file:delete(File2), + ok = wait_for_repair_to_start(Tab), + + %% It is assumed that it takes some time to repair the file. {ok,Tab2} = dets:open_file(Tab2, [{file,File2}]), + %% The Dets server managed to handle to open_file request. + 0 = qlen(), % still repairing + ok = dets:close(Tab2), file:delete(File2), - 0 = qlen(), % still repairing receive {Pid1,R1} -> {ok, Tab} = R1 end, receive {Pid2,R2} -> {ok, Tab} = R2 end, @@ -3456,6 +3479,15 @@ open_w(Tab, File, Delay, Config) -> file:delete(File), ok. +wait_for_repair_to_start(Tab) -> + case catch dets_server:get_pid(Tab) of + {'EXIT', _} -> + timer:sleep(1), + wait_for_repair_to_start(Tab); + Pid when is_pid(Pid) -> + ok + end. + qlen() -> {_, {_, N}} = lists:keysearch(message_queue_len, 1, process_info(self())), N. @@ -4350,6 +4382,7 @@ check_badarg({'EXIT', {badarg, [{M,F,A,_} | _]}}, M, F, Args) -> true = test_server:is_native(M) andalso length(Args) =:= A. check_pps({Ports0,Procs0} = P0) -> + ok = check_dets_tables(), case pps() of P0 -> ok; @@ -4375,13 +4408,45 @@ check_pps({Ports0,Procs0} = P0) -> end end. +%% Copied from dets_server.erl: +-define(REGISTRY, dets_registry). +-define(OWNERS, dets_owners). +-define(STORE, dets). + +check_dets_tables() -> + Store = [T || + T <- ets:all(), + ets:info(T, name) =:= ?STORE, + owner(T) =:= dets], + S = case Store of + [Tab] -> ets:tab2list(Tab); + [] -> [] + end, + case {ets:tab2list(?REGISTRY), ets:tab2list(?OWNERS), S} of + {[], [], []} -> ok; + {R, O, _} -> + io:format("Registry: ~p~n", [R]), + io:format("Owners: ~p~n", [O]), + io:format("Store: ~p~n", [S]), + not_ok + end. + +owner(Tab) -> + Owner = ets:info(Tab, owner), + case process_info(Owner, registered_name) of + {registered_name, Name} -> Name; + _ -> Owner + end. + show(_S, []) -> ok; -show(S, [Pid|Pids]) when is_pid(Pid) -> - io:format("~s: ~p~n", [S, erlang:process_info(Pid)]), +show(S, [{Pid, Name, InitCall}|Pids]) when is_pid(Pid) -> + io:format("~s: ~w (~w), ~w: ~p~n", + [S, Pid, proc_reg_name(Name), InitCall, + erlang:process_info(Pid)]), show(S, Pids); -show(S, [Port|Ports]) when is_port(Port)-> - io:format("~s: ~p~n", [S, erlang:port_info(Port)]), +show(S, [{Port, _}|Ports]) when is_port(Port)-> + io:format("~s: ~w: ~p~n", [S, Port, erlang:port_info(Port)]), show(S, Ports). pps() -> @@ -4397,5 +4462,8 @@ process_list() -> safe_second_element(process_info(P, initial_call))} || P <- processes()]. +proc_reg_name({registered_name, Name}) -> Name; +proc_reg_name([]) -> no_reg_name. + safe_second_element({_,Info}) -> Info; safe_second_element(Other) -> Other. diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl index 336065b258..39f0442824 100644 --- a/lib/stdlib/test/gen_fsm_SUITE.erl +++ b/lib/stdlib/test/gen_fsm_SUITE.erl @@ -434,7 +434,7 @@ terminate_crash_format(Config) when is_list(Config) -> io:format("Timeout: expected error logger msg", []), ?t:fail() end, - [] = ?t:messages_get(), + _ = ?t:messages_get(), process_flag(trap_exit, OldFl), ok. diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl index 42694d8b5d..0f03fda30a 100644 --- a/lib/stdlib/test/gen_server_SUITE.erl +++ b/lib/stdlib/test/gen_server_SUITE.erl @@ -275,7 +275,9 @@ crash(Config) when is_list(Config) -> receive {error,_GroupLeader4,{Pid4, "** Generic server"++_, - [Pid4,crash,{formatted, state4},crashed]}} -> + [Pid4,crash,{formatted, state4}, + {crashed,[{?MODULE,handle_call,3,_} + |_Stacktrace]}]}} -> ok; Other4a -> ?line io:format("Unexpected: ~p", [Other4a]), @@ -1026,7 +1028,9 @@ error_format_status(Config) when is_list(Config) -> receive {error,_GroupLeader,{Pid, "** Generic server"++_, - [Pid,crash,{formatted, State},crashed]}} -> + [Pid,crash,{formatted, State}, + {crashed,[{?MODULE,handle_call,3,_} + |_Stacktrace]}]}} -> ok; Other -> ?line io:format("Unexpected: ~p", [Other]), @@ -1048,7 +1052,9 @@ terminate_crash_format(Config) when is_list(Config) -> receive {error,_GroupLeader,{Pid, "** Generic server"++_, - [Pid,stop, {formatted, State},{crash, terminate}]}} -> + [Pid,stop, {formatted, State}, + {{crash, terminate},[{?MODULE,terminate,2,_} + |_Stacktrace]}]}} -> ok; Other -> io:format("Unexpected: ~p", [Other]), diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl index 3a76275f31..2203dd8f51 100644 --- a/lib/stdlib/test/io_SUITE.erl +++ b/lib/stdlib/test/io_SUITE.erl @@ -30,7 +30,8 @@ io_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1, printable_range/1, io_lib_print_binary_depth_one/1, otp_10302/1, otp_10755/1, - otp_10836/1, io_lib_width_too_small/1]). + otp_10836/1, io_lib_width_too_small/1, + io_with_huge_message_queue/1]). -export([pretty/2]). @@ -70,7 +71,7 @@ all() -> io_fread_newlines, otp_8989, io_lib_fread_literal, printable_range, io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836, - io_lib_width_too_small]. + io_lib_width_too_small, io_with_huge_message_queue]. groups() -> []. @@ -2219,3 +2220,44 @@ io_lib_width_too_small(Config) -> "**" = lists:flatten(io_lib:format("~2.3w", [3.14])), "**" = lists:flatten(io_lib:format("~2.5w", [3.14])), ok. + +%% Test that the time for a huge message queue is not +%% significantly slower than with an empty message queue. +io_with_huge_message_queue(Config) when is_list(Config) -> + case test_server:is_native(gen) of + true -> + {skip, + "gen is native - huge message queue optimization " + "is not implemented"}; + false -> + do_io_with_huge_message_queue(Config) + end. + +do_io_with_huge_message_queue(Config) -> + PrivDir = ?privdir(Config), + File = filename:join(PrivDir, "slask"), + {ok, F1} = file:open(File, [write]), + + {Time,ok} = timer:tc(fun() -> writes(1000, F1) end), + + [self() ! {msg,N} || N <- lists:seq(1, 500000)], + erlang:garbage_collect(), + {NewTime,ok} = timer:tc(fun() -> writes(1000, F1) end), + file:close(F1), + io:format("Time for empty message queue: ~p", [Time]), + io:format("Time for huge message queue: ~p", [NewTime]), + + IsCover = test_server:is_cover(), + case (NewTime+1) / (Time+1) of + Q when Q < 10; IsCover -> + ok; + Q -> + io:format("Q = ~p", [Q]), + ?t:fail() + end, + ok. + +writes(0, _) -> ok; +writes(N, F1) -> + file:write(F1, "hello\n"), + writes(N - 1, F1). diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl index 4ec13ed472..1577caa80f 100644 --- a/lib/stdlib/test/ms_transform_SUITE.erl +++ b/lib/stdlib/test/ms_transform_SUITE.erl @@ -91,21 +91,23 @@ warnings(Config) when is_list(Config) -> " end)">>, ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = compile_ww(Prog), - Prog2 = <<"C=5, " - "ets:fun2ms(fun({A,B} = C) " - " when is_integer(A) and (A+5 > B) -> " - " {A andalso B,C} " - " end)">>, - ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + Prog2 = <<"C = 5, + ets:fun2ms(fun ({A,B} = + C) when is_integer(A) and (A+5 > B) -> + {A andalso B,C} + end)">>, + [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = compile_ww(Prog2), Rec3 = <<"-record(a,{a,b,c,d=foppa}).">>, - Prog3 = <<"A=3,C=5, " - "ets:fun2ms(fun(#a{a = A, b = B} = C) " - " when is_integer(A) and (A+5 > B) -> " - " {A andalso B,C} " - " end)">>, - ?line [{_,[{_,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}, - {_,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}]}] = + Prog3 = <<"A = 3, + C = 5, + ets:fun2ms(fun (C + = #a{a = A, b = B}) + when is_integer(A) and (A+5 > B) -> + {A andalso B,C} + end)">>, + [{_,[{3,ms_transform,{?WARN_NUMBER_SHADOW,'C'}}, + {4,ms_transform,{?WARN_NUMBER_SHADOW,'A'}}]}] = compile_ww(Rec3,Prog3), Rec4 = <<"-record(a,{a,b,c,d=foppa}).">>, Prog4 = <<"A=3,C=5, " @@ -867,6 +869,7 @@ compile_ww(Records,Expr) -> "-include_lib(\"stdlib/include/ms_transform.hrl\").\n", "-export([tmp/0]).\n", Records/binary,"\n", + "-file(?FILE, 0). ", "tmp() ->\n", Expr/binary,".\n">>, FN=temp_name(), diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl index 6349139925..9b6d65011e 100644 --- a/lib/stdlib/test/tar_SUITE.erl +++ b/lib/stdlib/test/tar_SUITE.erl @@ -654,6 +654,7 @@ open_add_close(Config) when is_list(Config) -> ?line ok = erl_tar:add(AD, FileOne, []), ?line ok = erl_tar:add(AD, FileTwo, "second file", []), ?line ok = erl_tar:add(AD, FileThree, [verbose]), + ?line ok = erl_tar:add(AD, FileThree, "chunked", [{chunks,11411},verbose]), ?line ok = erl_tar:add(AD, ADir, [verbose]), ?line ok = erl_tar:add(AD, AnotherDir, [verbose]), ?line ok = erl_tar:close(AD), @@ -661,7 +662,7 @@ open_add_close(Config) when is_list(Config) -> ?line ok = erl_tar:t(TarOne), ?line ok = erl_tar:tt(TarOne), - ?line {ok,[FileOne,"second file",FileThree,ADir,SomeContent]} = erl_tar:table(TarOne), + ?line {ok,[FileOne,"second file",FileThree,"chunked",ADir,SomeContent]} = erl_tar:table(TarOne), ?line delete_files(["oac_file","oac_small","oac_big",Dir,AnotherDir,ADir]), diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index b522c3ea3c..5be130bac9 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 2.2 +STDLIB_VSN = 2.3 diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 8384af53b0..b0f11bb243 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -31,6 +31,27 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> +<section><title>Syntax_Tools 1.6.17</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Teach Maps to erl_syntax</p> + <p> + Affected functions: <list> + <item>erl_syntax:abstract/1</item> + <item>erl_syntax:concrete/1</item> + <item>erl_syntax:is_leaf/1</item> + <item>erl_syntax:is_literal/1</item> </list></p> + <p> + Own Id: OTP-12265</p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 1.6.16</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl index 7e12eab1b5..3ca7a8197e 100644 --- a/lib/syntax_tools/src/epp_dodger.erl +++ b/lib/syntax_tools/src/epp_dodger.erl @@ -88,7 +88,7 @@ %% This is a so-called Erlang I/O ErrorInfo structure; see the {@link %% //stdlib/io} module for details. --type errorinfo() :: term(). % {integer(), atom(), term()}. +-type errorinfo() :: {integer(), atom(), term()}. -type option() :: atom() | {atom(), term()}. @@ -208,8 +208,8 @@ do_parse_file(DefEncoding, File, Parser, Options) -> try Parser(Dev, 1, Options) after ok = file:close(Dev) end; - {error, _} = Error -> - Error + {error, Error} -> + {error, {0, file, Error}} % defer to file:format_error/1 end. find_invalid_unicode([H|T]) -> diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index 46a5ca48df..40372a2106 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -669,6 +669,9 @@ is_leaf(Node) -> operator -> true; % nonstandard type string -> true; text -> true; % nonstandard type + map_expr -> + map_expr_fields(Node) =:= [] andalso + map_expr_argument(Node) =:= none; tuple -> tuple_elements(Node) =:= []; underscore -> true; variable -> true; @@ -6093,6 +6096,9 @@ abstract([]) -> nil(); abstract(T) when is_tuple(T) -> tuple(abstract_list(tuple_to_list(T))); +abstract(T) when is_map(T) -> + map_expr([map_field_assoc(abstract(Key),abstract(Value)) + || {Key,Value} <- maps:to_list(T)]); abstract(T) when is_binary(T) -> binary([binary_field(integer(B)) || B <- binary_to_list(T)]); abstract(T) -> @@ -6154,6 +6160,14 @@ concrete(Node) -> | concrete(list_tail(Node))]; tuple -> list_to_tuple(concrete_list(tuple_elements(Node))); + map_expr -> + As = [tuple([map_field_assoc_name(F), + map_field_assoc_value(F)]) || F <- map_expr_fields(Node)], + M0 = maps:from_list(concrete_list(As)), + case map_expr_argument(Node) of + none -> M0; + Node0 -> maps:merge(concrete(Node0),M0) + end; binary -> Fs = [revert_binary_field( binary_field(binary_field_body(F), @@ -6209,10 +6223,31 @@ is_literal(T) -> is_literal(list_head(T)) andalso is_literal(list_tail(T)); tuple -> lists:all(fun is_literal/1, tuple_elements(T)); + map_expr -> + case map_expr_argument(T) of + none -> true; + Arg -> is_literal(Arg) + end andalso lists:all(fun is_literal_map_field/1, map_expr_fields(T)); + binary -> + lists:all(fun is_literal_binary_field/1, binary_fields(T)); _ -> false end. +is_literal_binary_field(F) -> + case binary_field_types(F) of + [] -> is_literal(binary_field_body(F)); + _ -> false + end. + +is_literal_map_field(F) -> + case type(F) of + map_field_assoc -> + is_literal(map_field_assoc_name(F)) andalso + is_literal(map_field_assoc_value(F)); + map_field_exact -> + false + end. %% ===================================================================== %% @doc Returns an `erl_parse'-compatible representation of a diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile index d4733b9a42..f67e3f8984 100644 --- a/lib/syntax_tools/test/Makefile +++ b/lib/syntax_tools/test/Makefile @@ -61,5 +61,6 @@ release_tests_spec: make_emakefile $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) syntax_tools.spec syntax_tools.cover "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl index 6fb3e5ccfb..3c6b33f459 100644 --- a/lib/syntax_tools/test/syntax_tools_SUITE.erl +++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl @@ -24,12 +24,16 @@ init_per_group/2,end_per_group/2]). %% Test cases --export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1]). +-export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1, + t_abstract_type/1,t_erl_parse_type/1,t_epp_dodger/1, + t_comment_scan/1,t_igor/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test,appup_test,smoke_test,revert,revert_map]. + [app_test,appup_test,smoke_test,revert,revert_map, + t_abstract_type,t_erl_parse_type,t_epp_dodger, + t_comment_scan,t_igor]. groups() -> []. @@ -54,15 +58,15 @@ appup_test(Config) when is_list(Config) -> %% Read and parse all source in the OTP release. smoke_test(Config) when is_list(Config) -> - ?line Dog = ?t:timetrap(?t:minutes(12)), - ?line Wc = filename:join([code:lib_dir(),"*","src","*.erl"]), - ?line Fs = filelib:wildcard(Wc), - ?line io:format("~p files\n", [length(Fs)]), - ?line case p_run(fun smoke_test_file/1, Fs) of - 0 -> ok; - N -> ?line ?t:fail({N,errors}) - end, - ?line ?t:timetrap_cancel(Dog). + Dog = ?t:timetrap(?t:minutes(12)), + Wc = filename:join([code:lib_dir(),"*","src","*.erl"]), + Fs = filelib:wildcard(Wc), + io:format("~p files\n", [length(Fs)]), + case p_run(fun smoke_test_file/1, Fs) of + 0 -> ok; + N -> ?t:fail({N,errors}) + end, + ?t:timetrap_cancel(Dog). smoke_test_file(File) -> case epp_dodger:parse_file(File) of @@ -94,9 +98,9 @@ revert(Config) when is_list(Config) -> io:format("~p files\n", [length(Fs)]), case p_run(fun (File) -> revert_file(File, Path) end, Fs) of 0 -> ok; - N -> ?line ?t:fail({N,errors}) + N -> ?t:fail({N,errors}) end, - ?line ?t:timetrap_cancel(Dog). + ?t:timetrap_cancel(Dog). revert_file(File, Path) -> case epp:parse_file(File, Path, []) of @@ -110,14 +114,298 @@ revert_file(File, Path) -> end. %% Testing bug fix for reverting map_field_assoc -revert_map(Config) -> +revert_map(Config) when is_list(Config) -> Dog = ?t:timetrap(?t:minutes(1)), - ?line [{map_field_assoc,16,{atom,17,name},{var,18,'Value'}}] = - erl_syntax:revert_forms([{tree,map_field_assoc, - {attr,16,[],none}, - {map_field_assoc, - {atom,17,name},{var,18,'Value'}}}]), - ?line ?t:timetrap_cancel(Dog). + [{map_field_assoc,16,{atom,17,name},{var,18,'Value'}}] = + erl_syntax:revert_forms([{tree,map_field_assoc, + {attr,16,[],none}, + {map_field_assoc,{atom,17,name},{var,18,'Value'}}}]), + ?t:timetrap_cancel(Dog). + + + +%% api tests + +t_abstract_type(Config) when is_list(Config) -> + F = fun validate_abstract_type/1, + ok = validate(F,[{hi,atom}, + {1,integer}, + {1.0,float}, + {$a,integer}, + {[],nil}, + {[<<1,2>>,a,b],list}, + {[2,3,<<1,2>>,a,b],list}, + {[$a,$b,$c],string}, + {"hello world",string}, + {<<1,2,3>>,binary}, + {#{a=>1,"b"=>2},map_expr}, + {#{#{i=>1}=>1,"b"=>#{v=>2}},map_expr}, + {{a,b,c},tuple}]), + ok. + +t_erl_parse_type(Config) when is_list(Config) -> + F = fun validate_erl_parse_type/1, + %% leaf types + ok = validate(F,[{"1",integer,true}, + {"123456789",integer,true}, + {"$h", char,true}, + {"3.1415", float,true}, + {"1.33e36", float,true}, + {"\"1.33e36: hello\"", string,true}, + {"Var1", variable,true}, + {"_", underscore,true}, + {"[]", nil,true}, + {"{}", tuple,true}, + {"#{}",map_expr,true}, + {"'some atom'", atom, true}]), + %% composite types + ok = validate(F,[{"case X of t -> t; f -> f end", case_expr,false}, + {"try X of t -> t catch C:R -> error end", try_expr,false}, + {"receive X -> X end", receive_expr,false}, + {"receive M -> X1 after T -> X2 end", receive_expr,false}, + {"catch (X)", catch_expr,false}, + {"fun(X) -> X end", fun_expr,false}, + {"fun Foo(X) -> X end", named_fun_expr,false}, + {"fun foo/2", implicit_fun,false}, + {"fun bar:foo/2", implicit_fun,false}, + {"if X -> t; true -> f end", if_expr,false}, + {"<<1,2,3,4>>", binary,false}, + {"<<1,2,3,4:5>>", binary,false}, + {"<<V1:63,V2:22/binary, V3/bits>>", binary,false}, + {"begin X end", block_expr,false}, + {"foo(X1,X2)", application,false}, + {"bar:foo(X1,X2)", application,false}, + {"[1,2,3,4]", list,false}, + {"[1|4]", list, false}, + {"[<<1>>,<<2>>,-2,<<>>,[more,list]]", list,false}, + {"[1|[2|[3|[4|[]]]]]", list,false}, + {"#{ a=>1, b=>2 }", map_expr,false}, + {"#{3=>3}#{ a=>1, b=>2 }", map_expr,false}, + {"#{ a:=1, b:=2 }", map_expr,false}, + {"M#{ a=>1, b=>2 }", map_expr,false}, + {"[V||V <- Vs]", list_comp,false}, + {"<< <<B>> || <<B>> <= Bs>>", binary_comp,false}, + {"#state{ a = A, b = B}", record_expr,false}, + {"#state{}", record_expr,false}, + {"#s{ a = #def{ a=A }, b = B}", record_expr,false}, + {"State#state{ a = A, b = B}", record_expr,false}, + {"State#state.a", record_access,false}, + {"#state.a", record_index_expr,false}, + {"-X", prefix_expr,false}, + {"X1 + X2", infix_expr,false}, + {"(X1 + X2) * X3", infix_expr,false}, + {"X1 = X2", match_expr,false}, + {"{a,b,c}", tuple,false}]), + ok. + +%% the macro ?MODULE seems faulty +t_epp_dodger(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + Filenames = ["syntax_tools_SUITE_test_module.erl", + "syntax_tools_test.erl"], + ok = test_epp_dodger(Filenames,DataDir,PrivDir), + ok. + +t_comment_scan(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + Filenames = ["syntax_tools_SUITE_test_module.erl", + "syntax_tools_test.erl"], + ok = test_comment_scan(Filenames,DataDir), + ok. + +t_igor(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + FileM1 = filename:join(DataDir,"m1.erl"), + FileM2 = filename:join(DataDir,"m2.erl"), + ["m.erl",_]=R = igor:merge(m,[FileM1,FileM2],[{outdir,PrivDir}]), + io:format("igor:merge/3 = ~p~n", [R]), + ok. + +test_comment_scan([],_) -> ok; +test_comment_scan([File|Files],DataDir) -> + Filename = filename:join(DataDir,File), + {ok, Fs0} = epp:parse_file(Filename, [], []), + Comments = erl_comment_scan:file(Filename), + Fun = fun(Node) -> + case erl_syntax:is_form(Node) of + true -> + C1 = erl_syntax:comment(2,[" This is a form."]), + Node1 = erl_syntax:add_precomments([C1],Node), + Node1; + false -> + Node + end + end, + Fs1 = erl_recomment:recomment_forms(Fs0, Comments), + Fs2 = erl_syntax_lib:map(Fun, Fs1), + io:format("File: ~s~n", [Filename]), + io:put_chars(erl_prettypr:format(Fs2, [{paper, 120}, + {ribbon, 110}])), + test_comment_scan(Files,DataDir). + + +test_epp_dodger([], _, _) -> ok; +test_epp_dodger([Filename|Files],DataDir,PrivDir) -> + io:format("Parsing ~p~n", [Filename]), + InFile = filename:join(DataDir, Filename), + Parsers = [{fun epp_dodger:parse_file/1,parse_file}, + {fun epp_dodger:quick_parse_file/1,quick_parse_file}, + {fun (File) -> + {ok,Dev} = file:open(File,[read]), + Res = epp_dodger:parse(Dev), + file:close(File), + Res + end, parse}, + {fun (File) -> + {ok,Dev} = file:open(File,[read]), + Res = epp_dodger:quick_parse(Dev), + file:close(File), + Res + end, quick_parse}], + FsForms = parse_with(Parsers, InFile), + ok = pretty_print_parse_forms(FsForms,PrivDir,Filename), + test_epp_dodger(Files,DataDir,PrivDir). + +parse_with([],_) -> []; +parse_with([{Fun,ParserType}|Funs],File) -> + {ok, Fs} = Fun(File), + [{Fs,ParserType}|parse_with(Funs,File)]. + +pretty_print_parse_forms([],_,_) -> ok; +pretty_print_parse_forms([{Fs0,Type}|FsForms],PrivDir,Filename) -> + Parser = atom_to_list(Type), + OutFile = filename:join(PrivDir, Parser ++"_" ++ Filename), + io:format("Pretty print ~p (~w) to ~p~n", [Filename,Type,OutFile]), + Comment = fun (Node,{CntCase,CntTry}=Cnt) -> + case erl_syntax:type(Node) of + case_expr -> + C1 = erl_syntax:comment(2,["Before a case expression"]), + Node1 = erl_syntax:add_precomments([C1],Node), + C2 = erl_syntax:comment(2,["After a case expression"]), + Node2 = erl_syntax:add_postcomments([C2],Node1), + {Node2,{CntCase+1,CntTry}}; + try_expr -> + C1 = erl_syntax:comment(2,["Before a try expression"]), + Node1 = erl_syntax:set_precomments(Node, + erl_syntax:get_precomments(Node) ++ [C1]), + C2 = erl_syntax:comment(2,["After a try expression"]), + Node2 = erl_syntax:set_postcomments(Node1, + erl_syntax:get_postcomments(Node1) ++ [C2]), + {Node2,{CntCase,CntTry+1}}; + _ -> + {Node,Cnt} + end + end, + Fs1 = erl_syntax:form_list(Fs0), + {Fs2,{CC,CT}} = erl_syntax_lib:mapfold(Comment,{0,0}, Fs1), + io:format("Commented on ~w cases and ~w tries~n", [CC,CT]), + PP = erl_prettypr:format(Fs2), + ok = file:write_file(OutFile,iolist_to_binary(PP)), + pretty_print_parse_forms(FsForms,PrivDir,Filename). + + +validate(_,[]) -> ok; +validate(F,[V|Vs]) -> + ok = F(V), + validate(F,Vs). + + +validate_abstract_type({Lit,Type}) -> + Tree = erl_syntax:abstract(Lit), + ok = validate_special_type(Type,Tree), + Type = erl_syntax:type(Tree), + true = erl_syntax:is_literal(Tree), + ErlT = erl_syntax:revert(Tree), + Type = erl_syntax:type(ErlT), + ok = validate_special_type(Type,ErlT), + Conc = erl_syntax:concrete(Tree), + Lit = Conc, + ok. + +validate_erl_parse_type({String,Type,Leaf}) -> + ErlT = string_to_expr(String), + ok = validate_special_type(Type,ErlT), + Type = erl_syntax:type(ErlT), + Leaf = erl_syntax:is_leaf(ErlT), + Tree = erl_syntax_lib:map(fun(Node) -> Node end, ErlT), + Type = erl_syntax:type(Tree), + _ = erl_syntax:meta(Tree), + ok = validate_special_type(Type,Tree), + RevT = erl_syntax:revert(Tree), + ok = validate_special_type(Type,RevT), + Type = erl_syntax:type(RevT), + ok. + +validate_special_type(string,Node) -> + Val = erl_syntax:string_value(Node), + true = erl_syntax:is_string(Node,Val), + _ = erl_syntax:string_literal(Node), + ok; +validate_special_type(variable,Node) -> + _ = erl_syntax:variable_literal(Node), + ok; +validate_special_type(fun_expr,Node) -> + A = erl_syntax:fun_expr_arity(Node), + true = is_integer(A), + ok; +validate_special_type(named_fun_expr,Node) -> + A = erl_syntax:named_fun_expr_arity(Node), + true = is_integer(A), + ok; +validate_special_type(tuple,Node) -> + Size = erl_syntax:tuple_size(Node), + true = is_integer(Size), + ok; +validate_special_type(float,Node) -> + Str = erl_syntax:float_literal(Node), + Val = list_to_float(Str), + Val = erl_syntax:float_value(Node), + false = erl_syntax:is_proper_list(Node), + false = erl_syntax:is_list_skeleton(Node), + ok; +validate_special_type(integer,Node) -> + Str = erl_syntax:integer_literal(Node), + Val = list_to_integer(Str), + true = erl_syntax:is_integer(Node,Val), + Val = erl_syntax:integer_value(Node), + false = erl_syntax:is_proper_list(Node), + ok; +validate_special_type(nil,Node) -> + true = erl_syntax:is_proper_list(Node), + ok; +validate_special_type(list,Node) -> + true = erl_syntax:is_list_skeleton(Node), + _ = erl_syntax:list_tail(Node), + ErrV = erl_syntax:list_head(Node), + false = erl_syntax:is_string(Node,ErrV), + Norm = erl_syntax:normalize_list(Node), + list = erl_syntax:type(Norm), + case erl_syntax:is_proper_list(Node) of + true -> + true = erl_syntax:is_list_skeleton(Node), + Compact = erl_syntax:compact_list(Node), + list = erl_syntax:type(Compact), + [_|_] = erl_syntax:list_elements(Node), + _ = erl_syntax:list_elements(Node), + N = erl_syntax:list_length(Node), + true = N > 0, + ok; + false -> + ok + end; +validate_special_type(_,_) -> + ok. + +%%% scan_and_parse + +string_to_expr(String) -> + io:format("Str: ~p~n", [String]), + {ok, Ts, _} = erl_scan:string(String++"."), + {ok,[Expr]} = erl_parse:parse_exprs(Ts), + Expr. + p_run(Test, List) -> N = erlang:system_info(schedulers), @@ -138,4 +426,3 @@ p_run_loop(Test, List, N, Refs0, Errors0) -> Refs = Refs0 -- [Ref], p_run_loop(Test, List, N, Refs, Errors) end. - diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl new file mode 100644 index 0000000000..d0d1911199 --- /dev/null +++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/m1.erl @@ -0,0 +1,22 @@ +%% +%% File: m1.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-10-24 +%% + +-module(m1). + +-export([foo/0,bar/1,baz/2]). + +foo() -> + [m2:foo(), + m2:bar()]. + +bar(A) -> + [m2:foo(A), + m2:bar(A), + m2:record_update(3,m2:record())]. + +baz(A,B) -> + [m2:foo(A,B), + m2:bar(A,B)]. diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl new file mode 100644 index 0000000000..781139317d --- /dev/null +++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/m2.erl @@ -0,0 +1,26 @@ +%% +%% File: m2.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-10-24 +%% + +-module(m2). + + +-export([foo/0,foo/1,foo/2, + bar/0,bar/1,bar/2, + record_update/2, record/0]). + +foo() -> ok. +foo(A) -> [item,A]. +foo(A,B) -> A + B. + +bar() -> true. +bar(A) -> {element,A}. +bar(A,B) -> A*B. + +-record(rec, {a,b}). + +record() -> #rec{a=3,b=0}. +record_update(V,#rec{a=V0}=R) -> + R#rec{a=V0+V,b=V0}. diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl new file mode 100644 index 0000000000..07c419b4b7 --- /dev/null +++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl @@ -0,0 +1,540 @@ +-module(syntax_tools_SUITE_test_module). + +-export([foo1/1,foo2/3,start_child/2]). + +-export([len/1,equal/2,concat/2,chr/2,rchr/2,str/2,rstr/2, + span/2,cspan/2,substr/2,substr/3,tokens/2,chars/2,chars/3]). +-export([copies/2,words/1,words/2,strip/1,strip/2,strip/3, + sub_word/2,sub_word/3,left/2,left/3,right/2,right/3, + sub_string/2,sub_string/3,centre/2,centre/3, join/2]). +-export([to_upper/1, to_lower/1]). + +-import(lists,[reverse/1,member/2]). + + +%% @type some_type() = map() +%% @type some_other_type() = {a, #{ list() => term()}} + +-type some_type() :: map(). +-type some_other_type() :: {'a', #{ list() => term()} }. + +-spec foo1(Map :: #{ 'a' => integer(), 'b' => term()}) -> term(). + +%% @doc Gets value from map. + +foo1(#{ a:= 1, b := V}) -> V. + +%% @spec foo2(some_type(), Type2 :: some_other_type(), map()) -> Value +%% @doc Gets value from map. + +-spec foo2( + Type1 :: some_type(), + Type2 :: some_other_type(), + Map :: #{ get => 'value', 'value' => binary()}) -> binary(). + +foo2(Type1, {a,#{ "a" := _}}, #{get := value, value := B}) when is_map(Type1) -> B. + +%% from supervisor 18.0 + +-type child() :: 'undefined' | pid(). +-type child_id() :: term(). +-type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}. +-type modules() :: [module()] | 'dynamic'. +-type restart() :: 'permanent' | 'transient' | 'temporary'. +-type shutdown() :: 'brutal_kill' | timeout(). +-type worker() :: 'worker' | 'supervisor'. +-type sup_ref() :: (Name :: atom()) + | {Name :: atom(), Node :: node()} + | {'global', Name :: atom()} + | {'via', Module :: module(), Name :: any()} + | pid(). +-type child_spec() :: #{name => child_id(), % mandatory + start => mfargs(), % mandatory + restart => restart(), % optional + shutdown => shutdown(), % optional + type => worker(), % optional + modules => modules()} % optional + | {Id :: child_id(), + StartFunc :: mfargs(), + Restart :: restart(), + Shutdown :: shutdown(), + Type :: worker(), + Modules :: modules()}. + +-type startchild_err() :: 'already_present' + | {'already_started', Child :: child()} | term(). +-type startchild_ret() :: {'ok', Child :: child()} + | {'ok', Child :: child(), Info :: term()} + | {'error', startchild_err()}. + + +-spec start_child(SupRef, ChildSpec) -> startchild_ret() when + SupRef :: sup_ref(), + ChildSpec :: child_spec() | (List :: [term()]). +start_child(Supervisor, ChildSpec) -> + {Supervisor,ChildSpec}. + + +%% From string.erl +%% Robert's bit + +%% len(String) +%% Return the length of a string. + +-spec len(String) -> Length when + String :: string(), + Length :: non_neg_integer(). + +len(S) -> length(S). + +%% equal(String1, String2) +%% Test if 2 strings are equal. + +-spec equal(String1, String2) -> boolean() when + String1 :: string(), + String2 :: string(). + +equal(S, S) -> true; +equal(_, _) -> false. + +%% concat(String1, String2) +%% Concatenate 2 strings. + +-spec concat(String1, String2) -> String3 when + String1 :: string(), + String2 :: string(), + String3 :: string(). + +concat(S1, S2) -> S1 ++ S2. + +%% chr(String, Char) +%% rchr(String, Char) +%% Return the first/last index of the character in a string. + +-spec chr(String, Character) -> Index when + String :: string(), + Character :: char(), + Index :: non_neg_integer(). + +chr(S, C) when is_integer(C) -> chr(S, C, 1). + +chr([C|_Cs], C, I) -> I; +chr([_|Cs], C, I) -> chr(Cs, C, I+1); +chr([], _C, _I) -> 0. + +-spec rchr(String, Character) -> Index when + String :: string(), + Character :: char(), + Index :: non_neg_integer(). + +rchr(S, C) when is_integer(C) -> rchr(S, C, 1, 0). + +rchr([C|Cs], C, I, _L) -> %Found one, now find next! + rchr(Cs, C, I+1, I); +rchr([_|Cs], C, I, L) -> + rchr(Cs, C, I+1, L); +rchr([], _C, _I, L) -> L. + +%% str(String, SubString) +%% rstr(String, SubString) +%% index(String, SubString) +%% Return the first/last index of the sub-string in a string. +%% index/2 is kept for backwards compatibility. + +-spec str(String, SubString) -> Index when + String :: string(), + SubString :: string(), + Index :: non_neg_integer(). + +str(S, Sub) when is_list(Sub) -> str(S, Sub, 1). + +str([C|S], [C|Sub], I) -> + case prefix(Sub, S) of + true -> I; + false -> str(S, [C|Sub], I+1) + end; +str([_|S], Sub, I) -> str(S, Sub, I+1); +str([], _Sub, _I) -> 0. + +-spec rstr(String, SubString) -> Index when + String :: string(), + SubString :: string(), + Index :: non_neg_integer(). + +rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0). + +rstr([C|S], [C|Sub], I, L) -> + case prefix(Sub, S) of + true -> rstr(S, [C|Sub], I+1, I); + false -> rstr(S, [C|Sub], I+1, L) + end; +rstr([_|S], Sub, I, L) -> rstr(S, Sub, I+1, L); +rstr([], _Sub, _I, L) -> L. + +prefix([C|Pre], [C|String]) -> prefix(Pre, String); +prefix([], String) when is_list(String) -> true; +prefix(Pre, String) when is_list(Pre), is_list(String) -> false. + +%% span(String, Chars) -> Length. +%% cspan(String, Chars) -> Length. + +-spec span(String, Chars) -> Length when + String :: string(), + Chars :: string(), + Length :: non_neg_integer(). + +span(S, Cs) when is_list(Cs) -> span(S, Cs, 0). + +span([C|S], Cs, I) -> + case member(C, Cs) of + true -> span(S, Cs, I+1); + false -> I + end; +span([], _Cs, I) -> I. + +-spec cspan(String, Chars) -> Length when + String :: string(), + Chars :: string(), + Length :: non_neg_integer(). + +cspan(S, Cs) when is_list(Cs) -> cspan(S, Cs, 0). + +cspan([C|S], Cs, I) -> + case member(C, Cs) of + true -> I; + false -> cspan(S, Cs, I+1) + end; +cspan([], _Cs, I) -> I. + +%% substr(String, Start) +%% substr(String, Start, Length) +%% Extract a sub-string from String. + +-spec substr(String, Start) -> SubString when + String :: string(), + SubString :: string(), + Start :: pos_integer(). + +substr(String, 1) when is_list(String) -> + String; +substr(String, S) when is_integer(S), S > 1 -> + substr2(String, S). + +-spec substr(String, Start, Length) -> SubString when + String :: string(), + SubString :: string(), + Start :: pos_integer(), + Length :: non_neg_integer(). + +substr(String, S, L) when is_integer(S), S >= 1, is_integer(L), L >= 0 -> + substr1(substr2(String, S), L). + +substr1([C|String], L) when L > 0 -> [C|substr1(String, L-1)]; +substr1(String, _L) when is_list(String) -> []. %Be nice! + +substr2(String, 1) when is_list(String) -> String; +substr2([_|String], S) -> substr2(String, S-1). + +%% tokens(String, Seperators). +%% Return a list of tokens seperated by characters in Seperators. + +-spec tokens(String, SeparatorList) -> Tokens when + String :: string(), + SeparatorList :: string(), + Tokens :: [Token :: nonempty_string()]. + +tokens(S, Seps) -> + tokens1(S, Seps, []). + +tokens1([C|S], Seps, Toks) -> + case member(C, Seps) of + true -> tokens1(S, Seps, Toks); + false -> tokens2(S, Seps, Toks, [C]) + end; +tokens1([], _Seps, Toks) -> + reverse(Toks). + +tokens2([C|S], Seps, Toks, Cs) -> + case member(C, Seps) of + true -> tokens1(S, Seps, [reverse(Cs)|Toks]); + false -> tokens2(S, Seps, Toks, [C|Cs]) + end; +tokens2([], _Seps, Toks, Cs) -> + reverse([reverse(Cs)|Toks]). + +-spec chars(Character, Number) -> String when + Character :: char(), + Number :: non_neg_integer(), + String :: string(). + +chars(C, N) -> chars(C, N, []). + +-spec chars(Character, Number, Tail) -> String when + Character :: char(), + Number :: non_neg_integer(), + Tail :: string(), + String :: string(). + +chars(C, N, Tail) when N > 0 -> + chars(C, N-1, [C|Tail]); +chars(C, 0, Tail) when is_integer(C) -> + Tail. + +%% Torbjörn's bit. + +%%% COPIES %%% + +-spec copies(String, Number) -> Copies when + String :: string(), + Copies :: string(), + Number :: non_neg_integer(). + +copies(CharList, Num) when is_list(CharList), is_integer(Num), Num >= 0 -> + copies(CharList, Num, []). + +copies(_CharList, 0, R) -> + R; +copies(CharList, Num, R) -> + copies(CharList, Num-1, CharList++R). + +%%% WORDS %%% + +-spec words(String) -> Count when + String :: string(), + Count :: pos_integer(). + +words(String) -> words(String, $\s). + +-spec words(String, Character) -> Count when + String :: string(), + Character :: char(), + Count :: pos_integer(). + +words(String, Char) when is_integer(Char) -> + w_count(strip(String, both, Char), Char, 0). + +w_count([], _, Num) -> Num+1; +w_count([H|T], H, Num) -> w_count(strip(T, left, H), H, Num+1); +w_count([_H|T], Char, Num) -> w_count(T, Char, Num). + +%%% SUB_WORDS %%% + +-spec sub_word(String, Number) -> Word when + String :: string(), + Word :: string(), + Number :: integer(). + +sub_word(String, Index) -> sub_word(String, Index, $\s). + +-spec sub_word(String, Number, Character) -> Word when + String :: string(), + Word :: string(), + Number :: integer(), + Character :: char(). + +sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) -> + case words(String, Char) of + Num when Num < Index -> + []; + _Num -> + s_word(strip(String, left, Char), Index, Char, 1, []) + end. + +s_word([], _, _, _,Res) -> reverse(Res); +s_word([Char|_],Index,Char,Index,Res) -> reverse(Res); +s_word([H|T],Index,Char,Index,Res) -> s_word(T,Index,Char,Index,[H|Res]); +s_word([Char|T],Stop,Char,Index,Res) when Index < Stop -> + s_word(strip(T,left,Char),Stop,Char,Index+1,Res); +s_word([_|T],Stop,Char,Index,Res) when Index < Stop -> + s_word(T,Stop,Char,Index,Res). + +%%% STRIP %%% + +-spec strip(string()) -> string(). + +strip(String) -> strip(String, both). + +-spec strip(String, Direction) -> Stripped when + String :: string(), + Stripped :: string(), + Direction :: left | right | both. + +strip(String, left) -> strip_left(String, $\s); +strip(String, right) -> strip_right(String, $\s); +strip(String, both) -> + strip_right(strip_left(String, $\s), $\s). + +-spec strip(String, Direction, Character) -> Stripped when + String :: string(), + Stripped :: string(), + Direction :: left | right | both, + Character :: char(). + +strip(String, right, Char) -> strip_right(String, Char); +strip(String, left, Char) -> strip_left(String, Char); +strip(String, both, Char) -> + strip_right(strip_left(String, Char), Char). + +strip_left([Sc|S], Sc) -> + strip_left(S, Sc); +strip_left([_|_]=S, Sc) when is_integer(Sc) -> S; +strip_left([], Sc) when is_integer(Sc) -> []. + +strip_right([Sc|S], Sc) -> + case strip_right(S, Sc) of + [] -> []; + T -> [Sc|T] + end; +strip_right([C|S], Sc) -> + [C|strip_right(S, Sc)]; +strip_right([], Sc) when is_integer(Sc) -> + []. + +%%% LEFT %%% + +-spec left(String, Number) -> Left when + String :: string(), + Left :: string(), + Number :: non_neg_integer(). + +left(String, Len) when is_integer(Len) -> left(String, Len, $\s). + +-spec left(String, Number, Character) -> Left when + String :: string(), + Left :: string(), + Number :: non_neg_integer(), + Character :: char(). + +left(String, Len, Char) when is_integer(Char) -> + Slen = length(String), + if + Slen > Len -> substr(String, 1, Len); + Slen < Len -> l_pad(String, Len-Slen, Char); + Slen =:= Len -> String + end. + +l_pad(String, Num, Char) -> String ++ chars(Char, Num). + +%%% RIGHT %%% + +-spec right(String, Number) -> Right when + String :: string(), + Right :: string(), + Number :: non_neg_integer(). + +right(String, Len) when is_integer(Len) -> right(String, Len, $\s). + +-spec right(String, Number, Character) -> Right when + String :: string(), + Right :: string(), + Number :: non_neg_integer(), + Character :: char(). + +right(String, Len, Char) when is_integer(Char) -> + Slen = length(String), + if + Slen > Len -> substr(String, Slen-Len+1); + Slen < Len -> r_pad(String, Len-Slen, Char); + Slen =:= Len -> String + end. + +r_pad(String, Num, Char) -> chars(Char, Num, String). + +%%% CENTRE %%% + +-spec centre(String, Number) -> Centered when + String :: string(), + Centered :: string(), + Number :: non_neg_integer(). + +centre(String, Len) when is_integer(Len) -> centre(String, Len, $\s). + +-spec centre(String, Number, Character) -> Centered when + String :: string(), + Centered :: string(), + Number :: non_neg_integer(), + Character :: char(). + +centre(String, 0, Char) when is_list(String), is_integer(Char) -> + []; % Strange cases to centre string +centre(String, Len, Char) when is_integer(Char) -> + Slen = length(String), + if + Slen > Len -> substr(String, (Slen-Len) div 2 + 1, Len); + Slen < Len -> + N = (Len-Slen) div 2, + r_pad(l_pad(String, Len-(Slen+N), Char), N, Char); + Slen =:= Len -> String + end. + +%%% SUB_STRING %%% + +-spec sub_string(String, Start) -> SubString when + String :: string(), + SubString :: string(), + Start :: pos_integer(). + +sub_string(String, Start) -> substr(String, Start). + +-spec sub_string(String, Start, Stop) -> SubString when + String :: string(), + SubString :: string(), + Start :: pos_integer(), + Stop :: pos_integer(). + +sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1). + +%% ISO/IEC 8859-1 (latin1) letters are converted, others are ignored +%% + +to_lower_char(C) when is_integer(C), $A =< C, C =< $Z -> + C + 32; +to_lower_char(C) when is_integer(C), 16#C0 =< C, C =< 16#D6 -> + C + 32; +to_lower_char(C) when is_integer(C), 16#D8 =< C, C =< 16#DE -> + C + 32; +to_lower_char(C) -> + C. + +to_upper_char(C) when is_integer(C), $a =< C, C =< $z -> + C - 32; +to_upper_char(C) when is_integer(C), 16#E0 =< C, C =< 16#F6 -> + C - 32; +to_upper_char(C) when is_integer(C), 16#F8 =< C, C =< 16#FE -> + C - 32; +to_upper_char(C) -> + C. + +-spec to_lower(String) -> Result when + String :: io_lib:latin1_string(), + Result :: io_lib:latin1_string() + ; (Char) -> CharResult when + Char :: char(), + CharResult :: char(). + +to_lower(S) when is_list(S) -> + [to_lower_char(C) || C <- S]; +to_lower(C) when is_integer(C) -> + to_lower_char(C). + +-spec to_upper(String) -> Result when + String :: io_lib:latin1_string(), + Result :: io_lib:latin1_string() + ; (Char) -> CharResult when + Char :: char(), + CharResult :: char(). + +to_upper(S) when is_list(S) -> + [to_upper_char(C) || C <- S]; +to_upper(C) when is_integer(C) -> + to_upper_char(C). + +-spec join(StringList, Separator) -> String when + StringList :: [string()], + Separator :: string(), + String :: string(). + +join([], Sep) when is_list(Sep) -> + []; +join([H|T], Sep) -> + H ++ lists:append([Sep ++ X || X <- T]). diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl new file mode 100644 index 0000000000..dd3f88d7a8 --- /dev/null +++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_test.erl @@ -0,0 +1,115 @@ +%% +%% File: syntax_tools_test.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-10-23 +%% + +-module(syntax_tools_test). + +-export([foo1/0,foo2/2,foo3/0,foo4/3,foo5/1]). + +-include_lib("kernel/include/file.hrl"). +-record(state, { a, b, c, d}). +-attribute([foo/0]). + +-define(attrib, some_attrib). + +-?attrib([foo2/2]). + +-define(macro_simple1, ok). +-define(MACRO_SIMPLE2, (other)). +-define(macro_simple3, ?MODULE). +-define(macro_simple4, [?macro_simple3,?MODULE,?MACRO_SIMPLE2]). +-define(macro_simple5, (process_info)). +-define(macro_string, "hello world"). +-define(macro_argument1(X), (X + 3)). +-define(macro_argument2(X,Y), (X + 3 * Y)). +-define(macro_block(X), begin X end). +-define(macro_if(X1,X2), if X1 -> X2; true -> none end). + + +-ifdef(macro_def1). +-define(macro_cond1, yep). +-else. +-define(macro_cond1, nope). +-endif. +-ifndef(macro_def2). +-define(macro_cond2, nope). +-else. +-define(macro_cond2, yep). +-endif. +-undef(macro_def1). +-undef(macro_def2). + +%% basic test +foo1() -> + ok. + +%% macro test +foo2(A,B) -> + % string combining ? + [?macro_string, ?macro_string + ?macro_string, + "hello world " + "more hello", + [?macro_simple1, + ?MACRO_SIMPLE2, + ?macro_simple3, + ?macro_simple4, + ?macro_simple5, + ?macro_string, + ?macro_cond1, + ?macro_cond2, + ?macro_block(A), + ?macro_if(A,B), + ?macro_argument1(A), + ?macro_argument1(begin A end), + ?macro_block(<<"hello">>), + ?macro_block("hello"), + ?macro_block([$h,$e,$l,$l,$0]), + ?macro_argument1(id(<<"hello">>)), + ?macro_argument1(if A -> B; true -> 3.14 end), + ?macro_argument1(case A of ok -> B; C -> C end), + ?macro_argument1(receive M -> M after 100 -> 3 end), + ?macro_argument1(try foo5(A) catch C:?macro_simple5 -> {C,B} end), + ?macro_argument2(A,B)], + A,B,ok]. + +id(I) -> I. +%% basic terms + +foo3() -> + [atom, + 'some other atom', + {tuple,1,2,3}, + 1,2,3,3333, + 3,3333,2,1, + [$a,$b,$c], + "hello world", + <<"hello world">>, + <<1,2,3,4,5:6>>, + 3.1415, + 1.03e33]. + +%% application and records + +foo4(A,B,#state{c = C}=S) -> + Ls = foo3(), + S1 = #state{ a = 1, b = 2 }, + [foo2(A,Ls),B,C, + B(3,C), + erlang:process_info(self()), + erlang:?macro_simple5(self()), + A:?MACRO_SIMPLE2(), + A:?macro_simple1(), + A:process_info(self()), + A:B(3), + S#state{ a = 2, b = B, d = S1 }]. + +foo5(A) -> + try foo2(A,A) of + R -> R + catch + error:?macro_simple5 -> + nope + end. diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 6a80734f83..673362d01d 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 1.6.16 +SYNTAX_TOOLS_VSN = 1.6.17 diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml index a801a87725..68dc1fec88 100644 --- a/lib/test_server/doc/src/notes.xml +++ b/lib/test_server/doc/src/notes.xml @@ -32,6 +32,47 @@ <file>notes.xml</file> </header> +<section><title>Test_Server 3.7.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The source code to html code generator in Test Server + (and Common Test) would fail to generate anchors in the + html code for functions with non-expandable macros, + resulting in bad html links to such functions. This + correction lets the code generator ignore macros that + can't be expanded (i.e. not pre-process them), so that + correct anchors will always be produced.</p> + <p> + Own Id: OTP-11766 Aux Id: seq12556 </p> + </item> + <item> + <p> + Make sure to install .hrl files when needed</p> + <p> + Own Id: OTP-12197</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + </list> + </section> + +</section> + <section><title>Test_Server 3.7.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/test_server/src/config.guess b/lib/test_server/src/config.guess deleted file mode 100755 index f475ceb413..0000000000 --- a/lib/test_server/src/config.guess +++ /dev/null @@ -1,1534 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to [email protected]. - - -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 1992-2013 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - 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 ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <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:*:[4567]) - 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 -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <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:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-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 ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </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 i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <[email protected]> - 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*) - # From [email protected]. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From [email protected]. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From [email protected]. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - 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 ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -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/test_server/src/config.sub b/lib/test_server/src/config.sub deleted file mode 100755 index bb6edbdb47..0000000000 --- a/lib/test_server/src/config.sub +++ /dev/null @@ -1,1789 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to [email protected]. -# -# 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. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# 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 1992-2013 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-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - 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 | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -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 \ - | aarch64 | aarch64_be \ - | 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[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-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-* \ - | aarch64-* | aarch64_be-* \ - | 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-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | 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-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - 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-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - 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 - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - 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 | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - 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 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - 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 - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -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* | -es*) - # 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 - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -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 - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - 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 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or1k-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: - diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in index cd723bcd4d..8398825d95 100644 --- a/lib/test_server/src/configure.in +++ b/lib/test_server/src/configure.in @@ -357,7 +357,23 @@ AC_CHECK_FUNCS(usleep) # First check if the library is available, then if we can choose between # two versions of gethostbyname AC_HAVE_LIBRARY(resolv) -AC_CHECK_LIB(resolv, res_gethostbyname,[DEFS="$DEFS -DHAVE_RES_GETHOSTBYNAME=1"]) +AC_CHECK_LIB(resolv, res_gethostbyname,[AC_DEFINE(HAVE_RES_GETHOSTBYNAME,1)]) + +#-------------------------------------------------------------------- +# Check for isfinite +#-------------------------------------------------------------------- + +AC_MSG_CHECKING([for isfinite]) +AC_TRY_LINK([#include <math.h>], + [isfinite(0);], have_isfinite=yes, have_isfinite=no) + +if test $have_isfinite = yes; then + AC_DEFINE(HAVE_ISFINITE,1) + AC_MSG_RESULT(yes) +else + AC_DEFINE(HAVE_FINITE,1) + AC_MSG_RESULT(no) +fi #-------------------------------------------------------------------- # Emulator compatible flags (for drivers) diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl index 952036502a..7cfaa2c325 100644 --- a/lib/test_server/src/erl2html2.erl +++ b/lib/test_server/src/erl2html2.erl @@ -22,11 +22,11 @@ %%%------------------------------------------------------------------ -module(erl2html2). --export([convert/2, convert/3]). +-export([convert/3, convert/4]). -convert([], _Dest) -> % Fake clause. +convert([], _Dest, _InclPath) -> % Fake clause. ok; -convert(File, Dest) -> +convert(File, Dest, InclPath) -> %% The generated code uses the BGCOLOR attribute in the %% BODY tag, which wasn't valid until HTML 3.2. Also, %% good HTML should either override all colour attributes @@ -48,12 +48,12 @@ convert(File, Dest) -> "</head>\n\n" "<body bgcolor=\"white\" text=\"black\"" " link=\"blue\" vlink=\"purple\" alink=\"red\">\n"], - convert(File, Dest, Header). + convert(File, Dest, InclPath, Header). -convert(File, Dest, Header) -> +convert(File, Dest, InclPath, Header) -> %% statistics(runtime), - case parse_file(File) of + case parse_file(File, InclPath) of {ok,Functions} -> %% {_, Time1} = statistics(runtime), %% io:format("Parsed file in ~.2f Seconds.~n",[Time1/1000]), @@ -88,34 +88,75 @@ convert(File, Dest, Header) -> %%% %%% All function clauses are also marked in order to allow %%% possibly_enhance/2 to write these in bold. -parse_file(File) -> - case epp:open(File, [], []) of +%%% +%%% Use expanded preprocessor directives if possible (epp). Only if +%%% this fails, fall back on using non-expanded code (epp_dodger). + +parse_file(File, InclPath) -> + case epp:open(File, InclPath, []) of {ok,Epp} -> - Forms = parse_file(Epp,File,false), - epp:close(Epp), - {ok,Forms}; - {error,E} -> - {error,E} + try parse_preprocessed_file(Epp,File,false) of + Forms -> + epp:close(Epp), + {ok,Forms} + catch + _:{error,_Reason,true} -> + parse_non_preprocessed_file(File); + _:{error,_Reason,false} -> + {ok,[]} + end; + Error = {error,_} -> + Error end. - -parse_file(Epp,File,InCorrectFile) -> +parse_preprocessed_file(Epp,File,InCorrectFile) -> case epp:parse_erl_form(Epp) of {ok,Form} -> case Form of {attribute,_,file,{File,_}} -> - parse_file(Epp,File,true); + parse_preprocessed_file(Epp,File,true); {attribute,_,file,{_OtherFile,_}} -> - parse_file(Epp,File,false); + parse_preprocessed_file(Epp,File,false); {function,L,F,A,[_|C]} when InCorrectFile -> Clauses = [{clause,CL} || {clause,CL,_,_,_} <- C], [{atom_to_list(F),A,L} | Clauses] ++ - parse_file(Epp,File,true); + parse_preprocessed_file(Epp,File,true); + _ -> + parse_preprocessed_file(Epp,File,InCorrectFile) + end; + {error,Reason={_L,epp,{undefined,_Macro,none}}} -> + throw({error,Reason,InCorrectFile}); + {error,_Reason} -> + parse_preprocessed_file(Epp,File,InCorrectFile); + {eof,_Location} -> + [] + end. + +parse_non_preprocessed_file(File) -> + case file:open(File, []) of + {ok,Epp} -> + Forms = parse_non_preprocessed_file(Epp, File, 1), + file:close(Epp), + {ok,Forms}; + Error = {error,_E} -> + Error + end. + +parse_non_preprocessed_file(Epp, File, Location) -> + case epp_dodger:parse_form(Epp, Location) of + {ok,Tree,Location1} -> + try erl_syntax:revert(Tree) of + {function,L,F,A,[_|C]} -> + Clauses = [{clause,CL} || {clause,CL,_,_,_} <- C], + [{atom_to_list(F),A,L} | Clauses] ++ + parse_non_preprocessed_file(Epp, File, Location1); _ -> - parse_file(Epp,File,InCorrectFile) + parse_non_preprocessed_file(Epp, File, Location1) + catch + _:_ -> parse_non_preprocessed_file(Epp, File, Location1) end; - {error,_E} -> - parse_file(Epp,File,InCorrectFile); + {error,_E,Location1} -> + parse_non_preprocessed_file(Epp, File, Location1); {eof,_Location} -> [] end. diff --git a/lib/test_server/src/install-sh b/lib/test_server/src/install-sh deleted file mode 100755 index a5897de6ea..0000000000 --- a/lib/test_server/src/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/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src index 5672baa6ef..173f7075db 100644 --- a/lib/test_server/src/test_server.app.src +++ b/lib/test_server/src/test_server.app.src @@ -34,5 +34,5 @@ {env, []}, {runtime_dependencies, ["tools-2.6.14","stdlib-2.0","runtime_tools-1.8.14", "observer-2.0","kernel-3.0","inets-5.10", - "erts-6.0"]}]}. + "syntax_tools-1.6.16","erts-6.0"]}]}. diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 9192a76a17..f1592d9442 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -130,7 +130,8 @@ cover_compile(CoverInfo=#cover{app=App,excl=all,incl=Include,cross=Cross}) -> io:fwrite("done\n\n",[]), {ok,CoverInfo#cover{mods=Include}} end; -cover_compile(CoverInfo=#cover{app=App,excl=Exclude,incl=Include,cross=Cross}) -> +cover_compile(CoverInfo=#cover{app=App,excl=Exclude, + incl=Include,cross=Cross}) -> CrossMods = lists:flatmap(fun({_,M}) -> M end,Cross), case code:lib_dir(App) of {error,bad_name} -> @@ -779,7 +780,9 @@ do_call_end_conf(Starter,Mod,Func,Data,Conf,TVal) -> EndConfApply = fun() -> timetrap(TVal), - case catch apply(Mod,end_per_testcase,[Func,Conf]) of + case catch apply(Mod, + end_per_testcase, + [Func,Conf]) of {'EXIT',Why} -> timer:sleep(1), group_leader() ! {printout,12, @@ -817,7 +820,9 @@ spawn_fw_call(Mod,{init_per_testcase,Func},CurrConf,Pid, Skip = {skip,{failed,{Mod,init_per_testcase,Why}}}, %% if init_per_testcase fails, the test case %% should be skipped - case catch do_end_tc_call(Mod,Func, {Pid,Skip,[CurrConf]}, Why) of + case catch do_end_tc_call(Mod,Func, + {Pid,Skip,[CurrConf]}, + Why) of {'EXIT',FwEndTCErr} -> exit({fw_notify_done,end_tc,FwEndTCErr}); _ -> @@ -984,12 +989,15 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit, NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf]}, {fail,Reason}), {{0,NewResult},Where,[]}; - Skip = {skip,_Reason} -> - NewResult = do_end_tc_call(Mod,Func, {Skip,Args0}, Skip), + Skip = {SkipType,_Reason} when SkipType == skip; + SkipType == skipped -> + NewResult = do_end_tc_call(Mod,Func, + {Skip,Args0}, Skip), {{0,NewResult},Where,[]}; AutoSkip = {auto_skip,_Reason} -> %% special case where a conf case "pretends" to be skipped - NewResult = do_end_tc_call(Mod,Func, {AutoSkip,Args0}, AutoSkip), + NewResult = + do_end_tc_call(Mod,Func, {AutoSkip,Args0}, AutoSkip), {{0,NewResult},Where,[]} end, exit({Ref,Time,Value,Loc,Opts}). @@ -1000,10 +1008,12 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> set_tc_state(init_per_testcase, hd(Args)), ensure_timetrap(Args), case init_per_testcase(Mod, Func, Args) of - Skip = {skip,Reason} -> + Skip = {SkipType,Reason} when SkipType == skip; + SkipType == skipped -> Line = get_loc(), Conf = [{tc_status,{skipped,Reason}}|hd(Args)], - NewRes = do_end_tc_call(Mod,Func, {Skip,[Conf]}, Skip), + NewRes = do_end_tc_call(Mod,Func, + {Skip,[Conf]}, Skip), {{0,NewRes},Line,[]}; {skip_and_save,Reason,SaveCfg} -> Line = get_loc(), @@ -1021,11 +1031,12 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {{0,NewRes},[{Mod,Func}],[]}; {ok,NewConf} -> %% call user callback function if defined - NewConf1 = user_callback(TCCallback, Mod, Func, init, NewConf), + NewConf1 = + user_callback(TCCallback, Mod, Func, init, NewConf), %% save current state in controller loop set_tc_state(tc, NewConf1), %% execute the test case - {{T,Return},Loc} = {ts_tc(Mod, Func, [NewConf1]),get_loc()}, + {{T,Return},Loc} = {ts_tc(Mod,Func,[NewConf1]), get_loc()}, {EndConf,TSReturn,FWReturn} = case Return of {E,TCError} when E=='EXIT' ; E==failed -> @@ -1041,30 +1052,39 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {[{tc_status,{skipped,Why}}, {save_config,SaveCfg}|NewConf1], Skip,Skip}; - {skip,Why} -> - {[{tc_status,{skipped,Why}}|NewConf1],Return,Return}; + {SkipType,Why} when SkipType == skip; + SkipType == skipped -> + {[{tc_status,{skipped,Why}}|NewConf1],Return, + Return}; _ -> {[{tc_status,ok}|NewConf1],Return,ok} end, %% call user callback function if defined - EndConf1 = user_callback(TCCallback, Mod, Func, 'end', EndConf), + EndConf1 = + user_callback(TCCallback, Mod, Func, 'end', EndConf), %% update current state in controller loop {FWReturn1,TSReturn1,EndConf2} = case end_per_testcase(Mod, Func, EndConf1) of SaveCfg1={save_config,_} -> - {FWReturn,TSReturn,[SaveCfg1|lists:keydelete(save_config,1, - EndConf1)]}; + {FWReturn,TSReturn, + [SaveCfg1|lists:keydelete(save_config,1, + EndConf1)]}; {fail,ReasonToFail} -> %% user has failed the testcase - fw_error_notify(Mod, Func, EndConf1, ReasonToFail), - {{error,ReasonToFail},{failed,ReasonToFail},EndConf1}; - {failed,{_,end_per_testcase,_}} = Failure when FWReturn == ok -> + fw_error_notify(Mod, Func, EndConf1, + ReasonToFail), + {{error,ReasonToFail}, + {failed,ReasonToFail}, + EndConf1}; + {failed,{_,end_per_testcase,_}} = Failure when + FWReturn == ok -> %% unexpected termination in end_per_testcase %% report this as the result to the framework {Failure,TSReturn,EndConf1}; _ -> - %% test case result should be reported to framework - %% no matter the status of end_per_testcase + %% test case result should be reported to + %% framework no matter the status of + %% end_per_testcase {FWReturn,TSReturn,EndConf1} end, %% clear current state in controller loop @@ -1131,7 +1151,8 @@ process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) -> ReturnTags = [skip,skip_and_save,save_config,comment,return_group_result], %% check if all elements in the list are valid end conf return value tuples case lists:all(fun(Val) when is_tuple(Val) -> - lists:any(fun(T) -> T == element(1, Val) end, ReturnTags); + lists:any(fun(T) -> T == element(1, Val) end, + ReturnTags); (ok) -> true; (_) -> @@ -1165,14 +1186,19 @@ process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts) NewReturn -> {NewReturn,SaveOpts} end; -process_return_val1([SaveCfg={save_config,_}|Opts], M,F,[Args], Loc, Final, SaveOpts) -> +process_return_val1([SaveCfg={save_config,_}|Opts], M,F,[Args], + Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,[[SaveCfg|Args]], Loc, Final, SaveOpts); -process_return_val1([{skip_and_save,Why,SaveCfg}|Opts], M,F,[Args], Loc, _, SaveOpts) -> - process_return_val1(Opts, M,F,[[{save_config,SaveCfg}|Args]], Loc, {skip,Why}, SaveOpts); -process_return_val1([GR={return_group_result,_}|Opts], M,F,A, Loc, Final, SaveOpts) -> +process_return_val1([{skip_and_save,Why,SaveCfg}|Opts], M,F,[Args], + Loc, _, SaveOpts) -> + process_return_val1(Opts, M,F,[[{save_config,SaveCfg}|Args]], + Loc, {skip,Why}, SaveOpts); +process_return_val1([GR={return_group_result,_}|Opts], M,F,A, + Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,A, Loc, Final, [GR|SaveOpts]); -process_return_val1([RetVal={Tag,_}|Opts], M,F,A, Loc, _, SaveOpts) when Tag==skip; - Tag==comment -> +process_return_val1([RetVal={Tag,_}|Opts], M,F,A, + Loc, _, SaveOpts) when Tag==skip; + Tag==comment -> process_return_val1(Opts, M,F,A, Loc, RetVal, SaveOpts); process_return_val1([_|Opts], M,F,A, Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,A, Loc, Final, SaveOpts); @@ -1186,7 +1212,8 @@ process_return_val1([], M,F,A, _Loc, Final, SaveOpts) -> user_callback(undefined, _, _, _, Args) -> Args; -user_callback({CBMod,CBFunc}, Mod, Func, InitOrEnd, [Args]) when is_list(Args) -> +user_callback({CBMod,CBFunc}, Mod, Func, InitOrEnd, + [Args]) when is_list(Args) -> case catch apply(CBMod, CBFunc, [InitOrEnd,Mod,Func,Args]) of Args1 when is_list(Args1) -> [Args1]; @@ -1778,7 +1805,8 @@ timetrap(Timeout0, TimeToReport0, TCPid, MultAndScale = {Multiplier,Scale}) -> put(test_server_timetraps,[{Handle,TCPid,{TimeToReport,Scale}}]); List -> List1 = lists:delete({infinity,TCPid,{infinity,false}}, List), - put(test_server_timetraps,[{Handle,TCPid,{TimeToReport,Scale}}|List1]) + put(test_server_timetraps,[{Handle,TCPid, + {TimeToReport,Scale}}|List1]) end, Handle. @@ -1837,7 +1865,9 @@ time_ms(Ms, _, _) when is_integer(Ms) -> Ms; time_ms(infinity, _, _) -> infinity; time_ms(Fun, TCPid, MultAndScale) when is_function(Fun) -> time_ms_apply(Fun, TCPid, MultAndScale); -time_ms({M,F,A}=MFA, TCPid, MultAndScale) when is_atom(M), is_atom(F), is_list(A) -> +time_ms({M,F,A}=MFA, TCPid, MultAndScale) when is_atom(M), + is_atom(F), + is_list(A) -> time_ms_apply(MFA, TCPid, MultAndScale); time_ms(Other, _, _) -> exit({invalid_time_format,Other}). diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index af8921fe75..488f38d05d 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -1927,15 +1927,20 @@ html_possibly_convert(Src, SrcInfo, Dest) -> {ok,DestInfo} when DestInfo#file_info.mtime >= SrcInfo#file_info.mtime -> ok; % dest file up to date _ -> + InclPath = case application:get_env(test_server, include) of + {ok,Incls} -> Incls; + _ -> [] + end, + OutDir = get(test_server_log_dir_base), case test_server_sup:framework_call(get_html_wrapper, ["Module "++Src,false, OutDir,undefined, encoding(Src)], "") of Empty when (Empty == "") ; (element(2,Empty) == "") -> - erl2html2:convert(Src, Dest); + erl2html2:convert(Src, Dest, InclPath); {_,Header,_} -> - erl2html2:convert(Src, Dest, Header) + erl2html2:convert(Src, Dest, InclPath, Header) end end. diff --git a/lib/test_server/src/ts_make.erl b/lib/test_server/src/ts_make.erl index 8727f7ebfe..9cb77ecb12 100644 --- a/lib/test_server/src/ts_make.erl +++ b/lib/test_server/src/ts_make.erl @@ -67,7 +67,17 @@ get_port_data(Port, Last0, Complete0) -> end. update_last([C|Rest], Line, true) -> - io:put_chars(list_to_binary(Line)), %% Utf-8 list to utf-8 binary + try + %% Utf-8 list to utf-8 binary + %% (e.g. we assume utf-8 bytes from port) + io:put_chars(list_to_binary(Line)) + catch + error:badarg -> + %% io:put_chars/1 badarged + %% this likely means we had unicode code points + %% in our bytes buffer (e.g warning from gcc with åäö) + io:put_chars(unicode:characters_to_binary(Line)) + end, io:nl(), update_last([C|Rest], [], false); update_last([$\r|Rest], Result, Complete) -> diff --git a/lib/test_server/test/erl2html2_SUITE.erl b/lib/test_server/test/erl2html2_SUITE.erl index 37c2b74d8e..908985c879 100644 --- a/lib/test_server/test/erl2html2_SUITE.erl +++ b/lib/test_server/test/erl2html2_SUITE.erl @@ -161,7 +161,7 @@ convert_module(Mod,Config) -> Src = filename:join(DataDir,Mod++".erl"), Dst = filename:join(PrivDir,Mod++".erl.html"), io:format("<a href=\"~s\">~s</a>\n",[Src,filename:basename(Src)]), - ok = erl2html2:convert(Src, Dst, "<html><body>"), + ok = erl2html2:convert(Src, Dst, [], "<html><body>"), io:format("<a href=\"~s\">~s</a>\n",[Dst,filename:basename(Dst)]), {Src,Dst}. diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk index 9e1ac8fd12..18d7583c35 100644 --- a/lib/test_server/vsn.mk +++ b/lib/test_server/vsn.mk @@ -1 +1 @@ -TEST_SERVER_VSN = 3.7.1 +TEST_SERVER_VSN = 3.7.2 diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml index 3ebacf5546..73fd563fbd 100644 --- a/lib/tools/doc/src/eprof.xml +++ b/lib/tools/doc/src/eprof.xml @@ -35,7 +35,7 @@ used. The profiling is done using the Erlang trace BIFs. Tracing of local function calls for a specified set of processes is enabled when profiling is begun, and disabled when profiling is stopped.</p> - <p>When using Eprof expect a slowdown in program execution.</p> + <p>When using Eprof, expect a slowdown in program execution.</p> </description> <funcs> <func> diff --git a/lib/tools/doc/src/fprof.xml b/lib/tools/doc/src/fprof.xml index ef8b82c9fa..f83c049fcd 100644 --- a/lib/tools/doc/src/fprof.xml +++ b/lib/tools/doc/src/fprof.xml @@ -789,7 +789,7 @@ create_file_slow(FD, M, N) -> function was first unsuspended and then garbage collected. Otherwise the printout would show <c>garbage_collect</c> being called from <c>suspend</c> but not - not which function that might have caused the garbage + which function that might have caused the garbage collection. </p> <p>Let us now get back to the test code:</p> diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index faee5efd43..6f9563bb68 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,41 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.7.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a typo in erlang-mode comment.</p> + <p> + Own Id: OTP-12214</p> + </item> + <item> + <p> + Add a skeleton for -spec in Erlang mode for Emacs</p> + <p> + Own Id: OTP-12283</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Cover no longer crashes when compiling <c>receive</c> and + the like with just an <c>after</c> clause. Thanks to + José Valim for providing a fix.</p> + <p> + Own Id: OTP-12328</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.7</title> <section><title>Improvements and New Features</title> diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el index b37d08e767..78929ac510 100644 --- a/lib/tools/emacs/erlang-skels.el +++ b/lib/tools/emacs/erlang-skels.el @@ -31,6 +31,7 @@ ("Module" "module" erlang-skel-module) ("Author" "author" erlang-skel-author) ("Function" "function" erlang-skel-function) + ("Spec" "spec" erlang-skel-spec) () ("Small Header" "small-header" erlang-skel-small-header erlang-skel-header) @@ -54,6 +55,8 @@ erlang-skel-gen-event erlang-skel-header) ("gen_fsm" "gen-fsm" erlang-skel-gen-fsm erlang-skel-header) + ("wx_object" "wx-object" + erlang-skel-wx-object erlang-skel-header) ("Library module" "gen-lib" erlang-skel-lib erlang-skel-header) ("Corba callback" "gen-corba-cb" @@ -147,6 +150,10 @@ Please see the function `tempo-define-template'.") "*The template of a function skeleton. Please see the function `tempo-define-template'.") +(defvar erlang-skel-spec + '("-spec " (erlang-skel-get-function-name) "(" (erlang-skel-get-function-args) ") -> undefined.") + "*The template of a -spec for the function following point. +Please see the function `tempo-define-template'.") ;; Attribute templates @@ -851,6 +858,137 @@ Please see the function `tempo-define-template'.") "*The template of a gen_fsm. Please see the function `tempo-define-template'.") +(defvar erlang-skel-wx-object + '((erlang-skel-include erlang-skel-large-header) + "-behaviour(wx_object)." n n + + "-include_lib(\"wx/include/wx.hrl\")." n n + + "%% API" n + "-export([start_link/0])." n n + + "%% wx_object callbacks" n + "-export([init/1, handle_call/3, handle_cast/2, " + "handle_info/2," n> + "handle_event/2, terminate/2, code_change/3])." n n + + "-record(state, {})." n n + + (erlang-skel-double-separator-start 3) + "%%% API" n + (erlang-skel-double-separator-end 3) n + (erlang-skel-separator-start 2) + "%% @doc" n + "%% Starts the server" n + "%%" n + "%% @spec start_link() -> wxWindow()" n + (erlang-skel-separator-end 2) + "start_link() ->" n> + "wx_object:start_link(?MODULE, [], [])." n + n + (erlang-skel-double-separator-start 3) + "%%% wx_object callbacks" n + (erlang-skel-double-separator-end 3) + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Initializes the server" n + "%%" n + "%% @spec init(Args) -> {wxWindow(), State} |" n + "%% {wxWindow(), State, Timeout} |" n + "%% ignore |" n + "%% {stop, Reason}" n + (erlang-skel-separator-end 2) + "init([]) ->" n> + "wx:new()," n> + "Frame = wxFrame:new()," n> + "{Frame, #state{}}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Handling events" n + "%%" n + "%% @spec handle_event(wx{}, State) ->" n + "%% {noreply, State} |" n + "%% {noreply, State, Timeout} |" n + "%% {stop, Reason, State}" n + (erlang-skel-separator-end 2) + "handle_event(#wx{}, State) ->" n> + "{noreply, State}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Handling call messages" n + "%%" n + "%% @spec handle_call(Request, From, State) ->" n + "%% {reply, Reply, State} |" n + "%% {reply, Reply, State, Timeout} |" n + "%% {noreply, State} |" n + "%% {noreply, State, Timeout} |" n + "%% {stop, Reason, Reply, State} |" n + "%% {stop, Reason, State}" n + (erlang-skel-separator-end 2) + "handle_call(_Request, _From, State) ->" n> + "Reply = ok," n> + "{reply, Reply, State}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Handling cast messages" n + "%%" n + "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n + "%% {noreply, State, Timeout} |" n + "%% {stop, Reason, State}" n + (erlang-skel-separator-end 2) + "handle_cast(_Msg, State) ->" n> + "{noreply, State}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Handling all non call/cast messages" n + "%%" n + "%% @spec handle_info(Info, State) -> {noreply, State} |" n + "%% {noreply, State, Timeout} |" n + "%% {stop, Reason, State}" n + (erlang-skel-separator-end 2) + "handle_info(_Info, State) ->" n> + "{noreply, State}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% This function is called by a wx_object when it is about to" n + "%% terminate. It should be the opposite of Module:init/1 and do any" n + "%% necessary cleaning up. When it returns, the wx_object terminates" n + "%% with Reason. The return value is ignored." n + "%%" n + "%% @spec terminate(Reason, State) -> void()" n + (erlang-skel-separator-end 2) + "terminate(_Reason, _State) ->" n> + "ok." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Convert process state when code is changed" n + "%%" n + "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n + (erlang-skel-separator-end 2) + "code_change(_OldVsn, State, _Extra) ->" n> + "{ok, State}." n + n + (erlang-skel-double-separator-start 3) + "%%% Internal functions" n + (erlang-skel-double-separator-end 3) + ) + "*The template of a generic server. +Please see the function `tempo-define-template'.") + (defvar erlang-skel-lib '((erlang-skel-include erlang-skel-large-header) @@ -1546,6 +1684,16 @@ The first character of DD is space if the value is less than 10." (substring date 4 7) (substring date -4)))) +(defun erlang-skel-get-function-name () + (save-excursion + (erlang-beginning-of-function -1) + (erlang-get-function-name))) + +(defun erlang-skel-get-function-args () + (save-excursion + (erlang-beginning-of-function -1) + (erlang-get-function-arguments))) + ;; Local variables: ;; coding: iso-8859-1 ;; End: diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 113fa24bd5..31754015f7 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1696,6 +1696,8 @@ fix_expr(T, Line, Bump) when is_tuple(T) -> fix_expr(E, _Line, _Bump) -> E. +fix_clauses([], _Line, _Bump) -> + []; fix_clauses(Cs, Line, Bump) -> case bumps_line(lists:last(Cs), Line) of true -> diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl index f1251fddab..d5ba8aa52f 100644 --- a/lib/tools/src/lcnt.erl +++ b/lib/tools/src/lcnt.erl @@ -305,7 +305,7 @@ handle_call({inspect, Lockname, InOpts}, _From, #state{ duration=Duration, locks {true, true} -> locks_ids(Filtered); _ -> [] end, - Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)), + Combos = combine_classes(Filtered, proplists:get_value(combine, Opts)), case proplists:get_value(locations, Opts) of true -> lists:foreach(fun @@ -329,9 +329,8 @@ handle_call({inspect, Lockname, InOpts}, _From, #state{ duration=Duration, locks end end, Combos); _ -> - Print1 = locks2print(Combos, Duration), - Print2 = filter_print(Print1, Opts), - print_lock_information(Print2, proplists:get_value(print, Opts)) + Print = filter_print(locks2print(Combos, Duration), Opts), + print_lock_information(Print, proplists:get_value(print, Opts)) end, {reply, ok, State}; @@ -357,8 +356,7 @@ handle_call({histogram, Lockname, InOpts}, _From, #state{ duration=Duration, loc {thresholds, [{tries, -1}, {colls, -1}, {time, -1}]}], Opts), Prints = locks2print([L], Duration), print_lock_information(Prints, proplists:get_value(print, Opts1)), - print_full_histogram(SumStats#stats.hist), - io:format("~n") + print_full_histogram(SumStats#stats.hist) end, Combos), {reply, ok, State}; @@ -509,20 +507,23 @@ filter_locks(Locks, Lockname) -> % 4. max length of locks filter_print(PLs, Opts) -> - TLs = threshold_locks(PLs, proplists:get_value(thresholds, Opts, [])), - SLs = sort_locks(TLs, proplists:get_value(sort, Opts, time)), - CLs = cut_locks(SLs, proplists:get_value(max_locks, Opts, none)), - reverse_locks(CLs, not proplists:get_value(reverse,Opts, false)). - -sort_locks(Locks, name) -> lists:keysort(#print.name, Locks); -sort_locks(Locks, id) -> lists:keysort(#print.id, Locks); -sort_locks(Locks, type) -> lists:keysort(#print.type, Locks); -sort_locks(Locks, tries) -> lists:keysort(#print.tries, Locks); -sort_locks(Locks, colls) -> lists:keysort(#print.colls, Locks); -sort_locks(Locks, ratio) -> lists:keysort(#print.cr, Locks); -sort_locks(Locks, time) -> lists:keysort(#print.time, Locks); + TLs = threshold_locks(PLs, proplists:get_value(thresholds, Opts, [])), + SLs = sort_locks(TLs, proplists:get_value(sort, Opts, time)), + CLs = cut_locks(SLs, proplists:get_value(max_locks, Opts, none)), + reverse_locks(CLs, proplists:get_value(reverse, Opts, false)). + +sort_locks(Locks, name) -> reverse_sort_locks(#print.name, Locks); +sort_locks(Locks, id) -> reverse_sort_locks(#print.id, Locks); +sort_locks(Locks, type) -> reverse_sort_locks(#print.type, Locks); +sort_locks(Locks, tries) -> reverse_sort_locks(#print.tries, Locks); +sort_locks(Locks, colls) -> reverse_sort_locks(#print.colls, Locks); +sort_locks(Locks, ratio) -> reverse_sort_locks(#print.cr, Locks); +sort_locks(Locks, time) -> reverse_sort_locks(#print.time, Locks); sort_locks(Locks, _) -> sort_locks(Locks, time). +reverse_sort_locks(Ix, Locks) -> + lists:reverse(lists:keysort(Ix, Locks)). + % cut locks not above certain thresholds threshold_locks(Locks, Thresholds) -> Tries = proplists:get_value(tries, Thresholds, -1), @@ -647,15 +648,19 @@ format_histogram(Tup) when is_tuple(Tup) -> _ -> string_histogram([case V of 0 -> 0; _ -> V/Max end || V <- Vs]) end. -string_histogram([0|Vs]) -> - [$\s|string_histogram(Vs)]; -string_histogram([V|Vs]) when V > 0.66 -> - [$X|string_histogram(Vs)]; -string_histogram([V|Vs]) when V > 0.33 -> - [$x|string_histogram(Vs)]; -string_histogram([_|Vs]) -> - [$.|string_histogram(Vs)]; -string_histogram([]) -> []. +string_histogram(Vs) -> + [$||histogram_values_to_string(Vs,$|)]. + +histogram_values_to_string([0|Vs],End) -> + [$\s|histogram_values_to_string(Vs,End)]; +histogram_values_to_string([V|Vs],End) when V > 0.66 -> + [$X|histogram_values_to_string(Vs,End)]; +histogram_values_to_string([V|Vs],End) when V > 0.33 -> + [$x|histogram_values_to_string(Vs,End)]; +histogram_values_to_string([_|Vs],End) -> + [$.|histogram_values_to_string(Vs,End)]; +histogram_values_to_string([],End) -> + [End]. %% state making @@ -778,7 +783,7 @@ auto_print_width(Locks, Print) -> ({print,print}, Out) -> [print|Out]; ({Str, Len}, Out) -> [erlang:min(erlang:max(length(s(Str))+1,Len),80)|Out] end, [], lists:zip(tuple_to_list(L), tuple_to_list(Max))))) - end, #print{ id = 4, type = 5, entry = 5, name = 6, tries = 8, colls = 13, cr = 16, time = 11, dtr = 14, hist=20 }, + end, #print{ id=4, type=5, entry=5, name=6, tries=8, colls=13, cr=16, time=11, dtr=14, hist=20 }, Locks), % Setup the offsets for later pruning Offsets = [ @@ -820,7 +825,7 @@ print_header(Opts) -> cr = "collisions [%]", time = "time [us]", dtr = "duration [%]", - hist = "histogram" + hist = "histogram [log2(us)]" }, Divider = #print{ name = lists:duplicate(1 + length(Header#print.name), 45), @@ -863,9 +868,9 @@ format_lock(L, [Opt|Opts]) -> {time, W} -> [{space, W, s(L#print.time) } | format_lock(L, Opts)]; duration -> [{space, 20, s(L#print.dtr) } | format_lock(L, Opts)]; {duration, W} -> [{space, W, s(L#print.dtr) } | format_lock(L, Opts)]; - histogram -> [{space, 0, s(L#print.hist) } | format_lock(L, Opts)]; - {histogram, W} -> [{space, W, s(L#print.hist) } | format_lock(L, Opts)]; - _ -> format_lock(L, Opts) + histogram -> [{space, 20, s(L#print.hist) } | format_lock(L, Opts)]; + {histogram, W} -> [{left, W - length(s(L#print.hist)) - 1, s(L#print.hist)} | format_lock(L, Opts)]; + _ -> format_lock(L, Opts) end. print_state_information(#state{locks = Locks} = State) -> @@ -926,6 +931,7 @@ s(T) -> term2string(T). strings(Strings) -> strings(Strings, []). strings([], Out) -> Out; strings([{space, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string("~~~ws", [N]), [S])); +strings([{left, N, S} | Ss], Out) -> strings(Ss, Out ++ term2string(term2string(" ~~s~~~ws", [N]), [S,""])); strings([{format, Format, S} | Ss], Out) -> strings(Ss, Out ++ term2string(Format, [S])); strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~ts", [S])). diff --git a/lib/tools/test/cover_SUITE_data/b.erl b/lib/tools/test/cover_SUITE_data/b.erl index 13f39b8cb9..0a418a58d8 100644 --- a/lib/tools/test/cover_SUITE_data/b.erl +++ b/lib/tools/test/cover_SUITE_data/b.erl @@ -1,5 +1,5 @@ -module(b). --export([start/0, loop/0]). +-export([start/0, loop/0, wait/0]). start() -> spawn(?MODULE, loop, []). @@ -12,3 +12,9 @@ loop() -> stop -> done end. + +%% This checks for a bug in expressions which have no +%% "main" clauses (only after and friends) followed by +%% a return value in the same line. +wait() -> + receive after 1000 -> done end, ok. diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 3acb8d38e2..d9651c30e3 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.7 +TOOLS_VSN = 2.7.1 diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4 deleted file mode 100644 index ed492d55ff..0000000000 --- a/lib/wx/aclocal.m4 +++ /dev/null @@ -1,1954 +0,0 @@ -dnl -dnl %CopyrightBegin% -dnl -dnl Copyright Ericsson AB 1998-2013. 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 - -AC_DEFUN(LM_PRECIOUS_VARS, -[ - -dnl ERL_TOP -AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) - -dnl Tools -AC_ARG_VAR(CC, [C compiler]) -AC_ARG_VAR(CFLAGS, [C compiler flags]) -AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) -AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) -AC_ARG_VAR(CPP, [C/C++ preprocessor]) -AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) -AC_ARG_VAR(CXX, [C++ compiler]) -AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) -AC_ARG_VAR(LD, [linker (is often overridden by configure)]) -AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) -AC_ARG_VAR(LIBS, [libraries]) -AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) -AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) -AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) -AC_ARG_VAR(RANLIB, [ranlib]) -AC_ARG_VAR(AR, [ar]) -AC_ARG_VAR(GETCONF, [getconf]) - -dnl Cross system root -AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) - -dnl Cross compilation variables -AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) -AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) - -dnl Cross compilation variables for OSE -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_BEAM_LM_CONF, [BEAM OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_EPMD_LM_CONF, [EPMD OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_RUN_ERL_LM_CONF, [run_erl_lm OSE load module default configuration file (only used when cross compiling for OSE)]) -AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE confd source file]) -AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) - -]) - -AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, -[ -erl_xcomp_without_sysroot=no -if test "$cross_compiling" = "yes"; then - test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes - test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" -else - erl_xcomp_sysroot= - erl_xcomp_isysroot= -fi -]) - -AC_DEFUN(LM_CHECK_GETCONF, -[ -if test "$cross_compiling" != "yes"; then - AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) -else - dnl First check if we got a `<HOST>-getconf' in $PATH - host_getconf="$host_alias-getconf" - AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) - if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then - dnl We should perhaps give up if we have'nt found it by now, but at - dnl least in one Tilera MDE `getconf' under sysroot is a bourne - dnl shell script which we can use. We try to find `<HOST>-getconf' - dnl or `getconf' under sysconf, but only under sysconf since - dnl `getconf' in $PATH is almost guaranteed to be for the build - dnl machine. - GETCONF= - prfx="$erl_xcomp_sysroot" - AC_PATH_TOOL([GETCONF], [getconf], [false], - ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) - fi -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_WINDOWS_ENVIRONMENT -dnl -dnl -dnl Tries to determine thw windows build environment, i.e. -dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC -dnl - -AC_DEFUN(LM_WINDOWS_ENVIRONMENT, -[ -MIXED_CYGWIN=no -MIXED_MSYS=no - -AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) -if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([Cygwin and VC]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - elif test -x /usr/bin/msysinfo; then - CFLAGS="-O2" - MIXED_MSYS=yes - AC_MSG_RESULT([MSYS and VC]) - MIXED_MSYS_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no - MIXED_MSYS_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) -AC_SUBST(MIXED_MSYS_VC) - -MIXED_VC=no -if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then - MIXED_VC=yes -fi - -AC_SUBST(MIXED_VC) - -if test "x$MIXED_MSYS" != "xyes"; then - AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) - if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi - else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no - fi -else - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) - -AC_MSG_CHECKING(if we mix msys with another native compiler) -if test "X$MIXED_MSYS" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_MSYS) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_FIND_EMU_CC -dnl -dnl -dnl Tries fairly hard to find a C compiler that can handle jump tables. -dnl Defines the @EMU_CC@ variable for the makefiles and -dnl inserts NO_JUMP_TABLE in the header if one cannot be found... -dnl - -AC_DEFUN(LM_FIND_EMU_CC, - [AC_CACHE_CHECK(for a compiler that handles jumptables, - ac_cv_prog_emu_cc, - [ -AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; -lbl1: - return 1; -lbl2: - return 2; -],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - -if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc-4.2 gcc; do - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_progname; then - ac_cv_prog_emu_cc=$ac_dir/$ac_progname - break - fi - done - IFS="$ac_save_ifs" - if test $ac_cv_prog_emu_cc != no; then - break - fi - done -fi - -if test $ac_cv_prog_emu_cc != no; then - save_CC=$CC - save_CFLAGS=$CFLAGS - save_CPPFLAGS=$CPPFLAGS - CC=$ac_cv_prog_emu_cc - CFLAGS="" - CPPFLAGS="" - AC_TRY_COMPILE([],[ -#if defined(__clang_major__) && __clang_major__ >= 3 - /* clang 3.x or later is fine */ -#elif defined(__llvm__) -#error "this version of llvm is unable to correctly compile beam_emu.c" -#endif - __label__ lbl1; - __label__ lbl2; - int x = magic(); - static void *jtab[2]; - - jtab[0] = &&lbl1; - jtab[1] = &&lbl2; - goto *jtab[x]; - lbl1: - return 1; - lbl2: - return 2; - ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) - CC=$save_CC - CFLAGS=$save_CFLAGS - CPPFLAGS=$save_CPPFLAGS -fi -]) -if test $ac_cv_prog_emu_cc = no; then - AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) - EMU_CC=$CC -else - EMU_CC=$ac_cv_prog_emu_cc -fi -AC_SUBST(EMU_CC) -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_INSTALL_DIR -dnl -dnl This macro may be used by any OTP application. -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 -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_PROG_PERL5 -dnl -dnl Try to find perl version 5. If found set PERL to the absolute path -dnl of the program, if not found set PERL to false. -dnl -dnl On some systems /usr/bin/perl is perl 4 and e.g. -dnl /usr/local/bin/perl is perl 5. We try to handle this case by -dnl putting a couple of -dnl Tries to handle the case that there are two programs called perl -dnl in the path and one of them is perl 5 and the other isn't. -dnl -AC_DEFUN(LM_PROG_PERL5, -[AC_PATH_PROGS(PERL, perl5 perl, false, - /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) -changequote(, )dnl -dnl[ That bracket is needed to balance the right bracket below -if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then -changequote([, ])dnl - ac_cv_path_PERL=false - PERL=false -dnl AC_MSG_WARN(perl version 5 not found) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SO_BSDCOMPAT -dnl -dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) -dnl -AC_DEFUN(LM_DECL_SO_BSDCOMPAT, -[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, -AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], - ac_cv_decl_so_bsdcompat=yes, - ac_cv_decl_so_bsdcompat=no)) - -case "${ac_cv_decl_so_bsdcompat}" in - "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], - [Define if you have SO_BSDCOMPAT flag on sockets]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_INADDR_LOOPBACK -dnl -dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default -dnl - -AC_DEFUN(LM_DECL_INADDR_LOOPBACK, -[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], - ac_cv_decl_inaddr_loopback, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], -ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) -]) - -if test ${ac_cv_decl_inaddr_loopback} = no; then - AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], - ac_cv_decl_inaddr_loopback_rpc, - AC_TRY_COMPILE([#include <rpc/types.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_rpc=yes, - ac_cv_decl_inaddr_loopback_rpc=no)) - - case "${ac_cv_decl_inaddr_loopback_rpc}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], - [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; - * ) - AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], - ac_cv_decl_inaddr_loopback_winsock2, - AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN - #include <winsock2.h>], - [int i = INADDR_LOOPBACK;], - ac_cv_decl_inaddr_loopback_winsock2=yes, - ac_cv_decl_inaddr_loopback_winsock2=no)) - case "${ac_cv_decl_inaddr_loopback_winsock2}" in - "yes" ) - AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], - [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; - * ) - # couldn't find it anywhere - AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], - [Define if you don't have a definition of INADDR_LOOPBACK]) ;; - esac;; - esac -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_SOCKADDR_SA_LEN -dnl -dnl Check if the sockaddr structure has the field sa_len -dnl - -AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, -[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], - ac_cv_struct_sockaddr_sa_len, -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], - ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) - -dnl FIXME convbreak -case ${ac_cv_struct_sockaddr_sa_len} in - "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; - *) ;; -esac -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_STRUCT_EXCEPTION -dnl -dnl Check to see whether the system supports the matherr function -dnl and its associated type "struct exception". -dnl - -AC_DEFUN(LM_STRUCT_EXCEPTION, -[AC_CACHE_CHECK([for struct exception (and matherr function)], - ac_cv_struct_exception, -AC_TRY_COMPILE([#include <math.h>], - [struct exception x; x.type = DOMAIN; x.type = SING;], - ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) - -case "${ac_cv_struct_exception}" in - "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; - * ) ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_IPV6 -dnl -dnl Check for ipv6 support and what the in6_addr structure is called. -dnl (early linux used in_addr6 insted of in6_addr) -dnl - -AC_DEFUN(LM_SYS_IPV6, -[AC_MSG_CHECKING(for IP version 6 support) -AC_CACHE_VAL(ac_cv_sys_ipv6_support, -[ok_so_far=yes - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) - -if test $ok_so_far = yes; then - ac_cv_sys_ipv6_support=yes -else - AC_TRY_COMPILE([#include <sys/types.h> -#ifdef __WIN32__ -#include <winsock2.h> -#include <ws2tcpip.h> -#elif __OSE__ -#error "no ipv6" -#else -#include <netinet/in.h> -#endif], - [struct in_addr6 a6; struct sockaddr_in6 s6;], - ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) -fi -])dnl - -dnl -dnl Have to use old style AC_DEFINE due to BC with old autoconf. -dnl - -case ${ac_cv_sys_ipv6_support} in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - ;; - in_addr6) - AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) - AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) - AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) - ;; - *) - AC_MSG_RESULT(no) - ;; -esac -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_SYS_MULTICAST -dnl -dnl Check for multicast support. Only checks for multicast options in -dnl setsockopt(), no check is performed that multicasting actually works. -dnl If options are found defines HAVE_MULTICAST_SUPPORT -dnl - -AC_DEFUN(LM_SYS_MULTICAST, -[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, -[AC_EGREP_CPP(yes, -[#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) -yes -#endif -], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) -if test $ac_cv_sys_multicast_support = yes; then - AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], - [Define if setsockopt() accepts multicast options]) -fi -])dnl - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_DECL_SYS_ERRLIST -dnl -dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared -dnl in a system header file, stdio.h or errno.h. -dnl - -AC_DEFUN(LM_DECL_SYS_ERRLIST, -[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], - ac_cv_decl_sys_errlist, -[AC_TRY_COMPILE([#include <stdio.h> -#include <errno.h>], [char *msg = *(sys_errlist + 1);], - ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) -if test $ac_cv_decl_sys_errlist = yes; then - AC_DEFINE(SYS_ERRLIST_DECLARED,[], - [define if the variable sys_errlist is declared in a system header file]) -fi -]) - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes -dnl [, action-if-found [, action-if-not-found]]] ) -dnl -dnl Checks if the declaration "declaration" of "funname" conflicts -dnl with the header files idea of how the function should be -dnl declared. It is useful on systems which lack prototypes and you -dnl need to provide your own (e.g. when you want to take the address -dnl of a function). The 4'th argument is expanded if conflicting, -dnl the 5'th argument otherwise -dnl -dnl - -AC_DEFUN(LM_CHECK_FUNC_DECL, -[AC_MSG_CHECKING([for conflicting declaration of $1]) -AC_CACHE_VAL(ac_cv_func_decl_$1, -[AC_TRY_COMPILE([#include <stdio.h> -$3],[$2 -char *c = (char *)$1; -], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) -if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then - AC_MSG_RESULT(yes) - ifelse([$4], , :, [$4]) -else - AC_MSG_RESULT(no) -ifelse([$5], , , [$5 -])dnl -fi -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl AC_DOUBLE_MIDDLE_ENDIAN -dnl -dnl Checks whether doubles are represented in "middle-endian" format. -dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly, -dnl as well as DOUBLE_MIDDLE_ENDIAN. -dnl -dnl - -AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN], -[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian, -[# It does not; compile a test program. -AC_RUN_IFELSE( -[AC_LANG_SOURCE([[#include <stdlib.h> - -int -main(void) -{ - int i = 0; - int zero = 0; - int bigendian; - int zero_index = 0; - - union - { - long int l; - char c[sizeof (long int)]; - } u; - - /* we'll use the one with 32-bit words */ - union - { - double d; - unsigned int c[2]; - } vint; - - union - { - double d; - unsigned long c[2]; - } vlong; - - union - { - double d; - unsigned short c[2]; - } vshort; - - - /* Are we little or big endian? From Harbison&Steele. */ - u.l = 1; - bigendian = (u.c[sizeof (long int) - 1] == 1); - - zero_index = bigendian ? 1 : 0; - - vint.d = 1.0; - vlong.d = 1.0; - vshort.d = 1.0; - - if (sizeof(unsigned int) == 4) - { - if (vint.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned long) == 4) - { - if (vlong.c[zero_index] != 0) - zero = 1; - } - else if (sizeof(unsigned short) == 4) - { - if (vshort.c[zero_index] != 0) - zero = 1; - } - - exit (zero); -} -]])], - [ac_cv_c_double_middle_endian=no], - [ac_cv_c_double_middle_endian=yes], - [ac_cv_c_double_middle=unknown])]) -case $ac_cv_c_double_middle_endian in - yes) - m4_default([$1], - [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1, - [Define to 1 if your processor stores the words in a double in - middle-endian format (like some ARMs).])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_WARN([unknown double endianness -presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;; -esac -])# AC_C_DOUBLE_MIDDLE_ENDIAN - - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_CHECK_THR_LIB -dnl -dnl This macro may be used by any OTP application. -dnl -dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also -dnl checks for some pthread headers which will appear in DEFS or config.h. -dnl - -AC_DEFUN(LM_CHECK_THR_LIB, -[ - -NEED_NPTL_PTHREAD_H=no - -dnl win32? -AC_MSG_CHECKING([for native win32 threads]) -if test "X$host_os" = "Xwin32"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DWIN32_THREADS" - THR_LIBS= - THR_LIB_NAME=win32_threads - THR_LIB_TYPE=win32_threads -elif test "X$host_os" = "Xose"; then - AC_MSG_RESULT(yes) - THR_DEFS="-DOSE_THREADS" - THR_LIBS= - THR_LIB_NAME=ose_threads - THR_LIB_TYPE=ose_threads -else - AC_MSG_RESULT(no) - THR_DEFS= - THR_LIBS= - THR_LIB_NAME= - THR_LIB_TYPE=posix_unknown - -dnl Try to find POSIX threads - -dnl The usual pthread lib... - AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") - -dnl Very old versions of FreeBSD have pthreads in special c library, c_r... - if test "x$THR_LIBS" = "x"; then - AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") - fi - -dnl QNX has pthreads in standard C library - if test "x$THR_LIBS" = "x"; then - AC_CHECK_FUNC(pthread_create, THR_LIBS="none_needed") - fi - -dnl On ofs1 the '-pthread' switch should be used - if test "x$THR_LIBS" = "x"; then - AC_MSG_CHECKING([if the '-pthread' switch can be used]) - saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -pthread" - AC_TRY_LINK([#include <pthread.h>], - pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, - [THR_DEFS="-pthread" - THR_LIBS="-pthread"]) - CFLAGS=$saved_cflags - if test "x$THR_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - fi - - if test "x$THR_LIBS" != "x"; then - THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" - THR_LIB_NAME=pthread - if test "x$THR_LIBS" = "xnone_needed"; then - THR_LIBS= - fi - case $host_os in - solaris*) - THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; - linux*) - THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" - - LM_CHECK_GETCONF - AC_MSG_CHECKING(for Native POSIX Thread Library) - libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` - if test $? -eq 0; then - case "$libpthr_vsn" in - *nptl*|*NPTL*) nptl=yes;; - *) nptl=no;; - esac - elif test "$cross_compiling" = "yes"; then - case "$erl_xcomp_linux_nptl" in - "") nptl=cross;; - yes|no) nptl=$erl_xcomp_linux_nptl;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; - esac - else - nptl=no - fi - AC_MSG_RESULT($nptl) - if test $nptl = cross; then - nptl=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $nptl = yes; then - THR_LIB_TYPE=posix_nptl - need_nptl_incldir=no - AC_CHECK_HEADER(nptl/pthread.h, - [need_nptl_incldir=yes - NEED_NPTL_PTHREAD_H=yes]) - if test $need_nptl_incldir = yes; then - # Ahh... - nptl_path="$C_INCLUDE_PATH:$CPATH" - if test X$cross_compiling != Xyes; then - nptl_path="$nptl_path:/usr/local/include:/usr/include" - else - IROOT="$erl_xcomp_isysroot" - test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" - test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) - nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" - fi - nptl_ws_path= - save_ifs="$IFS"; IFS=":" - for dir in $nptl_path; do - if test "x$dir" != "x"; then - nptl_ws_path="$nptl_ws_path $dir" - fi - done - IFS=$save_ifs - nptl_incldir= - for dir in $nptl_ws_path; do - AC_CHECK_HEADER($dir/nptl/pthread.h, - nptl_incldir=$dir/nptl) - if test "x$nptl_incldir" != "x"; then - THR_DEFS="$THR_DEFS -isystem $nptl_incldir" - break - fi - done - if test "x$nptl_incldir" = "x"; then - AC_MSG_ERROR(Failed to locate nptl system include directory) - fi - fi - fi - ;; - *) ;; - esac - - dnl We sometimes need THR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $THR_DEFS" - - dnl - dnl Check for headers - dnl - - AC_CHECK_HEADER(pthread.h, - AC_DEFINE(HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - fi -fi - -]) - -AC_DEFUN(ERL_INTERNAL_LIBS, -[ - -ERTS_INTERNAL_X_LIBS= - -AC_CHECK_LIB(kstat, kstat_open, -[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) -ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) - -AC_SUBST(ERTS_INTERNAL_X_LIBS) - -]) - -AC_DEFUN(ETHR_CHK_SYNC_OP, -[ - AC_MSG_CHECKING([for $3-bit $1()]) - case "$2" in - "1") sync_call="$1(&var);";; - "2") sync_call="$1(&var, ($4) 0);";; - "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; - esac - have_sync_op=no - AC_TRY_LINK([], - [ - $4 res; - volatile $4 var; - res = $sync_call - ], - [have_sync_op=yes]) - test $have_sync_op = yes && $5 - AC_MSG_RESULT([$have_sync_op]) -]) - -AC_DEFUN(ETHR_CHK_INTERLOCKED, -[ - ilckd="$1" - AC_MSG_CHECKING([for ${ilckd}()]) - case "$2" in - "1") ilckd_call="${ilckd}(var);";; - "2") ilckd_call="${ilckd}(var, ($3) 0);";; - "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; - "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; - esac - have_interlocked_op=no - AC_TRY_LINK( - [ - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <intrin.h> - ], - [ - volatile $3 *var; - volatile $3 arr[2]; - - $ilckd_call - return 0; - ], - [have_interlocked_op=yes]) - test $have_interlocked_op = yes && $4 - AC_MSG_RESULT([$have_interlocked_op]) -]) - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_FIND_ETHR_LIB -dnl -dnl NOTE! This macro may be changed at any time! Should *only* be used by -dnl ERTS! -dnl -dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link -dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS -dnl except that the ethread lib itself is not included), ETHR_DEFS to -dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the -dnl thread library which the ethread library is based on, and ETHR_LIB_NAME -dnl to the name of the library where the ethread implementation is located. -dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and -dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, -dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the -dnl empty string. -dnl - -AC_DEFUN(ERL_FIND_ETHR_LIB, -[ - -AC_ARG_ENABLE(native-ethr-impls, - AS_HELP_STRING([--disable-native-ethr-impls], - [disable native ethread implementations]), -[ case "$enableval" in - no) disable_native_ethr_impls=yes ;; - *) disable_native_ethr_impls=no ;; - esac ], disable_native_ethr_impls=no) - -test "X$disable_native_ethr_impls" = "Xyes" && - AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) - -AC_ARG_ENABLE(x86-out-of-order, - AS_HELP_STRING([--enable-x86-out-of-order], - [enable x86/x84_64 out of order support (default disabled)])) - -AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, - AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [prefer gcc native ethread implementations]), -[ case "$enableval" in - yes) enable_prefer_gcc_native_ethr_impls=yes ;; - *) enable_prefer_gcc_native_ethr_impls=no ;; - esac ], enable_prefer_gcc_native_ethr_impls=no) - -test $enable_prefer_gcc_native_ethr_impls = yes && - AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) - -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [specify and prefer usage of libatomic_ops in the ethread library])) - -AC_ARG_WITH(with_sparc_memory_order, - AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], - [specify sparc memory order (defaults to RMO)])) - -LM_CHECK_THR_LIB -ERL_INTERNAL_LIBS - -ethr_have_native_atomics=no -ethr_have_native_spinlock=no -ETHR_THR_LIB_BASE="$THR_LIB_NAME" -ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" -ETHR_DEFS="$THR_DEFS" -ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" -ETHR_LIBS= -ETHR_LIB_NAME= - -ethr_modified_default_stack_size= - -dnl Name of lib where ethread implementation is located -ethr_lib_name=ethread - -case "$THR_LIB_NAME" in - - win32_threads) - ETHR_THR_LIB_BASE_DIR=win - # * _WIN32_WINNT >= 0x0400 is needed for - # TryEnterCriticalSection - # * _WIN32_WINNT >= 0x0403 is needed for - # InitializeCriticalSectionAndSpinCount - # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. - # - # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it - # and save it in ETHR_DEFS. - found_win32_winnt=no - for cppflag in $CPPFLAGS; do - case $cppflag in - -DWINVER*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - ;; - -D_WIN32_WINNT*) - ETHR_DEFS="$ETHR_DEFS $cppflag" - found_win32_winnt=yes - ;; - *) - ;; - esac - done - if test $found_win32_winnt = no; then - AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) - fi - - AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) - - if test "X$disable_native_ethr_impls" = "Xyes"; then - have_interlocked_op=no - ethr_have_native_atomics=no - else - ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) - ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) - ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) - ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) - ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) - test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes - - ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) - fi - test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes - ;; - - pthread|ose_threads) - case "$THR_LIB_NAME" in - pthread) - ETHR_THR_LIB_BASE_DIR=pthread - AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) - ;; - ose_threads) - AC_DEFINE(ETHR_OSE_THREADS, 1, - [Define if you have OSE style threads]) - ETHR_THR_LIB_BASE_DIR=ose - AC_CHECK_HEADER(ose_spi/ose_spi.h, - AC_DEFINE(HAVE_OSE_SPI_H, 1, - [Define if you have the "ose_spi/ose_spi.h" header file.])) - ;; - esac - if test "x$THR_LIB_NAME" = "xpthread"; then - case $host_os in - openbsd*) - # The default stack size is insufficient for our needs - # on OpenBSD. We increase it to 256 kilo words. - ethr_modified_default_stack_size=256;; - linux*) - ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" - - if test X$cross_compiling = Xyes; then - case X$erl_xcomp_linux_usable_sigusrx in - X) usable_sigusrx=cross;; - Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; - esac - case X$erl_xcomp_linux_usable_sigaltstack in - X) usable_sigaltstack=cross;; - Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; - *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; - esac - else - # FIXME: Test for actual problems instead of kernel versions - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) - usable_sigusrx=no - usable_sigaltstack=no;; - 2.[[2-3]]|2.[[2-3]].*) - usable_sigusrx=yes - usable_sigaltstack=no;; - *) - usable_sigusrx=yes - usable_sigaltstack=yes;; - esac - fi - - AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) - AC_MSG_RESULT($usable_sigusrx) - if test $usable_sigusrx = cross; then - usable_sigusrx=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigusrx = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" - fi - - AC_MSG_CHECKING(if sigaltstack can be used) - AC_MSG_RESULT($usable_sigaltstack) - if test $usable_sigaltstack = cross; then - usable_sigaltstack=yes - AC_MSG_WARN([result yes guessed because of cross compilation]) - fi - if test $usable_sigaltstack = no; then - ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" - fi - ;; - *) ;; - esac - - fi - dnl We sometimes need ETHR_DEFS in order to find certain headers - dnl (at least for pthread.h on osf1). - saved_cppflags="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ETHR_DEFS" - - dnl We need the thread library in order to find some functions - saved_libs="$LIBS" - LIBS="$LIBS $ETHR_X_LIBS" - - dnl - dnl Check for headers - dnl - AC_CHECK_HEADER(pthread.h, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ -[Define if you have the <pthread.h> header file.])) - - dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> - AC_CHECK_HEADER(pthread/mit/pthread.h, \ - AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ -[Define if the pthread.h header file is in pthread/mit directory.])) - - if test $NEED_NPTL_PTHREAD_H = yes; then - AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ -[Define if you need the <nptl/pthread.h> header file.]) - fi - - AC_CHECK_HEADER(sched.h, \ - AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ -[Define if you have the <sched.h> header file.])) - - AC_CHECK_HEADER(sys/time.h, \ - AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ -[Define if you have the <sys/time.h> header file.])) - - AC_TRY_COMPILE([#include <time.h> - #include <sys/time.h>], - [struct timeval *tv; return 0;], - AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ -[Define if you can safely include both <sys/time.h> and <time.h>.])) - - - dnl - dnl Check for functions - dnl - if test "x$THR_LIB_NAME" = "xpthread"; then - AC_CHECK_FUNC(pthread_spin_lock, \ - [ethr_have_native_spinlock=yes \ - AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ -[Define if you have the pthread_spin_lock function.])]) - - have_sched_yield=no - have_librt_sched_yield=no - AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) - if test $have_sched_yield = no; then - AC_CHECK_LIB(rt, sched_yield, - [have_librt_sched_yield=yes - ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) - fi - if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then - AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) - AC_MSG_CHECKING([whether sched_yield() returns an int]) - sched_yield_ret_int=no - AC_TRY_COMPILE([ - #ifdef ETHR_HAVE_SCHED_H - #include <sched.h> - #endif - ], - [int sched_yield();], - [sched_yield_ret_int=yes]) - AC_MSG_RESULT([$sched_yield_ret_int]) - if test $sched_yield_ret_int = yes; then - AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) - fi - fi - - have_pthread_yield=no - AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) - if test $have_pthread_yield = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) - AC_MSG_CHECKING([whether pthread_yield() returns an int]) - pthread_yield_ret_int=no - AC_TRY_COMPILE([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [int pthread_yield();], - [pthread_yield_ret_int=yes]) - AC_MSG_RESULT([$pthread_yield_ret_int]) - if test $pthread_yield_ret_int = yes; then - AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) - fi - fi - - have_pthread_rwlock_init=no - AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) - if test $have_pthread_rwlock_init = yes; then - - ethr_have_pthread_rwlockattr_setkind_np=no - AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, - [ethr_have_pthread_rwlockattr_setkind_np=yes]) - - if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ -[Define if you have the pthread_rwlockattr_setkind_np() function.]) - - AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) - ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no - AC_TRY_LINK([ - #if defined(ETHR_NEED_NPTL_PTHREAD_H) - #include <nptl/pthread.h> - #elif defined(ETHR_HAVE_MIT_PTHREAD_H) - #include <pthread/mit/pthread.h> - #elif defined(ETHR_HAVE_PTHREAD_H) - #include <pthread.h> - #endif - ], - [ - pthread_rwlockattr_t *attr; - return pthread_rwlockattr_setkind_np(attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - ], - [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) - AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) - if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then - AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ -[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) - fi - fi - fi - - if test "$force_pthread_rwlocks" = "yes"; then - - AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ -[Define if you want to force usage of pthread rwlocks]) - - if test $have_pthread_rwlock_init = yes; then - AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) - else - AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) - fi - fi - - AC_CHECK_FUNC(pthread_attr_setguardsize, \ - AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ -[Define if you have the pthread_attr_setguardsize function.])) - - linux_futex=no - AC_MSG_CHECKING([for Linux futexes]) - AC_TRY_LINK([ - #include <sys/syscall.h> - #include <unistd.h> - #include <linux/futex.h> - #include <sys/time.h> - ], - [ - int i = 1; - syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, - (void*)0,(void*)0, 0); - syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, - (void*)0,(void*)0, 0); - return 0; - ], - linux_futex=yes) - AC_MSG_RESULT([$linux_futex]) - test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) - - fi - - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int128_t) - - if test "$ac_cv_sizeof_int" = "4"; then - int32="int" - elif test "$ac_cv_sizeof_long" = "4"; then - int32="long" - elif test "$ac_cv_sizeof_long_long" = "4"; then - int32="long long" - else - AC_MSG_ERROR([No 32-bit type found]) - fi - - if test "$ac_cv_sizeof_int" = "8"; then - int64="int" - elif test "$ac_cv_sizeof_long" = "8"; then - int64="long" - elif test "$ac_cv_sizeof_long_long" = "8"; then - int64="long long" - else - AC_MSG_ERROR([No 64-bit type found]) - fi - - int128=no - if test "$ac_cv_sizeof___int128_t" = "16"; then - int128="__int128_t" - fi - - if test "X$disable_native_ethr_impls" = "Xyes"; then - ethr_have_native_atomics=no - else - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) - - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) - test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes - ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) - ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) - - if test $int128 != no; then - ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) - fi - - AC_MSG_CHECKING([for a usable libatomic_ops implementation]) - case "x$with_libatomic_ops" in - xno | xyes | x) - libatomic_ops_include= - ;; - *) - if test -d "${with_libatomic_ops}/include"; then - libatomic_ops_include="-I$with_libatomic_ops/include" - CPPFLAGS="$CPPFLAGS $libatomic_ops_include" - else - AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) - fi;; - esac - ethr_have_libatomic_ops=no - AC_TRY_LINK([#include "atomic_ops.h"], - [ - volatile AO_t x; - AO_t y; - int z; - - AO_nop_full(); - AO_store(&x, (AO_t) 0); - z = AO_load(&x); - z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); - ], - [ethr_have_native_atomics=yes - ethr_have_libatomic_ops=yes]) - AC_MSG_RESULT([$ethr_have_libatomic_ops]) - if test $ethr_have_libatomic_ops = yes; then - AC_CHECK_SIZEOF(AO_t, , - [ - #include <stdio.h> - #include "atomic_ops.h" - ]) - AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) - - AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) - if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) - fi - ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" - elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then - AC_MSG_ERROR([No usable libatomic_ops implementation found]) - fi - - case "$host_cpu" in - sparc | sun4u | sparc64 | sun4v) - case "$with_sparc_memory_order" in - "TSO") - AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; - "PSO") - AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; - "RMO"|"") - AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; - *) - AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; - esac - ethr_have_native_atomics=yes;; - i86pc | i*86 | x86_64 | amd64) - if test "$enable_x86_out_of_order" = "yes"; then - AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) - fi - ethr_have_native_atomics=yes;; - macppc | ppc | powerpc | "Power Macintosh") - ethr_have_native_atomics=yes;; - tile) - ethr_have_native_atomics=yes;; - *) - ;; - esac - - fi - - test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes - - dnl Restore LIBS - LIBS=$saved_libs - dnl restore CPPFLAGS - CPPFLAGS=$saved_cppflags - - ;; - *) - ;; -esac - -AC_MSG_CHECKING([whether default stack size should be modified]) -if test "x$ethr_modified_default_stack_size" != "x"; then - AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) - AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) -else - AC_MSG_RESULT([no]) -fi - -if test "x$ETHR_THR_LIB_BASE" != "x"; then - ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" - ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" - ETHR_LIB_NAME=$ethr_lib_name -fi - -AC_CHECK_SIZEOF(void *) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) - -AC_CHECK_SIZEOF(int) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) -AC_CHECK_SIZEOF(long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) -AC_CHECK_SIZEOF(long long) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) -AC_CHECK_SIZEOF(__int64) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) -AC_CHECK_SIZEOF(__int128_t) -AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) - - -case X$erl_xcomp_bigendian in - X) ;; - Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; - *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; -esac - -AC_C_BIGENDIAN - -if test "$ac_cv_c_bigendian" = "yes"; then - AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) -fi - -case X$erl_xcomp_double_middle_endian in - X) ;; - Xyes|Xno|Xunknown) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;; - *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);; -esac - -AC_C_DOUBLE_MIDDLE_ENDIAN - -ETHR_X86_SSE2_ASM=no -case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in - yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) - AC_MSG_CHECKING([for gcc sse2 asm support]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -msse2" - gcc_sse2_asm=no - AC_TRY_COMPILE([], - [ - long long x, *y; - __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); - ], - [gcc_sse2_asm=yes]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$gcc_sse2_asm]) - if test "$gcc_sse2_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) - ETHR_X86_SSE2_ASM=yes - fi - ;; - *) - ;; -esac - -case "$GCC-$host_cpu" in - yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) - gcc_dw_cmpxchg_asm=no - AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; - __asm__ __volatile__( -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "pushl %%ebx\n\t" - "movl %8, %%ebx\n\t" -#endif -#if ETHR_SIZEOF_PTR == 4 - "lock; cmpxchg8b %0\n\t" -#else - "lock; cmpxchg16b %0\n\t" -#endif - "setz %3\n\t" -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "popl %%ebx\n\t" -#endif - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), -#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ - "r"(new[0]) -#else - "b"(new[0]) -#endif - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then - AC_TRY_COMPILE([], - [ - char xchgd; - long new[2], xchg[2], *p; -#if !defined(__PIC__) || !__PIC__ -# error nope -#endif - __asm__ __volatile__( - "pushl %%ebx\n\t" - "movl (%7), %%ebx\n\t" - "movl 4(%7), %%ecx\n\t" - "lock; cmpxchg8b %0\n\t" - "setz %3\n\t" - "popl %%ebx\n\t" - : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) - : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) - : "cc", "memory"); - - ], - [gcc_dw_cmpxchg_asm=yes]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) - fi - fi - AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) - if test "$gcc_dw_cmpxchg_asm" = "yes"; then - AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) - fi;; - *) - ;; -esac - -AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ -[Define if you have all ethread defines]) - -AC_SUBST(ETHR_X_LIBS) -AC_SUBST(ETHR_LIBS) -AC_SUBST(ETHR_LIB_NAME) -AC_SUBST(ETHR_DEFS) -AC_SUBST(ETHR_THR_LIB_BASE) -AC_SUBST(ETHR_THR_LIB_BASE_DIR) -AC_SUBST(ETHR_X86_SSE2_ASM) - -]) - - - -dnl ---------------------------------------------------------------------- -dnl -dnl ERL_TIME_CORRECTION -dnl -dnl In the presence of a high resolution realtime timer Erlang can adapt -dnl its view of time relative to this timer. On solaris such a timer is -dnl available with the syscall gethrtime(). On other OS's a fallback -dnl solution using times() is implemented. (However on e.g. FreeBSD times() -dnl is implemented using gettimeofday so it doesn't make much sense to -dnl use it there...) On second thought, it seems to be safer to do it the -dnl other way around. I.e. only use times() on OS's where we know it will -dnl work... -dnl - -AC_DEFUN(ERL_TIME_CORRECTION, -[if test x$ac_cv_func_gethrtime = x; then - AC_CHECK_FUNC(gethrtime) -fi -if test x$clock_gettime_correction = xunknown; then - AC_TRY_COMPILE([#include <time.h>], - [struct timespec ts; - long long result; - clock_gettime(CLOCK_MONOTONIC,&ts); - result = ((long long) ts.tv_sec) * 1000000000LL + - ((long long) ts.tv_nsec);], - clock_gettime_compiles=yes, - clock_gettime_compiles=no) -else - clock_gettime_compiles=no -fi - - -AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, -[ -case $clock_gettime_correction in - yes) - erl_cv_time_correction=clock_gettime;; - no|unknown) - case $ac_cv_func_gethrtime in - yes) - erl_cv_time_correction=hrtime ;; - no) - case $host_os in - linux*) - case $clock_gettime_correction in - unknown) - if test x$clock_gettime_compiles = xyes; then - if test X$cross_compiling != Xyes; then - linux_kernel_vsn_=`uname -r` - case $linux_kernel_vsn_ in - [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) - erl_cv_time_correction=times ;; - *) - erl_cv_time_correction=clock_gettime;; - esac - else - case X$erl_xcomp_linux_clock_gettime_correction in - X) - erl_cv_time_correction=cross;; - Xyes|Xno) - if test $erl_xcomp_linux_clock_gettime_correction = yes; then - erl_cv_time_correction=clock_gettime - else - erl_cv_time_correction=times - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; - esac - fi - else - erl_cv_time_correction=times - fi - ;; - *) - erl_cv_time_correction=times ;; - esac - ;; - *) - erl_cv_time_correction=none ;; - esac - ;; - esac - ;; -esac -]) - -xrtlib="" -case $erl_cv_time_correction in - times) - AC_DEFINE(CORRECT_USING_TIMES,[], - [Define if you do not have a high-res. timer & want to use times() instead]) - ;; - clock_gettime|cross) - if test $erl_cv_time_correction = cross; then - erl_cv_time_correction=clock_gettime - AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) - fi - xrtlib="-lrt" - AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], - [Define if you want to use clock_gettime to simulate gethrtime]) - ;; -esac -dnl -dnl Check if gethrvtime is working, and if to use procfs ioctl -dnl or (yet to be written) write to the procfs ctl file. -dnl - -AC_MSG_CHECKING([if gethrvtime works and how to use it]) -AC_TRY_RUN([ -/* gethrvtime procfs ioctl test */ -/* These need to be undef:ed to not break activation of - * micro level process accounting on /proc/self - */ -#ifdef _LARGEFILE_SOURCE -# undef _LARGEFILE_SOURCE -#endif -#ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -#endif -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/signal.h> -#include <sys/fault.h> -#include <sys/syscall.h> -#include <sys/procfs.h> -#include <fcntl.h> - -int main() { - long msacct = PR_MSACCT; - int fd; - long long start, stop; - int i; - pid_t pid = getpid(); - char proc_self[30] = "/proc/"; - - sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); - if ( (fd = open(proc_self, O_WRONLY)) == -1) - exit(1); - if (ioctl(fd, PIOCSET, &msacct) < 0) - exit(2); - if (close(fd) < 0) - exit(3); - start = gethrvtime(); - for (i = 0; i < 100; i++) - stop = gethrvtime(); - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; -} -], -erl_gethrvtime=procfs_ioctl, -erl_gethrvtime=false, -[ -case X$erl_xcomp_gethrvtime_procfs_ioctl in - X) - erl_gethrvtime=cross;; - Xyes|Xno) - if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then - erl_gethrvtime=procfs_ioctl - else - erl_gethrvtime=false - fi;; - *) - AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; -esac -]) - -case $erl_gethrvtime in - procfs_ioctl) - AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], - [define if gethrvtime() works and uses ioctl() to /proc/self]) - AC_MSG_RESULT(uses ioctl to procfs) - ;; - *) - if test $erl_gethrvtime = cross; then - erl_gethrvtime=false - AC_MSG_RESULT(cross) - AC_MSG_WARN([result 'not working' guessed because of cross compilation]) - else - AC_MSG_RESULT(not working) - fi - - dnl - dnl Check if clock_gettime (linux) is working - dnl - - AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) - save_libs=$LIBS - LIBS="-lrt" - AC_TRY_RUN([ - #include <stdlib.h> - #include <unistd.h> - #include <string.h> - #include <stdio.h> - #include <time.h> - int main() { - long long start, stop; - int i; - struct timespec tp; - - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) - exit(1); - start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - for (i = 0; i < 100; i++) - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); - stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; - if (start == 0) - exit(4); - if (start == stop) - exit(5); - exit(0); return 0; - } - ], - erl_clock_gettime=yes, - erl_clock_gettime=no, - [ - case X$erl_xcomp_clock_gettime_cpu_time in - X) erl_clock_gettime=cross;; - Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; - *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; - esac - ]) - LIBS=$save_libs - case $host_os in - linux*) - AC_MSG_RESULT([no; not stable]) - LIBRT=$xrtlib - ;; - *) - AC_MSG_RESULT($erl_clock_gettime) - case $erl_clock_gettime in - yes) - AC_DEFINE(HAVE_CLOCK_GETTIME,[], - [define if clock_gettime() works for getting process time]) - LIBRT=-lrt - ;; - cross) - erl_clock_gettime=no - AC_MSG_WARN([result no guessed because of cross compilation]) - LIBRT=$xrtlib - ;; - *) - LIBRT=$xrtlib - ;; - esac - ;; - esac - AC_SUBST(LIBRT) - ;; -esac -])dnl - -dnl ---------------------------------------------------------------------- -dnl -dnl LM_TRY_ENABLE_CFLAG -dnl -dnl -dnl Tries a CFLAG and sees if it can be enabled without compiler errors -dnl $1: textual cflag to add -dnl $2: variable to store the modified CFLAG in -dnl Usage example LM_TRY_ENABLE_CFLAG([-Werror=return-type], [CFLAGS]) -dnl -dnl -AC_DEFUN([LM_TRY_ENABLE_CFLAG], [ - AC_MSG_CHECKING([if we can add $1 to $2 (via CFLAGS)]) - saved_CFLAGS=$CFLAGS; - CFLAGS="$1 $$2"; - AC_TRY_COMPILE([],[return 0;],can_enable_flag=true,can_enable_flag=false) - CFLAGS=$saved_CFLAGS; - if test "X$can_enable_flag" = "Xtrue"; then - AC_MSG_RESULT([yes]) - AS_VAR_SET($2, "$1 $$2") - else - AC_MSG_RESULT([no]) - fi -]) - -dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY -dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a -dnl AC_LANG_JAVA instead...) -AC_DEFUN(ERL_TRY_LINK_JAVA, -[java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(, )dnl -cat > conftest.java <<EOF -$1 -class conftest { public static void main(String[] args) { - $2 - ; return; }} -EOF -changequote([, ])dnl -if AC_TRY_EVAL(java_link) && test -s conftest.class; then - ifelse([$3], , :, [rm -rf conftest* - $3]) -else - echo "configure: failed program was:" 1>&AC_FD_CC - cat conftest.java 1>&AC_FD_CC - echo "configure: PATH was $PATH" 1>&AC_FD_CC -ifelse([$4], , , [ rm -rf conftest* - $4 -])dnl -fi -rm -f conftest*]) -#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ - - diff --git a/lib/wx/autoconf/config.guess b/lib/wx/autoconf/config.guess deleted file mode 100755 index f475ceb413..0000000000 --- a/lib/wx/autoconf/config.guess +++ /dev/null @@ -1,1534 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to [email protected]. - - -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 1992-2013 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - 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 ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <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:*:[4567]) - 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 -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <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:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-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 ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </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 i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <[email protected]> - 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*) - # From [email protected]. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From [email protected]. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From [email protected]. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - 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 ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -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/wx/autoconf/config.sub b/lib/wx/autoconf/config.sub deleted file mode 100755 index bb6edbdb47..0000000000 --- a/lib/wx/autoconf/config.sub +++ /dev/null @@ -1,1789 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-02-12' - -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to [email protected]. -# -# 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. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# 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 1992-2013 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-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - 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 | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -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 \ - | aarch64 | aarch64_be \ - | 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[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-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-* \ - | aarch64-* | aarch64_be-* \ - | 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-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | 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-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - 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-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - 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 - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - 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 | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - 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 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - 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 - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -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* | -es*) - # 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 - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -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 - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - 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 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or1k-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: - diff --git a/lib/wx/autoconf/install-sh b/lib/wx/autoconf/install-sh deleted file mode 100755 index f694552bc2..0000000000 --- a/lib/wx/autoconf/install-sh +++ /dev/null @@ -1,258 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# 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. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -srcxtra="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - if [ $# -ne 1 ]; then - srcxtra="$srcxtra $1" - fi - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -srcxtra="$src $srcxtra" -src="" -dstsave=$dst - -if [ x"$dir_arg" != x ]; then - srcxtra="$srcxtra $dst" -fi - -# Now loop over $srcxtra - -for src in $srcxtra ; do - -dst=$dstsave - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# 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 $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi - -done && - - -exit 0 diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index 5a9c53e3b6..52087398e7 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -31,6 +31,35 @@ <p>This document describes the changes made to the wxErlang application.</p> +<section><title>Wx 1.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a minor typo in the graphicsContext example.</p> + <p> + Own Id: OTP-12259</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Distribute <c>autoconf</c> helpers to applications at + build time instead of having multiple identical copies + committed in the repository.</p> + <p> + Own Id: OTP-12348</p> + </item> + </list> + </section> + +</section> + <section><title>Wx 1.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/examples/demo/ex_graphicsContext.erl b/lib/wx/examples/demo/ex_graphicsContext.erl index 59bfe7ff64..9047f1d135 100644 --- a/lib/wx/examples/demo/ex_graphicsContext.erl +++ b/lib/wx/examples/demo/ex_graphicsContext.erl @@ -54,7 +54,7 @@ do_init(Config) -> %% Setup sizers MainSizer = wxBoxSizer:new(?wxVERTICAL), Sizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel, - [{label, "wxGrapicsContext"}]), + [{label, "wxGraphicsContext"}]), Win = wxPanel:new(Panel, []), Pen = ?wxBLACK_PEN, diff --git a/lib/wx/src/wxe_server.erl b/lib/wx/src/wxe_server.erl index 465b9da2e0..153e2475ba 100644 --- a/lib/wx/src/wxe_server.erl +++ b/lib/wx/src/wxe_server.erl @@ -223,14 +223,18 @@ handle_connect(Object, #evh{handler=undefined, cb=Callback} = EvData0, Error -> {reply, Error, State0} end; -handle_connect(Object, EvData=#evh{handler=Handler}, +handle_connect(Object, EvData=#evh{handler=Handler}, From, State0 = #state{users=Users}) -> %% Correct process is already listening just register it put(Handler, From), - User0 = #user{events=Listeners0} = gb_trees:get(From, Users), - User = User0#user{events=[{Object,EvData}|Listeners0]}, - State = State0#state{users=gb_trees:update(From, User, Users)}, - {reply, ok, State}. + case gb_trees:lookup(From, Users) of + {value, User0 = #user{events=Listeners0}} -> + User = User0#user{events=[{Object,EvData}|Listeners0]}, + State = State0#state{users=gb_trees:update(From, User, Users)}, + {reply, ok, State}; + none -> %% We are closing up the shop + {reply, {error, terminating}, State0} + end. invoke_cb({{Ev=#wx{}, Ref=#wx_ref{}}, FunId,_}, _S) -> %% Event callbacks diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl index 076f16ba16..f9f8788d8f 100644 --- a/lib/wx/test/wx_event_SUITE.erl +++ b/lib/wx/test/wx_event_SUITE.erl @@ -336,12 +336,14 @@ connect_in_callback(Config) -> end}]), wxWindow:show(F1), receive - {continue, F1} -> Tester ! {continue, F1} + {continue, F1} -> + true = wxFrame:disconnect(F1, size), + Tester ! {continue, F1} end end, - wxFrame:connect(Frame,size, + wxFrame:connect(Frame,show, [{callback, - fun(#wx{event=#wxSize{}},_SizeEv) -> + fun(#wx{event=#wxShow{}},_SizeEv) -> io:format("Frame got size~n",[]), spawn(TestWindow) end}]), diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 24e8c2ed11..78c24ec093 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 1.3.1 +WX_VSN = 1.3.2 @@ -260,62 +260,32 @@ create_lib_configure_in() } } -find_sum() +distribute_config_helpers () { - candidates="sum cksum md5sum sha1sum" - SUM_CMD="wc" - for x in $candidates; do - if (echo foo | $x > /dev/null 2>&1); then - SUM_CMD=$x - break - fi - done -} - -chk_eq() -{ - master=$1 - shift - slaves="$@" - master_sum=`$SUM_CMD $master | awk '{print $1}'` - for x in $slaves; do - s=`$SUM_CMD $x | awk '{print $1}'` - if test "$s" != "$master_sum"; then - echo "Error: $master and $x are not equal, make sure they are!" >&2 - echo "Maybe you would want to:" >&2 - echo "for x in $slaves; do cp $master \$x; done" >&2 - echo "? Or something else is wrong." 2>&1 - exit 2 - fi - done -} - -check_config_helpers () -{ - - aclocals="./aclocal.m4 ./lib/erl_interface/aclocal.m4 ./lib/odbc/aclocal.m4 ./lib/wx/aclocal.m4 ./lib/megaco/aclocal.m4" - install_shs="./lib/common_test/priv/auxdir/install-sh ./lib/erl_interface/src/auxdir/install-sh ./lib/test_server/src/install-sh" - config_guesses="./lib/common_test/priv/auxdir/config.guess ./lib/erl_interface/src/auxdir/config.guess ./lib/test_server/src/config.guess" - config_subs="./lib/common_test/priv/auxdir/config.sub ./lib/erl_interface/src/auxdir/config.sub ./lib/test_server/src/config.sub" + aclocal_dirs=". ./lib/erl_interface ./lib/odbc ./lib/wx ./lib/megaco" + autoconf_aux_dirs="./lib/common_test/priv/auxdir ./lib/erl_interface/src/auxdir ./lib/test_server/src ./lib/wx/autoconf" aclocal_master="./erts/aclocal.m4" install_sh_master="./erts/autoconf/install-sh" config_guess_master="./erts/autoconf/config.guess" config_sub_master="./erts/autoconf/config.sub" - find_sum - - chk_eq $aclocal_master $aclocals - chk_eq $install_sh_master $install_shs - chk_eq $config_guess_master $config_guesses - chk_eq $config_sub_master $config_subs + for dir in $aclocal_dirs; do + $install_sh_master -m 644 -t "$dir" "$aclocal_master" + done + for dir in $autoconf_aux_dirs; do + $install_sh_master -d "$dir" + $install_sh_master -t "$dir" "$install_sh_master" + $install_sh_master -t "$dir" "$config_guess_master" + $install_sh_master -t "$dir" "$config_sub_master" + done } do_autoconf () { create_lib_configure_in - check_config_helpers + distribute_config_helpers if target_contains win32; then # Select the correct autoconf on cygwin diff --git a/otp_versions.table b/otp_versions.table index 0387b0d0e4..41c05e79d8 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,7 @@ +OTP-17.4.1 : erts-6.3.1 inets-5.10.5 # asn1-3.0.3 common_test-1.9 compiler-5.0.3 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4.2 debugger-4.0.2 dialyzer-2.7.3 diameter-1.8 edoc-0.7.16 eldap-1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.2 ic-4.3.6 jinterface-1.5.12 kernel-3.1 megaco-3.17.3 mnesia-4.12.4 observer-2.0.3 odbc-2.10.22 orber-3.7.1 os_mon-2.3 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.22.1 reltool-0.6.6 runtime_tools-1.8.15 sasl-2.4.1 snmp-5.1.1 ssh-3.1 ssl-5.3.8 stdlib-2.3 syntax_tools-1.6.17 test_server-3.7.2 tools-2.7.1 typer-0.9.8 webtool-0.8.10 wx-1.3.2 xmerl-1.3.7 : +OTP-17.4 : asn1-3.0.3 common_test-1.9 compiler-5.0.3 crypto-3.4.2 debugger-4.0.2 dialyzer-2.7.3 diameter-1.8 edoc-0.7.16 eldap-1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.3 eunit-2.2.9 hipe-3.11.2 inets-5.10.4 jinterface-1.5.12 kernel-3.1 megaco-3.17.3 mnesia-4.12.4 observer-2.0.3 odbc-2.10.22 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 runtime_tools-1.8.15 snmp-5.1.1 ssh-3.1 ssl-5.3.8 stdlib-2.3 syntax_tools-1.6.17 test_server-3.7.2 tools-2.7.1 wx-1.3.2 # cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 et-1.5 gs-1.5.16 ic-4.3.6 orber-3.7.1 os_mon-2.3 ose-1.0.2 public_key-0.22.1 reltool-0.6.6 sasl-2.4.1 typer-0.9.8 webtool-0.8.10 xmerl-1.3.7 : +OTP-17.3.4 : erts-6.2.1 # asn1-3.0.2 common_test-1.8.2 compiler-5.0.2 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4.1 debugger-4.0.1 dialyzer-2.7.2 diameter-1.7.1 edoc-0.7.15 eldap-1.0.4 erl_docgen-0.3.6 erl_interface-3.7.19 et-1.5 eunit-2.2.8 gs-1.5.16 hipe-3.11.1 ic-4.3.6 inets-5.10.3 jinterface-1.5.11 kernel-3.0.3 megaco-3.17.2 mnesia-4.12.3 observer-2.0.2 odbc-2.10.21 orber-3.7.1 os_mon-2.3 ose-1.0.2 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22.1 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4.1 snmp-5.1 ssh-3.0.8 ssl-5.3.7 stdlib-2.2 syntax_tools-1.6.16 test_server-3.7.1 tools-2.7 typer-0.9.8 webtool-0.8.10 wx-1.3.1 xmerl-1.3.7 : +OTP-17.3.3 : ssh-3.0.8 # asn1-3.0.2 common_test-1.8.2 compiler-5.0.2 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4.1 debugger-4.0.1 dialyzer-2.7.2 diameter-1.7.1 edoc-0.7.15 eldap-1.0.4 erl_docgen-0.3.6 erl_interface-3.7.19 erts-6.2 et-1.5 eunit-2.2.8 gs-1.5.16 hipe-3.11.1 ic-4.3.6 inets-5.10.3 jinterface-1.5.11 kernel-3.0.3 megaco-3.17.2 mnesia-4.12.3 observer-2.0.2 odbc-2.10.21 orber-3.7.1 os_mon-2.3 ose-1.0.2 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22.1 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4.1 snmp-5.1 ssl-5.3.7 stdlib-2.2 syntax_tools-1.6.16 test_server-3.7.1 tools-2.7 typer-0.9.8 webtool-0.8.10 wx-1.3.1 xmerl-1.3.7 : OTP-17.3.2 : ssh-3.0.7 ssl-5.3.7 # asn1-3.0.2 common_test-1.8.2 compiler-5.0.2 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4.1 debugger-4.0.1 dialyzer-2.7.2 diameter-1.7.1 edoc-0.7.15 eldap-1.0.4 erl_docgen-0.3.6 erl_interface-3.7.19 erts-6.2 et-1.5 eunit-2.2.8 gs-1.5.16 hipe-3.11.1 ic-4.3.6 inets-5.10.3 jinterface-1.5.11 kernel-3.0.3 megaco-3.17.2 mnesia-4.12.3 observer-2.0.2 odbc-2.10.21 orber-3.7.1 os_mon-2.3 ose-1.0.2 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22.1 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4.1 snmp-5.1 stdlib-2.2 syntax_tools-1.6.16 test_server-3.7.1 tools-2.7 typer-0.9.8 webtool-0.8.10 wx-1.3.1 xmerl-1.3.7 : OTP-17.3.1 : eldap-1.0.4 erl_interface-3.7.19 jinterface-1.5.11 orber-3.7.1 ose-1.0.2 ssh-3.0.6 # asn1-3.0.2 common_test-1.8.2 compiler-5.0.2 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.4.1 debugger-4.0.1 dialyzer-2.7.2 diameter-1.7.1 edoc-0.7.15 erl_docgen-0.3.6 erts-6.2 et-1.5 eunit-2.2.8 gs-1.5.16 hipe-3.11.1 ic-4.3.6 inets-5.10.3 kernel-3.0.3 megaco-3.17.2 mnesia-4.12.3 observer-2.0.2 odbc-2.10.21 os_mon-2.3 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 public_key-0.22.1 reltool-0.6.6 runtime_tools-1.8.14 sasl-2.4.1 snmp-5.1 ssl-5.3.6 stdlib-2.2 syntax_tools-1.6.16 test_server-3.7.1 tools-2.7 typer-0.9.8 webtool-0.8.10 wx-1.3.1 xmerl-1.3.7 : OTP-17.3 : asn1-3.0.2 common_test-1.8.2 compiler-5.0.2 crypto-3.4.1 dialyzer-2.7.2 diameter-1.7.1 edoc-0.7.15 erl_docgen-0.3.6 erl_interface-3.7.18 erts-6.2 eunit-2.2.8 hipe-3.11.1 ic-4.3.6 inets-5.10.3 jinterface-1.5.10 kernel-3.0.3 megaco-3.17.2 mnesia-4.12.3 observer-2.0.2 odbc-2.10.21 os_mon-2.3 ose-1.0.1 public_key-0.22.1 sasl-2.4.1 snmp-5.1 ssh-3.0.5 ssl-5.3.6 stdlib-2.2 tools-2.7 wx-1.3.1 # cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 debugger-4.0.1 eldap-1.0.3 et-1.5 gs-1.5.16 orber-3.7 otp_mibs-1.0.9 parsetools-2.0.11 percept-0.8.9 reltool-0.6.6 runtime_tools-1.8.14 syntax_tools-1.6.16 test_server-3.7.1 typer-0.9.8 webtool-0.8.10 xmerl-1.3.7 : diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml index ba8a88d1c2..9d1e2c8669 100644 --- a/system/doc/design_principles/release_handling.xml +++ b/system/doc/design_principles/release_handling.xml @@ -310,7 +310,7 @@ the following instruction is used:</p> <code type="none"> {apply, {M, F, A}}</code> - <p>The release handler will evalute <c>apply(M, F, A)</c>.</p> + <p>The release handler will evaluate <c>apply(M, F, A)</c>.</p> </section> <section> @@ -350,7 +350,7 @@ possible.</p> </warning> <p>An info report is written when the upgrade is completed. To - programatically find out if the upgrade is complete, + programmatically find out if the upgrade is complete, call <c>release_handler:which_releases(current)</c> and check if it returns the expected (i.e. the new) release.</p> <p>The new release version must be made permanent when the new diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml index 6f85b029eb..86951e2dcc 100644 --- a/system/doc/efficiency_guide/processes.xml +++ b/system/doc/efficiency_guide/processes.xml @@ -186,7 +186,7 @@ kilo_byte(0, Acc) -> kilo_byte(N, Acc) -> kilo_byte(N-1, [Acc|Acc]).</code> - <p><c>kilo_byte/1</c> creates a deep list. If we call + <p><c>kilo_byte/0</c> creates a deep list. If we call <c>list_to_binary/1</c>, we can convert the deep list to a binary of 1024 bytes:</p> diff --git a/system/doc/efficiency_guide/tablesDatabases.xml b/system/doc/efficiency_guide/tablesDatabases.xml index 5b0df76371..94c921fa1c 100644 --- a/system/doc/efficiency_guide/tablesDatabases.xml +++ b/system/doc/efficiency_guide/tablesDatabases.xml @@ -136,7 +136,7 @@ print_person(PersonId) -> io:format("No person with ID = ~p~n", [PersonID]) end. -%%% Internal functionss +%%% Internal functions print_name(PersonID) -> [Person] = ets:lookup(person, PersonId), io:format("No person ~p~n", [Person#person.name]). diff --git a/system/doc/getting_started/conc_prog.xml b/system/doc/getting_started/conc_prog.xml index e392287ff0..2b64826a93 100644 --- a/system/doc/getting_started/conc_prog.xml +++ b/system/doc/getting_started/conc_prog.xml @@ -95,7 +95,7 @@ goodbye</pre> the second a "goodbye", the first another "hello" and so forth. But where did the <0.63.0> come from? The return value of a function is of course the return value of the last "thing" in - the function. The last thing in the function <c>start</c> is</p> + the function. The last thing in the function <c>start</c> is:</p> <code type="none"> spawn(tut14, say_something, [goodbye, 3]).</code> <p><c>spawn</c> returns a <em>process identifier</em>, or @@ -166,11 +166,11 @@ Pong_PID = spawn(tut15, pong, [])</code> <c>start</c> now creates another process "ping".</p> <code type="none"> spawn(tut15, ping, [3, Pong_PID]),</code> - <p>this process executes</p> + <p>This process executes:</p> <code type="none"> tut15:ping(3, Pong_PID)</code> <p><0.36.0> is the return value from the <c>start</c> function.</p> - <p>The process "pong" now does:</p> + <p>The process "pong" now does:</p> <code type="none"> receive finished -> @@ -235,7 +235,7 @@ Ping_PID ! pong</code> Pid ! Message</code> <p>I.e. <c>Message</c> (any Erlang term) is sent to the process with identity <c>Pid</c>.</p> - <p>After sending the message <c>pong</c>, to the process "ping", + <p>After sending the message <c>pong</c> to the process "ping", "pong" calls the <c>pong</c> function again, which causes it to get back to the <c>receive</c> again and wait for another message. Now let's look at the process "ping". Recall that it was started @@ -253,7 +253,7 @@ Pong_PID ! {ping, self()},</code> <p><c>self()</c> returns the pid of the process which executes <c>self()</c>, in this case the pid of "ping". (Recall the code for "pong", this will land up in the variable <c>Ping_PID</c> in - the <c>receive</c> previously explained).</p> + the <c>receive</c> previously explained.)</p> <p>"Ping" now waits for a reply from "pong":</p> <code type="none"> receive @@ -352,8 +352,8 @@ pong ! {ping, self()},</code> on different computers. Before we do this, there are a few things we need to set up to get this to work. The distributed Erlang implementation provides a basic security mechanism to prevent - unauthorized access to an Erlang system on another computer - (*manual*). Erlang systems which talk to each other must have + unauthorized access to an Erlang system on another computer. + Erlang systems which talk to each other must have the same <em>magic cookie</em>. The easiest way to achieve this is by having a file called <c>.erlang.cookie</c> in your home directory on all machines which on which you are going to run @@ -363,8 +363,8 @@ pong ! {ping, self()},</code> you can safely ignore this and simply create a file called <c>.erlang.cookie</c> in the directory you get to after executing the command <c>cd</c> without any argument). - The <c>.erlang.cookie</c> file should contain on line with - the same atom. For example on Linux or Unix in the OS shell:</p> + The <c>.erlang.cookie</c> file should contain one line with + the same atom. For example, on Linux or Unix in the OS shell:</p> <pre> $ <input>cd</input> $ <input>cat > .erlang.cookie</input> @@ -373,10 +373,10 @@ $ <input>chmod 400 .erlang.cookie</input></pre> <p>The <c>chmod</c> above make the <c>.erlang.cookie</c> file accessible only by the owner of the file. This is a requirement.</p> <p>When you start an Erlang system which is going to talk to other - Erlang systems, you must give it a name, eg: </p> + Erlang systems, you must give it a name, e.g.: </p> <pre> $ <input>erl -sname my_name</input></pre> - <p>We will see more details of this later (*manual*). If you want to + <p>We will see more details of this later. If you want to experiment with distributed Erlang, but you only have one computer to work on, you can start two separate Erlang systems on the same computer but give them different names. Each Erlang @@ -385,7 +385,7 @@ $ <input>erl -sname my_name</input></pre> IP domain and we can use only the first component of the IP address, if we want to use nodes in different domains we use <c>-name</c> instead, but then all IP address must be given in - full (*manual*).</p> + full.)</p> <p>Here is the ping pong example modified to run on two separate nodes:</p> <code type="none"> @@ -538,9 +538,9 @@ ping finished</pre> <p>Before we start, let's note the following:</p> <list type="bulleted"> <item> - <p>This example will just show the message passing logic no + <p>This example will just show the message passing logic - no attempt at all has been made to provide a nice graphical user - interface - this can of course also be done in Erlang - but + interface. This can, of course, also be done in Erlang - but that's another tutorial.</p> </item> <item> @@ -550,8 +550,8 @@ ping finished</pre> tutorial.</p> </item> <item> - <p>The first program we write will contain some inadequacies as - regards handling of nodes which disappear, we will correct + <p>The first program we write will contain some inadequacies + regarding the handling of nodes which disappear. We will correct these in a later version of the program.</p> </item> </list> @@ -571,7 +571,7 @@ ping finished</pre> %%% already logged in at the same node, login will be rejected %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this %%% function is not logged on or if ToName is not logged on at @@ -734,11 +734,11 @@ await_result() -> <item>copy the compiled code (<c>messenger.beam</c>) to the directory on each computer where you start Erlang.</item> </list> - <p>In the following example of use of this program, I have started + <p>In the following example of use of this program I have started nodes on four different computers, but if you don't have that - many machines available on your network, you could start up + many machines available on your network you could start up several nodes on the same machine.</p> - <p>We start up four Erlang nodes, messenger@super, c1@bilbo, + <p>We start up four Erlang nodes: messenger@super, c1@bilbo, c2@kosken, c3@gollum.</p> <p>First we start up a the server at messenger@super:</p> <pre> @@ -780,19 +780,19 @@ ok receiver_not_found</pre> <p>But this fails as Fred has already logged off.</p> <p>First let's look at some of the new concepts we have introduced.</p> - <p>There are two versions of the <c>server_transfer</c> function, + <p>There are two versions of the <c>server_transfer</c> function: one with four arguments (<c>server_transfer/4</c>) and one with five (<c>server_transfer/5</c>). These are regarded by Erlang as two separate functions.</p> <p>Note how we write the <c>server</c> function so that it calls - itself, <c>server(User_List)</c> and thus creates a loop. + itself, via <c>server(User_List)</c>, and thus creates a loop. The Erlang compiler is "clever" and optimizes the code so that this really is a sort of loop and not a proper function call. But this only works if there is no code after the call, otherwise the compiler will expect the call to return and make a proper function call. This would result in the process getting bigger and bigger for every loop.</p> - <p>We use functions in the <c>lists</c> module. This is a very + <p>We use functions from the <c>lists</c> module. This is a very useful module and a study of the manual page is recommended (<c>erl -man lists</c>). <c>lists:keymember(Key,Position,Lists)</c> looks through a list diff --git a/system/doc/getting_started/records_macros.xml b/system/doc/getting_started/records_macros.xml index 76e3d185fb..73c8ce5c8d 100644 --- a/system/doc/getting_started/records_macros.xml +++ b/system/doc/getting_started/records_macros.xml @@ -97,7 +97,7 @@ %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this @@ -284,7 +284,7 @@ server_transfer(From, Name, To, Message, User_List) -> the record is referred to. If you leave out a field when creating a record, it will get the value of the atom undefined. (*manual*)</p> <p>Pattern matching with records is very similar to creating - records. For example inside a <c>case</c> or <c>receive</c>:</p> + records. For example, inside a <c>case</c> or <c>receive</c>:</p> <code type="none"> #message_to{to_name=ToName, message=Message} -></code> <p>is the same as:</p> diff --git a/system/doc/getting_started/robustness.xml b/system/doc/getting_started/robustness.xml index 359ea93275..e8fb81d5e8 100644 --- a/system/doc/getting_started/robustness.xml +++ b/system/doc/getting_started/robustness.xml @@ -30,7 +30,7 @@ </header> <p>There are several things which are wrong with the <seealso marker="conc_prog#ex">messenger example</seealso> from - the previous chapter. For example if a node where a user is logged + the previous chapter. For example, if a node where a user is logged on goes down without doing a log off, the user will remain in the server's <c>User_List</c> but the client will disappear thus making it impossible for the user to log on again as the server @@ -214,9 +214,9 @@ Ping received pong</pre> signal to be sent to "pong" which will also terminate.</p> <p>It is possible to modify the default behaviour of a process so that it does not get killed when it receives abnormal exit - signals, but all signals will be turned into normal messages on + signals, but all signals will be turned into normal messages with the format <c>{'EXIT',FromPID,Reason}</c> and added to the end of - the receiving processes message queue. This behaviour is set by:</p> + the receiving process' message queue. This behaviour is set by:</p> <code type="none"> process_flag(trap_exit, true)</code> <p>There are several other process flags, see @@ -289,7 +289,7 @@ pong exiting, got {'EXIT',<3820.39.0>,ping}</pre> %%% already logged in at the same node, login will be rejected %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this %%% function is not logged on or if ToName is not logged on at diff --git a/system/doc/getting_started/seq_prog.xml b/system/doc/getting_started/seq_prog.xml index fd49102263..699b9487ed 100644 --- a/system/doc/getting_started/seq_prog.xml +++ b/system/doc/getting_started/seq_prog.xml @@ -31,14 +31,14 @@ <section> <title>The Erlang Shell</title> - <p>Most operating systems have a command interpreter or shell, Unix - and Linux have many, Windows has the Command Prompt. Erlang has + <p>Most operating systems have a command interpreter or shell- Unix + and Linux have many, while Windows has the Command Prompt. Erlang has its own shell where you can directly write bits of Erlang code and evaluate (run) them to see what happens (see <seealso marker="stdlib:shell">shell(3)</seealso>). Start the Erlang shell (in Linux or UNIX) by starting a shell or command interpreter in your operating system and typing - <c>erl</c>, you will see something like this.</p> + <c>erl</c>. You will see something like this.</p> <pre> % <input>erl</input> Erlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] @@ -62,7 +62,7 @@ Eshell V5.9.1 (abort with ^G) (See the chapter <seealso marker="erts:tty">"tty - A command line interface"</seealso> in ERTS User's Guide).</p> <p>(Note: you will find a lot of line numbers given by the shell out of sequence in this tutorial as it was written and the code - tested in several sessions).</p> + tested in several sessions.)</p> <p>Now let's try a more complex calculation.</p> <pre> 2> <input>(42 + 77) * 66 / 3.</input> @@ -115,7 +115,7 @@ double(X) -> entered and there will also be error messages to give you some idea as to what has gone wrong so you can change what you have written and try again.</p> - <p>Now lets run the program.</p> + <p>Now let's run the program.</p> <pre> 4> <input>tut:double(10).</input> 20</pre> @@ -208,7 +208,7 @@ mult(X, Y) -> called variables. Variables must start with a capital letter (see the chapter <seealso marker="doc/reference_manual:expressions">"Variables"</seealso> - in the Erlang Reference Manual). Examples of variable could be + in the Erlang Reference Manual). Examples of variables could be <c>Number</c>, <c>ShoeSize</c>, <c>Age</c> etc.</p> </section> @@ -271,7 +271,7 @@ convert(N, centimeter) -> Consider:</p> <code type="none"> tut2:convert(3, inch).</code> - <p>Does this mean that 3 is in inches? or that 3 is in centimeters + <p>Does this mean that 3 is in inches? Or that 3 is in centimeters and we want to convert it to inches? So Erlang has a way to group things together to make things more understandable. We call these <em>tuples</em>. Tuples are surrounded by "{" and "}".</p> @@ -309,7 +309,7 @@ convert_length({inch, Y}) -> <p>We have shown tuples with two parts above, but tuples can have as many parts as we want and contain any valid Erlang <em>term</em>. For example, to represent the temperature of - various cities of the world we could write</p> + various cities of the world we could write:</p> <code type="none"> {moscow, {c, -10}} {cape_town, {f, 70}} @@ -325,7 +325,7 @@ convert_length({inch, Y}) -> <title>Lists</title> <p>Whereas tuples group things together, we also want to be able to represent lists of things. Lists in Erlang are surrounded by "[" - and "]". For example a list of the temperatures of various cities + and "]". For example, a list of the temperatures of various cities in the world could be:</p> <code type="none"> [{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}}, @@ -345,7 +345,7 @@ convert_length({inch, Y}) -> [2,3,4,5]</pre> <p>We use | to separate the first elements of the list from the rest of the list. (<c>First</c> has got value 1 and - <c>TheRest</c> value [2,3,4,5]).</p> + <c>TheRest</c> value [2,3,4,5].)</p> <p>Another example:</p> <pre> 20> <input>[E1, E2 | R] = [1,2,3,4,5,6,7].</input> @@ -403,7 +403,7 @@ list_length([First | Rest]) -> the remaining elements <c>Rest</c> is 1 + the length of <c>Rest</c>.</p> <p>(Advanced readers only: This is not tail recursive, there is a - better way to write this function).</p> + better way to write this function.)</p> <p>In general we can say we use tuples where we would use "records" or "structs" in other languages and we use lists when we want to represent things which have varying sizes, (i.e. where we would @@ -481,7 +481,7 @@ blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) -> > <input>color:blend(C2,C1).</input> #{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51} </pre> - <p>This example warrant some explanation:</p> + <p>This example warrants some explanation:</p> <code type="none"> -define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).</code> <p> @@ -573,10 +573,9 @@ http://www.erlang.org/doc/r9b/doc/index.html</code> <section> <title>Writing Output to a Terminal</title> <p>It's nice to be able to do formatted output in these example, so - the next example shows a simple way to use to use - the <c>io:format</c> function. Of course, just like all other - exported functions, you can test the <c>io:format</c> function in - the shell:</p> + the next example shows a simple way to use the <c>io:format</c> + function. Of course, just like all other exported functions, you + can test the <c>io:format</c> function in the shell:</p> <pre> 31> <input>io:format("hello world~n", []).</input> hello world @@ -673,7 +672,7 @@ ok</pre> <p>Now we call <c>format_temps(Rest)</c> with the rest of the list as an argument. This way of doing things is similar to the loop constructs in other languages. (Yes, this is recursion, but don't - let that worry you). So the same <c>format_temps</c> function is + let that worry you.) So the same <c>format_temps</c> function is called again, this time <c>City</c> gets the value <c>{cape_town,{f,70}}</c> and we repeat the same procedure as before. We go on doing this until the list becomes empty, i.e. [], @@ -737,12 +736,12 @@ list_max([Head|Rest], Result_so_far) -> the next part of the function.</p> <p>Some useful operators in guards are, < less than, > greater than, == equal, >= greater or equal, =< less or - equal, /= not equal. (see the chapter - <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual).</p> + equal, /= not equal. (See the chapter + <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual.)</p> <p>To change the above program to one which works out the minimum value of the element in a list, all we would need to do is to write < instead of >. (But it would be wise to change - the name of the function to <c>list_min</c> :-).</p> + the name of the function to <c>list_min</c> :-).)</p> <p>Remember that I mentioned earlier that a variable could only be given a value once in its scope? In the above we see, for example, that <c>Result_so_far</c> has been given several values. This is @@ -846,7 +845,7 @@ reverse([], [3,2,1]) => write a list manipulating function it is a good idea to check that one isn't already written for you. (see <seealso marker="stdlib:lists">lists(3)</seealso>).</p> - <p>Now lets get back to the cities and temperatures, but take a more + <p>Now let's get back to the cities and temperatures, but take a more structured approach this time. First let's convert the whole list to Celsius as follows and test the function:</p> <code type="none"> @@ -890,7 +889,7 @@ format_temps(List_of_cities) -> <code type="none"> [City | convert_list_to_c(Rest)];</code> <p>We go on doing this until we get to the end of the list (i.e. - the list is empty:</p> + the list is empty):</p> <code type="none"> convert_list_to_c([]) -> [].</code> @@ -1152,13 +1151,13 @@ month_length(Year, Month) -> <section> <title>Built In Functions (BIFs)</title> - <p>Built in functions BIFs are functions which for some reason is + <p>Built in functions (BIFs) are functions which for some reason are built in to the Erlang virtual machine. BIFs often implement functionality that is impossible to implement in Erlang or is too inefficient to implement in Erlang. Some BIFs can be called - by use of the function name only but they are by default belonging - to the erlang module so for example the call to the BIF <c>trunc</c> - below is equivalent with a call to <c>erlang:trunc</c>.</p> + by use of the function name only, but they by default belong + to the erlang module. So for example, the call to the BIF <c>trunc</c> + below is equivalent to a call to <c>erlang:trunc</c>.</p> <p>As you can see, we first find out if a year is leap or not. If a year is divisible by 400, it is a leap year. To find this out we first divide the year by 400 and use the built in function @@ -1175,23 +1174,23 @@ trunc(5.01) = 5 2000 / 400 = 5.0 trunc(5.0) = 5 5 * 400 = 2000</code> - <p>so we have a leap year. The next two tests if the year is - divisible by 100 or 4 are done in the same way. The first - <c>if</c> returns <c>leap</c> or <c>not_leap</c> which lands up + <p>so we have a leap year. The next two tests, which check if the year is + divisible by 100 or 4, are done in the same way. The first + <c>if</c> returns <c>leap</c> or <c>not_leap</c> which ends up in the variable <c>Leap</c>. We use this variable in the guard for <c>feb</c> in the following <c>case</c> which tells us how long the month is.</p> - <p>This example showed the use of <c>trunc</c>, an easier way would - be to use the Erlang operator <c>rem</c> which gives the remainder + <p>This example showed the use of <c>trunc</c>. An easier way would + be to use the Erlang operator <c>rem</c>, which gives the remainder after division. For example:</p> <pre> 74> <input>2004 rem 400.</input> 4</pre> - <p>so instead of writing</p> + <p>so instead of writing:</p> <code type="none"> trunc(Year / 400) * 400 == Year -> leap;</code> - <p>we could write</p> + <p>we could write:</p> <code type="none"> Year rem 400 == 0 -> leap;</code> @@ -1201,7 +1200,7 @@ Year rem 400 == 0 -> (see the chapter <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual) (Aside for advanced readers: This is to ensure that guards don't have side - effects). Let's play with a few of these functions in the shell:</p> + effects.) Let's play with a few of these functions in the shell:</p> <pre> 75> <input>trunc(5.6).</input> 5 @@ -1268,7 +1267,7 @@ map(Fun, []) -> #Fun<erl_eval.5.123085357> 89> <input>lists:map(Add_3, [1,2,3]).</input> [4,5,6]</pre> - <p>Now lets print out the temperatures in a list of cities (yet + <p>Now let's print out the temperatures in a list of cities (yet again):</p> <pre> 90> <input>Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",</input> diff --git a/system/doc/programming_examples/fun_test.erl b/system/doc/programming_examples/fun_test.erl index 8472fd87f8..8a3b0106c0 100644 --- a/system/doc/programming_examples/fun_test.erl +++ b/system/doc/programming_examples/fun_test.erl @@ -1,17 +1,11 @@ %1 -module(fun_test). --export([t1/0, t2/0, t3/0, t4/0, double/1]). +-export([t1/0, t2/0]). -import(lists, [map/2]). t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]). t2() -> map(fun double/1, [1,2,3,4,5]). -t3() -> map({?MODULE, double}, [1,2,3,4,5]). - double(X) -> X * 2. %1 - - -t4() -> - "hello world". diff --git a/system/doc/reference_manual/character_set.xml b/system/doc/reference_manual/character_set.xml index 884898eb34..b09b484582 100644 --- a/system/doc/reference_manual/character_set.xml +++ b/system/doc/reference_manual/character_set.xml @@ -101,9 +101,10 @@ <tcaption>Character Classes.</tcaption> </table> <p>In Erlang/OTP R16B the syntax of Erlang tokens was extended to - handle Unicode. To begin with the support is limited to - strings, but Erlang/OTP 18 is expected to handle Unicode atoms - as well. More about the usage of Unicode in Erlang source files + handle Unicode. The support is limited to + string literals and comments. Atoms, module names, and + function names are restricted to the ISO-Latin-1 range. + More about the usage of Unicode in Erlang source files can be found in <seealso marker="stdlib:unicode_usage#unicode_in_erlang">STDLIB's User's Guide</seealso>.</p> diff --git a/system/doc/reference_manual/data_types.xml b/system/doc/reference_manual/data_types.xml index 37c0db5ff7..ad92143179 100644 --- a/system/doc/reference_manual/data_types.xml +++ b/system/doc/reference_manual/data_types.xml @@ -44,7 +44,8 @@ <list type="bulleted"> <item><c>$</c><em><c>char</c></em> <br></br> - ASCII value of the character <em><c>char</c></em>.</item> + ASCII value or unicode code-point of the character + <em><c>char</c></em>.</item> <item><em><c>base</c></em><c>#</c><em><c>value</c></em> <br></br> Integer with the base <em><c>base</c></em>, which must be an diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml index fa8f9b2e8f..62a344ad58 100644 --- a/system/doc/reference_manual/expressions.xml +++ b/system/doc/reference_manual/expressions.xml @@ -283,7 +283,7 @@ fun lists:append/2([1,2], [3,4]) length([]) -> 0; length([H|T]) -> - 1 + length(T). %% Calls the local funtion length/1 + 1 + length(T). %% Calls the local function length/1 f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1, %% which is allowed in guards @@ -301,7 +301,7 @@ f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1, -import(mod,[length/1]). -f(X) when erlang:length(X) > 33 -> %% Calls erlang:lenght/1, +f(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1, %% which is allowed in guards erlang:length(X); %% Explicit call to erlang:length in body diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index cc35c6eb21..e4aa2ceda6 100644 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -103,7 +103,7 @@ | Map | Tuple | Union - | UserDefined %% described in Section 6.3 + | UserDefined %% described in Section 7.3 Atom :: atom() | Erlang_Atom %% 'foo', 'bar', ... @@ -217,6 +217,9 @@ <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(byte() | binary() | iolist(), binary() | [])</c></cell> </row> <row> + <cell><c>function()</c></cell><cell><c>fun()</c></cell> + </row> + <row> <cell><c>module()</c></cell><cell><c>atom()</c></cell> </row> <row> diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc index b5f8d8ac4d..a8ee2d1245 100644 --- a/system/doc/system_principles/create_target.xmlsrc +++ b/system/doc/system_principles/create_target.xmlsrc @@ -91,7 +91,7 @@ {pea, "1.0"}]}.</code> <p>The listed applications are not only original Erlang/OTP applications but possibly also new applications that you have - written yourself (here examplified by the application + written yourself (here exemplified by the application <c>pea</c>). </p> <p><em>Step 2.</em> From the directory where the <c>mysystem.rel</c> file reside, start the Erlang/OTP system:</p> @@ -251,7 +251,7 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI <c>target_system:create/1</c>. In fact, if you create, in the current directory, not only the <c>mysystem.rel</c> file, but also a <c>sys.config</c> file, that latter file will be tacitly - put in the apropriate directory.</p> + put in the appropriate directory.</p> </section> <section> @@ -408,7 +408,7 @@ heart: Tue Apr 1 12:15:11 2014: Executed "/usr/local/erl-target/bin/start /usr/ Erlang/OTP has Changed</seealso> for more infomation about this. </p> <p> - The node will be accessable via a new pipe: + The node will be accessible via a new pipe: </p> <pre> os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre> diff --git a/system/doc/system_principles/system_principles.xml b/system/doc/system_principles/system_principles.xml index 70c69b1dab..79ed86cd9f 100644 --- a/system/doc/system_principles/system_principles.xml +++ b/system/doc/system_principles/system_principles.xml @@ -109,7 +109,7 @@ init:stop()</pre> <p>Loads the code for and starts the applications Kernel and STDLIB, skips loading the <c>.erlang</c> file. Useful for scripts and other tools that should be behave the - same irregardless of user preferences. + same regardless of user preferences. </p> </item> </taglist> diff --git a/system/doc/tutorial/c_portdriver.xmlsrc b/system/doc/tutorial/c_portdriver.xmlsrc index 421ea63f33..2fd6fb0aac 100644 --- a/system/doc/tutorial/c_portdriver.xmlsrc +++ b/system/doc/tutorial/c_portdriver.xmlsrc @@ -35,7 +35,7 @@ <section> <title>Port Drivers</title> - <p>A port driver is a linked in driver, that is accessible as a + <p>A port driver is a linked in driver that is accessible as a port from an Erlang program. It is a shared library (SO in Unix, DLL in Windows), with special entry points. The Erlang runtime calls these entry points, when the driver is started and when diff --git a/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf b/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf index c245b493a5..cc6c5a9678 100644 --- a/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf +++ b/xcomp/erl-xcomp-powerpc-dso-linux-gnu.conf @@ -55,7 +55,7 @@ erl_xcomp_build=guess # It does not have to be a full `CPU-VENDOR-OS' triplet, but can be. The # full `CPU-VENDOR-OS' triplet will be created by # `$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host'. -erl_xcomp_host=powerpc-linux-gnu +erl_xcomp_host=powerpc-wrs-linux-gnu # * `erl_xcomp_configure_flags' - Extra configure flags to pass to the # `configure' script. @@ -70,10 +70,10 @@ erl_xcomp_configure_flags="--without-termcap" ## All variables in this section can also be used when native compiling. # * `CC' - C compiler. -CC=powerpc-linux-gnu-gcc +CC=powerpc-wrs-linux-gnu-gcc # * `CFLAGS' - C compiler flags. -#CFLAGS= +CFLAGS="-O2 --sysroot=/ldisk/cross/gcc-toolchain/sysroot -Wall -g" # * `STATIC_CFLAGS' - Static C compiler flags. #STATIC_CFLAGS= @@ -84,22 +84,22 @@ CC=powerpc-linux-gnu-gcc #CFLAG_RUNTIME_LIBRARY_PATH= # * `CPP' - C pre-processor. -#CPP= +CPP="powerpc-wrs-linux-gnu-cpp " # * `CPPFLAGS' - C pre-processor flags. -#CPPFLAGS= +CPPFLAGS="--sysroot=/ldisk/cross/gcc-toolchain/sysroot" # * `CXX' - C++ compiler. -CXX=powerpc-linux-gnu-g++ +CXX="powerpc-wrs-linux-gnu-g++" # * `CXXFLAGS' - C++ compiler flags. -#CXXFLAGS= +CXXFLAGS="--sysroot=/ldisk/cross/gcc-toolchain/sysroot" # * `LD' - Linker. -LD=powerpc-linux-gnu-ld +LD="powerpc-wrs-linux-gnu-gcc" # * `LDFLAGS' - Linker flags. -#LDFLAGS= +LDFLAGS="--sysroot=/ldisk/cross/gcc-toolchain/sysroot" # * `LIBS' - Libraries. #LIBS= @@ -109,14 +109,14 @@ LD=powerpc-linux-gnu-ld ## *NOTE*! Either set all or none of the `DED_LD*' variables. # * `DED_LD' - Linker for Dynamically loaded Erlang Drivers. -#DED_LD= +DED_LD="powerpc-wrs-linux-gnu-gcc" # * `DED_LDFLAGS' - Linker flags to use with `DED_LD'. -#DED_LDFLAGS= +DED_LDFLAGS="--sysroot=/ldisk/cross/gcc-toolchain/sysroot -shared -Wl,-Bsymbolic" # * `DED_LD_FLAG_RUNTIME_LIBRARY_PATH' - This flag should set runtime library # search path for shared libraries when linking with `DED_LD'. -#DED_LD_FLAG_RUNTIME_LIBRARY_PATH= +DED_LD_FLAG_RUNTIME_LIBRARY_PATH="-Wl,-R" ## -- Large File Support -- @@ -134,10 +134,10 @@ LD=powerpc-linux-gnu-ld ## -- Other Tools -- # * `RANLIB' - `ranlib' archive index tool. -RANLIB=powerpc-linux-gnu-ranlib +RANLIB=powerpc-wrs-linux-gnu-ranlib # * `AR' - `ar' archiving tool. -AR=powerpc-linux-gnu-ar +AR=powerpc-wrs-linux-gnu-ar # * `GETCONF' - `getconf' system configuration inspection tool. `getconf' is # currently used for finding out large file support flags to use, and |