diff options
82 files changed, 2307 insertions, 2043 deletions
diff --git a/HOWTO/INSTALL-WIN32.md b/HOWTO/INSTALL-WIN32.md index 79d89551c0..067c939d7a 100644 --- a/HOWTO/INSTALL-WIN32.md +++ b/HOWTO/INSTALL-WIN32.md @@ -4,82 +4,110 @@ How to Build Erlang/OTP on Windows Introduction ------------ -This file describes how to build the Erlang emulator and the OTP -libraries on Windows. The instructions apply to versions of Windows -supporting the Cygwin emulated gnuish environment for Windows or the -Msys ditto. We've built on the following platforms: Windows 2003 -server, Windows XP Home/Professional, Windows Vista and Windows 7 (32 -and 64 bit). You can probably build on Windows 2000, but you will not -be able to install the latest Microsoft SDK, so you have to go back to -some earlier compiler. Any Windows95'ish platform will surely get you -into trouble, what I'm not sure of, but it certainly will... - -The procedure described uses either Cygwin or Msys as a build -environment, you run the bash shell in Cygwin/Msys and use gnu -make/configure/autoconf etc to do the build. The emulator C-source -code is, however, mostly compiled with Microsoft Visual C++™, -producing a native Windows binary. This is the same procedure as we -use to build the pre-built binaries. The fact that we use VC++ and not -gcc is explained further in the FAQ section. - -I describe the build procedure to make it possible for open source -customers to build the emulator, given that they have the needed -tools. The binary Windows releases is still a preferred alternative if -one does not have Microsoft's development tools and/or don't want to -install Cygwin or Msys. - -To use Cygwin/Msys, one needs basic experience from a Unix environment, if -one does not know how to set environment variables, run programs etc -in a Unix environment, one will be quite lost in the Cygwin os Msys -ditto. I can unfortunately not teach all the world how to use -Cygwin and bash, neither how to install Cygwin nor perform basic tasks -on a computer. Please refer to other documentation on the net for -help, or use the binary release instead if you have problems using the -tools. - -However, if you feel comfortable with the environment and build +This section describes how to build the Erlang emulator and the OTP +libraries on Windows. Note that the Windows binary releases are still +a preferred alternative if one does not have Microsoft’s development +tools and/or don’t want to install Cygwin, MSYS or MSYS2. + +The instructions apply to versions of Windows supporting the Cygwin +emulated gnuish environment or the MSYS or MSYS2 ditto. We’ve built on +the following platforms: Windows 2012, Windows 7, Windows 8 and Windows 10. +It’s probably possible to build on older platforms too, but you might +not be able to install the appropriate Microsoft SDK, Visual Studio or +OpenSSL, in which case you will need to go back to earlier compilers etc. + +The procedure described uses either Cygwin, MSYS or MSYS2 as a build +environment. You run the bash shell in Cygwin/MSYS/MSYS2 and use the gnu +make/configure/autoconf etc to do the build. The emulator C-source code +is, however, mostly compiled with Microsoft Visual C++™, producing a +native Windows binary. This is the same procedure as we use to build the +pre-built binaries. Why we use VC++ and not gcc is explained further in +the FAQ section. + +If you are not familiar with Cygwin, MSYS, MSYS2 or a Unix environment, +you’ll probably need to read up a bit on how that works. There are plenty of +documentation about this online. + +These instructions apply for both 32-bit and 64-bit Windows. Note that even +if you build a 64-bit version of Erlang, most of the directories and files +involved are still named win32. Some occurances of the name win64 are +however present. The installation file for a 64-bit Windows version of +Erlang, for example, is `otp_win64_%OTP-REL%.exe`. + +If you feel comfortable with the environment and build system, and have all the necessary tools, you have a great opportunity to make the Erlang/OTP distribution for Windows better. Please submit -any suggestions and patches to the appropriate [mailing lists] [1] to let +any suggestions to our [JIRA] [2] and patches to our [git project] [3] to let them find their way into the next version of Erlang. If making changes to the build system (like makefiles etc) please bear in mind that the same makefiles are used on Unix/VxWorks, so that your changes -don't break other platforms. That of course goes for C-code too, system +don't break other platforms. That of course goes for C-code too; system specific code resides in the `$ERL_TOP/erts/emulator/sys/win32` and `$ERL_TOP/erts/etc/win32` directories mostly. The `$ERL_TOP/erts/emulator/beam` directory is for common code. -Before the R9C release of Erlang/OTP, the Windows release was built -partly on a Unix (Solaris) box and partly on a Windows box, using Perl -hacks to communicate and sync between the two machines. R9C was the -first release ever built solely on Windows, where no Unix machine is -needed at all. Now we've used this build procedure for a couple of +We've used this build procedure for a couple of releases, and it has worked fine for us. Still, there might be all sorts of troubles on different machines and with different -setups. I'll try to give hints wherever I've encountered difficulties, +setups. We'll try to give hints wherever we've encountered difficulties, but please share your experiences by using the [erlang-questions] [1] -mailing list. I cannot of course help everyone with all -their problems, please try to solve the problems and submit -solutions/workarounds. Remember, it's all about sharing, not about -demanding... - -Starting with R15B, our build system runs both on Cygwin and Msys -(MinGW's fork of an early cygwin version). Msys is a smaller package -to install and may on some machines run slightly faster. If Cygwin -gives you trouble, try Msys instead, and v.v. Beginning with R15B -there is also a native 64bit version of Erlang for 64bit Windows 7 -(only). These instructions apply to both the 32bit VM and the 64bit -ditto. - -Note that even if you build a 64bit VM, most of the directories and -files involved are still named win32. You can view the name win32 as -meaning any windows version not beeing 16bit. A few occurences of the -name Win64 are however present in the system, for example the -installation file for a 64 bit windows version of Erlang is by default -named `otp_win64_<version>.exe`. - -Lets go then, I'll start with a little FAQ, based on in house questions -and misunderstandings. +mailing list. We cannot, of course, help everyone with all +their issues, so please try to solve such issues and submit +solutions/workarounds. + +Lets go then! We’ll start with a short version of the setup procedure, +followed by some FAQ, and then we’ll go into more details of the setup. + + +Short Version +-------------------------- +In the following sections, we've described as much as we could about the +installation of the tools needed. Once the tools are installed, building +is quite easy. We have also tried to make these instructions understandable +for people with limited Unix experience. Cygwin/MSYS/MSYS2 is a whole new +environment to some Windows users, why careful explanation of environment +variables etc seemed to be in place. + +This is the short story though, for the experienced and impatient: + + * Get and install complete Cygwin (latest), complete MinGW with MSYS or + complete MSYS2 + + * Install Visual Studio 12.0 (2013) + + * Install Microsofts Windows SDK 8.1 + + * Get and install Sun's JDK 1.6.0 or later + + * Get and install NSIS 2.01 or later (up to 2.46 tried and working) + + * Get, build and install OpenSSL 0.9.8r or later (up to 1.0.2d + tried & working) with static libs. + + * Get the Erlang source distribution (from + <http://www.erlang.org/download.html>) and unpack with + Cygwin's/MSYS's/MSYS2's `tar`. + + * Set `ERL_TOP` to where you unpacked the source distribution + + * `$ cd $ERL_TOP` + + * Modify PATH and other environment variables so that all these tools + are runnable from a bash shell. Still standing in `$ERL_TOP`, issue + the following commands (for 32-bit Windows, remove the x64 from the + first row and change `otp_win64_%OTP-REL%` to `otp_win32_%OTP-REL%` on + the last row): + + $ eval `./otp_build env_win32 x64` + $ ./otp_build autoconf + $ ./otp_build configure + $ ./otp_build boot -a + $ ./otp_build release -a + $ ./otp_build installer_win32 + $ release/win32/otp_win64_%OTP-REL% /S + + Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang + Windows shell. Frequently Asked Questions @@ -88,12 +116,12 @@ Frequently Asked Questions * Q: So, now I can build Erlang using GCC on Windows? A: No, unfortunately not. You'll need Microsoft's Visual C++ - still, a Bourne-shell script (cc.sh) wraps the Visual C++ compiler + still. A Bourne-shell script (cc.sh) wraps the Visual C++ compiler and runs it from within the Cygwin environment. All other tools needed to build Erlang are free-ware/open source, but not the C compiler. The Windows SDK is however enough to build Erlang, you do not need to buy Visual C++, just download the SDK (SDK version - 7.1 == Visual studio 2010). + 8.1 == Visual studio 2013). * Q: Why haven't you got rid of VC++ then, you \*\*\*\*\*\*? @@ -106,18 +134,17 @@ Frequently Asked Questions mingw build will possibly be back, but as long as VC++ gives better performance, the commercial build will be a VC++ one. -* Q: OK, you need VC++, but now you've started to demand a very recent - (and expensive) version of Visual studio, not the old and stable VC++ - 6.0 that was used in earlier versions. Why? +* Q: OK, you need VC++, but now you've started to demand a quite recent + (and expensive) version of Visual Studio. Why? A: Well, it's not expensive, it's free (as in free beer). Just download and install the latest Windows SDK from Microsoft and all the tools you need are there. The included debugger (WinDbg) is - also quite usable, it's what I used when porting Erlang to 64bit - Windows. Another reason to use the latest Microsoft compilers is + also quite usable. That's what I used when porting Erlang to 64bit + Windows. Another reason to use later Microsoft compilers is DLL compatibility. DLL's using a new version of the standard library might not load if the VM is compiled with an old VC++ - version, why we should aim to use the latest freely available SDK + version. So we should aim to use the latest freely available SDK and compiler. * Q: Can/will I build a Cygwin binary with the procedure you describe? @@ -130,9 +157,7 @@ Frequently Asked Questions some problems. Fixing those problems might be easy or might be hard. I suggest you try yourself and share your experience. No one would be happier if a simple `./configure && make` would produce a fully fledged - Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so - such a port would have to happen in spare time, which is a limited - resource... + Cygwin binary. * Q: Hah, I saw you, you used GCC even though you said you didn't! @@ -142,7 +167,7 @@ Frequently Asked Questions particular file, `beam_emu.c` benefits immensely from being able to use the GCC labels-as-values extension, which boosts emulator performance by up to 50%. That does unfortunately not (yet) mean - that all of OTP could be compiled using GCC, that particular + that all of OTP could be compiled using GCC. That particular source code does not do anything system specific and actually is adopted to the fact that GCC is used to compile it on Windows. @@ -152,229 +177,184 @@ Frequently Asked Questions A: No, never. The hassle of keeping the project files up to date and do all the steps that constitute an OTP build from within the VC++ GUI is simply not worth it, maybe even impossible. A VC++ project - file for Erlang/OTP will never happen, at least I will never make - one. Clicking around in super-multi-tab'd dialogs to add a file or - compiler option when it's so much easier in a makefile is simply not - my style. + file for Erlang/OTP will never happen. * Q: So how does it all work then? - A: Cygwin or Msys is the environment, which closely resembles the - environments found on any Unix machine. It's almost like you had a + A: Cygwin, MSYS or MSYS2 is the environment, which closely resembles the + environment found on any Unix machine. It's almost like you had a virtual Unix machine inside Windows. Configure, given certain parameters, then creates makefiles that are used by the - Cygwin/Msys gnu-make to built the system. Most of the actual - compilers etc are not, however, Cygwin/Msys tools, so I've written + environment's gnu-make to built the system. Most of the actual + compilers etc are not, however, Cygwin/MSYS/MSYS2 tools, so we've written a couple of wrappers (Bourne-shell scripts), which reside in `$ERL_TOP/etc/win32/cygwin_tools` and `$ERL_TOP/etc/win32/msys_tools`. They all do conversion of parameters and switches common in the Unix environment to fit the native Windows tools. Most notable is of course the paths, which - in Cygwin/Msys are Unix-like paths with "forward slashes" (/) and - no drive letters, the Cygwin specific command `cygpath` is used - for most of the path conversions in a Cygwin environment, other - tools are used (when needed) in the corresponding Msys + in Cygwin/MSYS/MSYS2 are Unix-like paths with "forward slashes" (/) and + no drive letters. The Cygwin specific command `cygpath` is used + for most of the path conversions in a Cygwin environment. Other + tools are used (when needed) in the corresponding MSYS and MSYS2 environment. Luckily most compilers accept forward slashes instead of backslashes as path separators, but one still have to get the drive letters etc right, though. The wrapper scripts are not general in - the sense that, for example, cc.sh would understand and translates - every possible gcc option and passes correct options to + the sense that, for example, cc.sh would understand and translate + every possible gcc option and pass correct options to cl.exe. The principle is that the scripts are powerful enough to allow building of Erlang/OTP, no more, no less. They might need - extensions to cope with changes during the development of Erlang, - that's one of the reasons I made them into shell-scripts and not - Perl-scripts, I believe they are easier to understand and change - that way. I might be wrong though, cause another reason I didn't - write them in Perl is because I've never liked Perl and my Perl - code is no pleasant reading... + extensions to cope with changes during the development of Erlang, and + that's one of the reasons we made them into shell-scripts and not + Perl-scripts. We believe they are easier to understand and change + that way. In `$ERL_TOP`, there is a script called `otp_build`. That script handles the hassle of giving all the right parameters to `configure`/`make` and also helps you set up the correct environment variables to work with - the Erlang source under Cygwin. + the Erlang source under Cygwin/MSYS/MSYS2. * Q: You use and need Cygwin, but then you haven't taken the time to port Erlang to the Cygwin environment but instead focus on your commercial release, is that really ethical? - A: No, not really, but see this as a step in the right direction. I'm - aiming at GCC compiled emulators and a Cygwin version, but I really - need to do other things as well... In time, but don't hold your - breath... + A: No, not really, but see this as a step in the right direction. * Q: Can I build something that looks exactly as the commercial release? - A: Yes, we use the exactly same build procedure. + A: Yes, we use the exact same build procedure. -* Q: Which version of Cygwin/Msys and other tools do you use then? +* Q: Which version of Cygwin/MSYS/MSYS2 and other tools do you use then? - A: For Cygwin and Msys alike, we try to use the latest releases + A: For Cygwin, MSYS and MSYS2 alike, we try to use the latest releases available when building. What versions you use shouldn't really - matter, I try to include workarounds for the bugs I've found in - different Cygwin/Msys releases, please help me add workarounds - for new Cygwin/Msys-related bugs as soon as you encounter - them. Also please do submit bug reports to the appropriate Cygwin - and/or Msys developers. The GCC we used for %OTP-REL% was version - 4.7.0 (MinGW 64bit) and 4.3.4 (Cygwin 32bit). We used VC++ 10.0 - (i.e. Visual studio 2010), Sun's JDK 1.5.0\_17 (32bit) and Sun's - JDK 1.7.0\_1 (64bit), NSIS 2.46, and Win32 OpenSSL 0.9.8r. Please + matter. We try to include workarounds for the bugs we've found in + different Cygwin/MSYS/MSYS2 releases. Please help us add workarounds + for new Cygwin/MSYS/MSYS2-related bugs as soon as you encounter + them. Also please do submit bug reports to the appropriate Cygwin, MSYS + and/or MSYS2 developers. The GCC we used for %OTP-REL% was version + 4.8.1 (MinGW 32bit) and 4.8.5 (MSYS2 64bit). We used VC++ 12.0 + (i.e. Visual studio 2013), Sun's JDK 1.6.0\_45 (32bit) and Sun's + JDK 1.7.0\_1 (64bit), NSIS 2.46, and Win32 OpenSSL 1.0.2d. Please read the next section for details on what you need. -* Q: Can you help me setup X in Cygwin? +* Q: Can you help me setup X in Cygwin/MSYS/MSYS2? - A: No, unfortunately I haven't got time to help with Cygwin related - user problems, please read Cygwin related web sites, newsgroups and + A: No, unfortunately we haven't got time to help with Cygwin/MSYS/MSYS2 + related user problems, please read related websites, newsgroups and mailing lists. -* Q: Why is the instruction so long? Is it really that complicated? - - A: Partly it's long because I babble too much, partly because I've - described as much as I could about the installation of the needed - tools. Once the tools are installed, building is quite easy. I also - have tried to make this instruction understandable for people with - limited Unix experience. Cygwin/Msys is a whole new environment to some - Windows users, why careful explanation of environment variables etc - seemed to be in place. The short story, for the experienced and - impatient is: - - * Get and install complete Cygwin (latest) or complete MinGW with msys - - * Install Microsofts Windows SDK 7.1 (and .Net 4) - - * Get and install Sun's JDK 1.5.0 or higher - - * Get and install NSIS 2.01 or higher (up to 2.46 tried and working) - - * Get, build and install OpenSSL 0.9.8r or higher (up to 1.0.0a - tried & working) with static libs. - - * Get the Erlang source distribution (from - <http://www.erlang.org/download.html>) and unpack with Cygwin's `tar`. - - * Set `ERL_TOP` to where you unpacked the source distribution - - * `$ cd $ERL_TOP` - - * Get (from <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz>) - and unpack the prebuilt TCL/TK binaries for windows with cygwin tar, - standing in `$ERL_TOP` - - * Modify PATH and other environment variables so that all these tools - are runnable from a bash shell. Still standing in `$ERL_TOP`, issue - the following commands: - - $ eval `./otp_build env_win32` - $ ./otp_build autoconf - $ ./otp_build configure - $ ./otp_build boot -a - $ ./otp_build release -a - $ ./otp_build installer_win32 - $ release/win32/otp_win32_%OTP-REL% /S - - Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang - Windows shell. - Tools you Need and Their Environment ------------------------------------ You need some tools to be able to build Erlang/OTP on Windows. Most -notably you'll need Cygwin or Msys and Microsofts Windows SDK, but -you also might want a Java compiler, the NSIS install system and -OpenSSL. Well' here's the list: +notably you'll need Cygwin, MSYS or MSYS2, Visual Studio and Microsofts +Windows SDK, but you might also want a Java compiler, the NSIS install +system and OpenSSL. Well, here's some information about the different +tools: * Cygwin, the very latest is usually best. Get all the development - tools and of course all the basic ditto. In fact getting the complete - package might be a good idea, as you'll start to love Cygwin after a - while if you're accustomed to Unix. Make sure to get jar and also make - sure *not* to install a Cygwin'ish Java... The Cygwin jar command is - used but Sun's Java compiler and virtual machine... + tools and of course all the basic ditto. Make sure to get jar and + also make sure *not* to install a Cygwin'ish Java, since the Cygwin + jar command is used but Sun's Java compiler and virtual machine. If you are going to build a 64bit Windows version, you should make - sure to get MinGW's 64bit gcc installed with cygwin. It's in one of + sure to get MinGW's 64bit gcc installed with Cygwin. It's in one of the development packages. URL: <http://www.cygwin.com> - Get the installer from the web site and use that to install - Cygwin. Be sure to have fair privileges. If you're on a NT domain you + Get the installer from the website and use it to install + Cygwin. Be sure to have fair privileges. If you're on an NT domain you should consider running `mkpasswd -d` and `mkgroup -d` after the installation to get the user databases correct. See their respective manual pages. - When you start you first bash shell, you will get an awful prompt. You + When you start your first bash shell, you will get an awful prompt. You might also have a `PATH` environment variable that contains backslashes and such. Edit `$HOME/.profile` and `$HOME/.bashrc` to set fair prompts - and set a correct PATH. Also do a `export SHELL` in `.profile`. For some + and a correct PATH. Also do an `export SHELL` in `.profile`. For some non-obvious reason the environment variable `$SHELL` is not exported in bash. Also note that `.profile` is run at login time and `.bashrc` when sub shells are created. You'll need to explicitly source `.bashrc` from `.profile` if you want the commands there to be run at login time (like - setting up aliases, shell functions and the like). I personally - usually do like this at the end of `.profile`: + setting up aliases, shell functions and the like). You can for example + do like this at the end of `.profile`: ENV=$HOME/.bashrc export ENV . $ENV - You might also, if you're a hard core type of person at least, want to - setup X-windows (XFree86), that might be as easy as running startx - from the command prompt and it might be much harder. Use Google to - find help... + You might also want to setup X-windows (XFree86). That might be as easy + as running startx from the command prompt and it might be much harder. + Use Google to find help. If you don't use X-windows, you might want to setup the Windows console window by selecting properties in the console system menu (upper left corner of the window, the Cygwin icon in the title bar). Especially setting a larger screen buffer size (lines) is useful as it gets you a scrollbar so you can see whatever error messages - that might appear... + that might appear. - If you want to use (t)csh instead of bash you're on your own, I - haven't tried and know of no one that has. I expect - that you use bash in all shell examples. + There are a few other shells available, but in all examples below we assume + that you use bash. -* Alternatively you download MinGW and Msys. You'll find the latest +* Alternatively you download MinGW and MSYS. You'll find the latest installer at: URL: <http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/> - Make sure to install everything they've got. + Make sure to install the basic dev tools, but avoid the MinGW autoconf and + install the msys one instead. To be able to build the 64bit VM, you will also need the 64bit MinGW compiler from: - URL: <http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/> + URL: <http://sourceforge.net/projects/mingw-w64/files/latest/download?source=files> - The latest version should do it. Make sure you download the - `mingw-w64-bin_i686-mingw_<something>.zip`, not a linux + We've tried up to 1.0, but the latest version should do. Make sure you + download the `mingw-w64-bin_i686-mingw_<something>.zip`, not a linux version. You unzip the package on top of your MinGW installation (`c:\MinGW`) and that's it. - Setting up your environment in Msys is similar to setting it up in - Cygwin. +* A third alternative is to download and install MSYS2 from: -* Microsofts Windows SDK version 7.1 (corresponding to VC++ 10.0 and - Visual Studio 2010). You'll find it here: - - URL: <http://www.microsoft.com/download/en/details.aspx?id=8279> + URL: <https://msys2.github.io/> + + When you've followed the instructions there, you also need to install + these packages: autoconf, make, perl, and tar. You do so by running + the following in the msys console: + + pacman -S msys/autoconf msys/make msys/perl msys/tar + + You also need a gcc. If you installed the 64 bit MSYS2 you run: - but before you install that, you need to have .Net 4 installed, - you'll find that here: + mingw64/mingw-w64-x86_64-gcc - URL: <http://www.microsoft.com/download/en/details.aspx?id=17851> + And for 32 bit MSYS2: - Use the web installer for the SDK, at least when I tried - downloading the whole package as an image, I got SDK 7.0 instead, - which is not what you want... + pacman -S mingw32/mingw-w64-i686-gcc + pacman -S mingw-w64-i686-editrights - There will be a Windows command file in `%PROGRAMFILES%\Mirosoft - SDKs\Windows\v7.1\Bin\SetEnv.cmd` that set's the appropriate +* Visual Studio 2013 (Visual Studio 12.0). Download and run the web + installer from: + + https://www.visualstudio.com/ + +* Microsofts Windows SDK version 8.1 (corresponding to VC++ 12.0 and + Visual Studio 2013). You'll find it here: + + URL: <https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx> + +* To help setup the environment, there is a bat file, + `%PROGRAMFILES%\Mirosoft Visual Studio 12.0\VC\vcvarsall.bat`, + that set's the appropriate environment for a Windows command prompt. This is not appropriate for bash, so you'll need to convert it to bash-style environments by editing your `.bash_profile`. In my case, where the SDK is installed in the default directory and `%PROGRAMFILES%` is `C:\Program Files`, the commands for setting up a 32bit build - environment (on a 64bit or 32bit machine) look like this (in cygwin): + environment (on a 64bit or 32bit machine) look like this (in Cygwin): # Some common paths C_DRV=/cygdrive/c @@ -383,309 +363,290 @@ OpenSSL. Well' here's the list: # nsis NSIS_BIN=$PRG_FLS/NSIS # java - JAVA_BIN=$PRG_FLS/Java/jdk1.6.0_16/bin + JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin ## ## MS SDK ## - CYGWIN=nowinsymlinks - MVS10="$PRG_FILES/Microsoft Visual Studio 10.0" - WIN_MVS10="C:\\Program Files\\Microsoft Visual Studio 10.0" - SDK10="$PRG_FILES/Microsoft SDKs/Windows/v7.1" - WIN_SDK10="C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1" + CYGWIN=nowinsymlinks + + VISUAL_STUDIO_ROOT=$PRG_FLS/Microsoft\ Visual\ Studio\ 12.0 + WIN_VISUAL_STUDIO_ROOT="C:\\Program Files\\Microsoft Visual Studio 12.0" + SDK=$PRG_FLS/Windows\ Kits/8.1 + WIN_SDK="C:\\Program Files\\Windows Kits\\8.1" PATH="$NSIS_BIN:\ - $MVS10/Common7/IDE:\ - $MVS10/Common7/Tools:\ - $MVS10/VC/Bin:\ - $MVS10/VC/Bin/VCPackages:\ - $SDK10/Bin/NETFX 4.0 Tools:\ - $SDK10/Bin:\ + $VISUAL_STUDIO_ROOT/VC/bin:\ + $VISUAL_STUDIO_ROOT/VC/vcpackages:\ + $VISUAL_STUDIO_ROOT/Common7/IDE:\ + $VISUAL_STUDIO_ROOT/Common7/Tools:\ + $SDK/bin/x86 /usr/local/bin:/usr/bin:/bin:\ /cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:\ /cygdrive/c/WINDOWS/system32/Wbem:\ $JAVA_BIN" - LIBPATH="$WIN_MVS10\\VC\\LIB" + LIBPATH="$WIN_VISUAL_STUDIO_ROOT\\VC\\lib" - LIB="$WIN_MVS10\\VC\\LIB;$WIN_SDK10\\LIB" + LIB="$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\;$WIN_SDK\\lib\\winv6.3\\um\\x86" - INCLUDE="$WIN_MVS10\\VC\\INCLUDE;$WIN_SDK10\\INCLUDE;$WIN_SDK10\\INCLUDE\\gl" + INCLUDE="$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;$WIN_SDK\\include\\shared\\; + $WIN_SDK\\include\\um;$WIN_SDK\\include\\winrt\\;$WIN_SDK\\include\\um\\gl" - export CYGWIN PATH LIBPATH LIB INCLUDE + export CYGWIN PATH LIBPATH LIB INCLUDE - If you're using Msys instead, the only thing you need to change is - the `C_DRV` setting, which would read: + If you're using MinGW's MSYS instead, you need to change the `C_DRV` setting, + which would read: C_DRV=/c - And of course you might need to change `C:\Program Files` etc if - you're using a non-english version of Windows (XP). Note that in - later versions of Windows, the national adoptions of the program - files directories etc are not on the file system but only in the - explorer, so even if explorer says that your programs reside in - e.g. `C:\Program`, they might still reside in `C:\Program Files` - in reality... - - If you are building a 64 bit version of Erlang, you should set up - PATHs etc a little differently. I use the following script to - make things work in both Cygwin and Msys: - - make_winpath() - { - P=$1 - if [ "$IN_CYGWIN" = "true" ]; then - cygpath -d "$P" - else - (cd "$P" && /bin/cmd //C "for %i in (".") do @echo %~fsi") - fi - } - - make_upath() - { - P=$1 - if [ "$IN_CYGWIN" = "true" ]; then - cygpath "$P" - else - echo "$P" | /bin/sed 's,^\([a-zA-Z]\):\\,/\L\1/,;s,\\,/,g' - fi - } - - # Some common paths - if [ -x /usr/bin/msysinfo ]; then - # Without this the path conversion won't work - COMSPEC='C:\Windows\SysWOW64\cmd.exe' - MSYSTEM=MINGW32 - export MSYSTEM COMSPEC - IN_CYGWIN=false - else - CYGWIN=nowinsymlinks - export CYGWIN - IN_CYGWIN=true - fi - - if [ "$IN_CYGWIN" = "true" ]; then - PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:\ - /cygdrive/c/windows/system32:/cygdrive/c/windows:/cygdrive/c/windows/system32/Wbem - else - PATH=/usr/local/bin:/mingw/bin:/bin:/c/Windows/system32:/c/Windows:\ - /c/Windows/System32/Wbem - fi - - if [ "$IN_CYGWIN" = "true" ]; then - C_DRV=/cygdrive/c - else - C_DRV=/c - fi - - PRG_FLS64=$C_DRV/Program\ Files - PRG_FLS32=$C_DRV/Program\ Files\ \(x86\) - VISUAL_STUDIO_ROOT32=$PRG_FLS32/Microsoft\ Visual\ Studio\ 10.0 - MS_SDK_ROOT64=$PRG_FLS64/Microsoft\ SDKs/Windows/v7.1 - - # Okay, now mangle the paths and get rid of spaces by using short names - WIN_VCROOT32=`make_winpath "$VISUAL_STUDIO_ROOT32"` - VCROOT32=`make_upath $WIN_VCROOT32` - WIN_SDKROOT64=`make_winpath "$MS_SDK_ROOT64"` - SDKROOT64=`make_upath $WIN_SDKROOT64` - WIN_PROGRAMFILES32=`make_winpath "$PRG_FLS32"` - PROGRAMFILES32=`make_upath $WIN_PROGRAMFILES32` - - WIN_PROGRAMFILES64=`make_winpath "$PRG_FLS64"` - PROGRAMFILES64=`make_upath $WIN_PROGRAMFILES64` - - # nsis - NSIS_BIN=$PROGRAMFILES32/NSIS - # java - JAVA_BIN=$PROGRAMFILES64/Java/jdk1.7.0_01/bin - - ## The PATH variable should be Unix'ish - VCPATH=$VCROOT32/Common7/IDE:$VCROOT32/VC/BIN/amd64:$VCROOT32/Common7/Tools:\ - $VCROOT32/VC/VCPackages:$SDKROOT64/bin/NETFX4~1.0TO/x64:$SDKROOT64/bin/x64:\ - $SDKROOT64/bin - - ## Microsoft SDK libs - - LIBPATH=$WIN_VCROOT32\\VC\\LIB\\amd64 - LIB=$WIN_VCROOT32\\VC\\LIB\\amd64\;$WIN_SDKROOT64\\LIB\\X64 - INCLUDE=$WIN_VCROOT32\\VC\\INCLUDE\;$WIN_SDKROOT64\\include\;\ - $WIN_SDKROOT64\\include\\gl - - # Put nsis, c compiler and java in path - PATH=$NSIS_BIN:$VCPATH:$PATH:$JAVA_BIN - - # Make sure LIB and INCLUDE is available for others - export PATH LIBPATH LIB INCLUDE - - All this is derived from the SetEnv.cmd command file mentioned - earlier. The bottom line is to set the PATH so that NSIS and - Microsoft SDK is found before the Msys/Cygwin tools and that Java - is last in the PATH. - - Make a simple hello world (maybe one that prints out - `sizeof(void *)`) and try to compile it with the `cl` command from within - bash. If that does not work, your environment needs fixing. Also - remember to fix up the PATH environment, especially old Erlang - installations might have inserted quoted paths that Cygwin/Msys - does not understand. Remove or correct such paths. There should be - no backslashes in your path environment variable in Cygwin bash, - but LIB and INCLUDE should contain Windows style paths with - semicolon, drive letters and backslashes. + and you also need to change the PATH environment variable to: -* Sun's Java JDK 1.5.0 or higher. Our Java code (jinterface, ic) is - written for JDK 1.5.0. Get it for Windows and install it, the JRE is - not enough. If you don't care about Java, you can skip this step, the - result will be that jinterface is not built. + MINGW_BIN=/c/MinGW/bin - URL: <http://java.sun.com> - Add javac *LAST* to your path environment in bash, in my case this means: + PATH="$NSIS_BIN:\ + $VISUAL_STUDIO_ROOT/VC/bin:\ + $VISUAL_STUDIO_ROOT/VC/vcpackages:\ + $VISUAL_STUDIO_ROOT/Common7/IDE:\ + $VISUAL_STUDIO_ROOT/Common7/Tools:\ + $SDK/bin/x86:/usr/local/bin:\ + $MINGW_BIN:\ + /bin:/c/Windows/system32:/c/Windows:\ + /c/Windows/System32/Wbem:\ + $JAVA_BIN" - `PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.5.0_17/bin"` + For MSYS2 you use the same `C_DRV` and PATH as for MSYS, only update the `MINGW_BIN`: - No `CLASSPATH` or anything is needed. Type `javac` at the bash prompt - and you should get a list of available Java options. Make sure by - typing `type java` that you use the Java you installed. Note however that - Cygwin's `jar.exe` is used, that's why the JDK bin-directory should be - added last in the `PATH`. + MINGW_BIN=/mingw32/bin + -* Nullsoft NSIS installer system. You need this to build the self - installing package. It's a free open source installer that's much - nicer to use than the commercial Wise and Install shield - installers. This is the installer we use for commercial releases as - well from R9C an on. + If you are building a 64 bit version of Erlang, you should set up + PATHs etc a little differently. We have two templates to make things + work in both Cygwin and MSYS but needs editing to work with MSYS2 (see the + comments in the script). + The following one is for 32 bits: + + make_winpath() + { + P=$1 + if [ "$IN_CYGWIN" = "true" ]; then + cygpath -d "$P" + else + (cd "$P" && /bin/cmd //C "for %i in (".") do @echo %~fsi") + fi + } + + make_upath() + { + P=$1 + if [ "$IN_CYGWIN" = "true" ]; then + cygpath "$P" + else + echo "$P" | /bin/sed 's,^\([a-zA-Z]\):\\,/\L\1/,;s,\\,/,g' + fi + } - URL: <http://www.nullsoft.com/free/nsis> + # Some common paths + if [ -x /usr/bin/msys-?.0.dll ]; then + # Without this the path conversion won't work + COMSPEC='C:\Windows\System32\cmd.exe' + MSYSTEM=MINGW32 # Comment out this line if in MSYS2 + export MSYSTEM COMSPEC + # For MSYS2: Change /mingw/bin to the msys bin dir on the line below + PATH=/usr/local/bin:/mingw/bin:/bin:/c/Windows/system32:\ + /c/Windows:/c/Windows/System32/Wbem + C_DRV=/c + IN_CYGWIN=false + else + PATH=/ldisk/overrides:/usr/local/bin:/usr/bin:/bin:\ + /usr/X11R6/bin:/cygdrive/c/windows/system32:\ + /cygdrive/c/windows:/cygdrive/c/windows/system32/Wbem + C_DRV=/cygdrive/c + IN_CYGWIN=true + fi + + obe_otp_gcc_vsn_map=" + .*=>default + " + obe_otp_64_gcc_vsn_map=" + .*=>default + " + # Program Files + PRG_FLS=$C_DRV/Program\ Files - Install the lot, especially the modern user interface components, as - it's definitely needed. Put `makensis` in your path, in my case: + # Visual Studio + VISUAL_STUDIO_ROOT=$PRG_FLS/Microsoft\ Visual\ Studio\ 12.0 + WIN_VISUAL_STUDIO_ROOT="C:\\Program Files\\Microsoft Visual Studio 12.0" - PATH=/cygdrive/c/Program\ Files/NSIS:$PATH + # SDK + SDK=$PRG_FLS/Windows\ Kits/8.1 + WIN_SDK="C:\\Program Files\\Windows Kits\\8.1" - type makensis at the bash prompt and you should get a list of options - if everything is OK. + # NSIS + NSIS_BIN=$PROGRAMFILES/NSIS -* OpenSSL. This is if you want the SSL and crypto applications to - compile (and run). There are prebuilt binaries available, but I - strongly recommend building this yourself. It's quite easy. + # Java + JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin - First get the source from + ## The PATH variable should be Cygwin'ish + VCPATH= + $VISUAL_STUDIO_ROOT/VC/bin:\ + $VISUAL_STUDIO_ROOT/VC/vcpackages:\ + $VISUAL_STUDIO_ROOT/Common7/IDE:\ + $VISUAL_STUDIO_ROOT/Common7/Tools:\ + $SDK/bin/x86 - URL: <http://openssl.org/source/> + ## Microsoft SDK libs + LIBPATH=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib - I would recommend using 0.9.8r. + LIB=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\;$WIN_KITS\\lib\\winv6.3\\um\\x86 - Download the tar file and unpack it (using your bash prompt) into - a directory of your choise. + INCLUDE=$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;\ + $WIN_KITS\\include\\shared\\;$WIN_KITS\\include\\um;\ + $WIN_KITS\\include\\winrt\\;$WIN_KITS\\include\\um\\gl - You will need a Windowish Perl for the build. ActiveState has one: + # Put nsis, c compiler and java in path + export PATH=$VCPATH:$PATH:$JAVA_BIN:$NSIS_BIN - URL: <http://www.activestate.com/activeperl/downloads> + # Make sure LIB and INCLUDE is available for others + export LIBPATH LIB INCLUDE - Download and install that. Disable options to associate it with - the .pl suffix and/or adding things to PATH, they are not needed. - Now fire up the Microsoft Windows SDK command prompt in RELEASE - mode for the architecture you are going to build. The easiest is - to copy the shortcut from the SDKs start menu item and edit the - command line in the shortcut (Right click->Properties) to end with - `/Release`. Make sure the banner when you double click your - shortcut (the text in the resulting command window) says - `Targeting Windows XP x64 Release` if you are going to do a 64 bit - build and `Targeting Windows XP x86 Release` if you are building a - 32 bit version. - Now cd to where you unpacked the OpenSSL source using your Release - Windows command prompt (it should be on the same drive as where - you are going to install it if everything is to work smothly). + The first part of the 64 bit template is identical to the 32 bit one, + but there are some environment variable differences: - C:\> cd <some dir> + # Program Files + PRG_FLS64=$C_DRV/Program\ Files + PRG_FLS32=$C_DRV/Program\ Files\ \(x86\) - Add ActiveState (or some other windows perl, not cygwins) to your PATH: + # Visual Studio + VISUAL_STUDIO_ROOT=$PRG_FLS32/Microsoft\ Visual\ Studio\ 12.0 + WIN_VISUAL_STUDIO_ROOT="C:\\Program Files (x86)\\Microsoft Visual Studio 12.0" - C:\...\> set PATH=C:\Perl\bin;%PATH% + # SDK + SDK=$PRG_FLS32/Windows\ Kits/8.1 + WIN_SDK="C:\\Program Files (x86)\\Windows Kits\\8.1" - Or if you installed the 64bit perl: - - C:\...\> set PATH=C:\Perl64\bin;%PATH% + # NSIS + NSIS_BIN=$PROGRAMFILES/NSIS + # Java + JAVA_BIN=$PROGRAMFILES/Java/jdk1.7.0_02/bin - Configure OpenSSL for 32 bit: + ## The PATH variable should be Cygwin'ish + VCPATH= + $VISUAL_STUDIO_ROOT/VC/bin/amd64:\ + $VISUAL_STUDIO_ROOT/VC/vcpackages:\ + $VISUAL_STUDIO_ROOT/Common7/IDE:\ + $VISUAL_STUDIO_ROOT/Common7/Tools:\ + $SDK/bin/x86 - C:\...\> perl Configure VC-WIN32 --prefix=/OpenSSL + ## Microsoft SDK libs + LIBPATH=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\amd64 - Or for 64 bit: + LIB=$WIN_VISUAL_STUDIO_ROOT\\VC\\lib\\amd64\\;\ + $WIN_KITS\\lib\\winv6.3\\um\\x64 - C:\...\> perl Configure VC-WIN64A --prefix=/OpenSSL-Win64 + INCLUDE=$WIN_VISUAL_STUDIO_ROOT\\VC\\include\\;\ + $WIN_KITS\\include\\shared\\;$WIN_KITS\\include\\um;\ + $WIN_KITS\\include\\winrt\\;$WIN_KITS\\include\\um\\gl - Do some setup (for 32 bit): + # Put nsis, c compiler and java in path + export PATH=$VCPATH:$PATH:$JAVA_BIN:$NSIS_BIN - C:\...\> ms\do_ms + # Make sure LIB and INCLUDE is available for others + export LIBPATH LIB INCLUDE - The same for 64 bit: - C:\...\> ms\do_win64a + Make sure to set the PATH so that NSIS and Microsoft SDK is found + before the MSYS/Cygwin tools and that Java is last in the PATH. - Then build static libraries and install: + Make a simple hello world and try to compile it with the `cl` + command from within bash. If that does not work, your environment + needs fixing. Remember, there should be + no backslashes in your path environment variable in Cygwin bash, + but LIB and INCLUDE should contain Windows style paths with + semicolon, drive letters and backslashes. - C:\...\> nmake -f ms\nt.mak - C:\...\> nmake -f ms\nt.mak install +* Sun's Java JDK 1.6.0 or later. Our Java code (jinterface, ic) is + written for JDK 1.6.0. Get it for Windows and install it, the JRE is + not enough. If you don't care about Java, you can skip this step. The + result will be that jinterface is not built. + + URL: <http://java.sun.com> + + Add javac *LAST* to your path environment in bash, in my case this means: + + `PATH="$PATH:/cygdrive/c/Program Files/Java/jdk1.7.0_02/bin"` + + No `CLASSPATH` or anything is needed. Type `javac` in the bash prompt + and you should get a list of available Java options. Make sure, e.g by + typing `type java`, that you use the Java you installed. Note however that + Cygwin's/MinGW's/MSYS2's `jar.exe` is used. That's why the JDK bin-directory should be + added last in the `PATH`. + +* Nullsoft NSIS installer system. You need this to build the self + installing package. It's a free open source installer that's much + nicer to use than the commercial Wise and Install shield + installers. This is the installer we use for commercial releases as + well. + + URL: <http://nsis.sourceforge.net/download> + + Install the lot, especially the modern user interface components, as + it's definitely needed. Put `makensis` in your path, in my case: + + PATH=/cygdrive/c/Program\ Files/NSIS:$PATH + + Type makensis at the bash prompt and you should get a list of options + if everything is OK. + +* OpenSSL. This is if you want the SSL and crypto applications to + compile (and run). There are prebuilt binaries, which you can just + download and install, available here: + + URL: <http://openssl.org/community/binaries.html> - That's it - you now have your perfectly consistent static build of - openssl. If you want to get rid of any possibly patented - algorithms in the lib, just read up on the OpenSSL FAQ and follow - the instructions. + We would recommend using 1.0.2d. - The installation locations chosen are where configure will look - for OpenSSL, so try to keep them as is. - -* Building with wxWidgets. Download wxWidgets-3.0.2 or higher patch - release. +* Building with wxWidgets. Download wxWidgets-3.0.2 or higher. - Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`. + Install or unpack it to the pgm folder: + Cygwin: + `DRIVE:/PATH/cygwin/opt/local/pgm` + MSYS: + `DRIVE:/PATH/MinGW/msys/1.0/opt/local/pgm` + MSYS2: + `DRIVE:/PATH/msys<32/64>/opt/local/pgm` - edit: `C:\cygwin\opt\local\pgm\wxMSW-3.0.2\include\wx\msw\setup.h` - enable `wxUSE_POSTSCRIPT` + If the `wxUSE_POSTSCRIPT` isn't enabled in `<path\to\pgm>\wxMSW-3.0.2\include\wx\msw\setup.h`, + enable it. build: From a command prompt with the VC tools available (See the instructions for OpenSSL build above for help on starting the proper command prompt in RELEASE mode): - C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-3.0.2\build\msw + C:\...\> cd <path\to\pgm>\wxMSW-3.0.2\build\msw C:\...\> nmake BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc Or - if building a 64bit version: - C:\...\> cd C:\cygwin\opt\local\pgm\wxMSW-3.0.2\build\msw + C:\...\> cd <path\to\pgm>\wxMSW-3.0.2\build\msw C:\...\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc -* The Erlang source distribution (from <http://www.erlang.org/download.html>). - The same as for Unix platforms. Preferably use tar from within Cygwin to +* Get the Erlang source distribution (from <http://www.erlang.org/download.html>). + The same as for Unix platforms. Preferably use tar from within Cygwin, MSYS or MSYS2 to unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`). - set the environment `ERL_TOP` to point to the root directory of the + Set the environment `ERL_TOP` to point to the root directory of the source distribution. Let's say I stood in `$HOME/src` and unpacked `otp_src_%OTP-REL%.tar.gz`, I then add the following to `.profile`: ERL_TOP=$HOME/src/otp_src_%OTP-REL% export $ERL_TOP -* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself, - but you can get a stripped down version from our website which is - suitable to include in the final binary package. If you want to supply - tcl/tk yourself, read the instructions about how the tcl/tk tar file - used in the build is constructed under `$ERL_TOP/lib/gs/tcl`. The easy - way is to download <http://www.erlang.org/download/tcltk85_win32_bin.tar.gz> - and unpack it standing in the `$ERL_TOP` directory. This will create the - file `win32.tar.gz` in `$ERL_TOP/lib/gs/tcl/binaries`. - - One last alternative is to create a file named `SKIP` in the - `$ERL_TOP/lib/gs/` after configure is run, but that will give you an - erlang system without gs (which might be okay as you probably will use - wx anyway). - - Note that there is no special 64bit version of TCL/TK needed, you - can use the 32bit program even for a 64bit build. The Shell Environment --------------------- @@ -726,37 +687,18 @@ be easy after this. You could run `./otp_build env_win32` without sets seems OK. The path is cleaned of spaces if possible (using DOS style short names instead), the variables `OVERRIDE_TARGET`, `CC`, `CXX`, `AR` and `RANLIB` are set to their respective wrappers and the directories -`$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and -`$ERL_TOP/erts/etc/win32/cygwin_tool` are added first in the PATH. - -Try now a `type erlc`. That should result in the erlc wrapper script -(which does not have the .sh extension, for reasons best kept -untold...). It should reside in `$ERL_TOP/erts/etc/win32/cygwin_tools` -or `$ERL_TOP/erts/etc/win32/msys_tools`. You could also try `which -cc.sh`, which `ar.sh` etc. +`$ERL_TOP/erts/etc/win32/<cygwin/msys>_tools/vc` and +`$ERL_TOP/erts/etc/win32/<cygwin/msys>_tool` are added first in the PATH. -Now you're ready to build... +Now you can check which erlc you have by writing `type erlc` in your shell. +It should reside in `$ERL_TOP/erts/etc/win32/cygwin_tools` +or `$ERL_TOP/erts/etc/win32/msys_tools`. Building and Installing ----------------------- -Now it's assumed that you have executed `` eval `./otp_build env_win32` `` or -`` eval `./otp_build env_win32 x64` `` for this particular shell... - -Building is easiest using the `otp_build` script. That script takes care -of running configure, bootstrapping etc on Windows in a simple -way. The `otp_build` script is the utility we use ourselves to build on -different platforms and it therefore contains code for all sorts of -platforms. The principle is, however, that for non-Unix platforms, one -uses `./otp_build env_<target>` to set up environment and then the -script knows how to build on the platform "by itself". You've already -run `./otp_build env_win32` in the step above, so now it's mostly like -we build on any platform. OK, here are then steps; Assuming you will -want to build a full installation executable with NSIS, you can omit -`<installation directory>` and the release will be copied to -`$ERL_TOP/release/win32`: and there is where the packed self installing -executable will reside too. +Building is easiest using the `otp_build` script: $ ./otp_build autoconf # Ignore the warning blob about versions of autoconf $ ./otp_build configure <optional configure options> @@ -764,18 +706,18 @@ executable will reside too. $ ./otp_build release -a <installation directory> $ ./otp_build installer_win32 <installation directory> # optional -Now you will have a file called `otp_win32_R12B.exe` in the -`<installation directory>`, i.e. `$ERL_TOP/release/win32`. +Now you will have a file called `otp_win32_%OTP-REL%.exe` or `otp_win64_%OTP-REL%.exe` +in the `<installation directory>`, i.e. `$ERL_TOP/release/win32`. Lets get into more detail: 1. `$ ./otp_build autoconf` - This step rebuilds the configure scripts - to work correctly in the cygwin environment. In an ideal world, this + to work correctly in your environment. In an ideal world, this would not be needed, but alas, we have encountered several incompatibilities between our distributed configure scripts (generated - on a Linux platform) and the cygwin environment over the - years. Running autoconf on cygwin ensures that the configure scripts - are generated in a cygwin-compatible way and that they will work well + on a Linux platform) and the Cygwin/MSYS/MSYS2 environment over the + years. Running autoconf in Cygwin/MSYS/MSYS2 ensures that the configure + scripts are generated in a compatible way and that they will work well in the next step. 2. `$ ./otp_build configure` - This runs the newly generated configure @@ -784,38 +726,21 @@ Lets get into more detail: this awkward target name and behave accordingly. The CC variable also makes the compiler be `cc.sh`, which wraps MSVC++, so all configure tests regarding the C compiler gets to run the right compiler. A lot of - the tests are not needed on Windows, but I thought it best to run the - whole configure anyway. The only configure option you might want to - supply is `--with-ssl`, which might be needed if you have built your - own OpenSSL distribution. The Shining Lights distribution should be - found automatically by `configure`, if that fails, add a - `--with-ssl=<dir>` that specifies the root directory of your OpenSSL - installation. + the tests are not needed on Windows, but we thought it best to run the + whole configure anyway. 3. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped with the source, `$ERL_TOP/bootstrap`) to build a complete OTP - system. It first builds an emulator and sets up a minimal OTP system - under `$ERL_TOP/bootstrap`, then starts to compile the different OTP - compilers to make the `$ERL_TOP/bootstrap` system potent enough to be - able to compile all Erlang code in OTP. Then, all Erlang and C code - under `$ERL_TOP/lib` is built using the bootstrap system, giving a - complete OTP system (although not installed). When this is done, one - can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl` - and you should have a prompt. If you omit the -a flag, you'll get a - smaller system, that might be useful during development. Now - exit from Erlang and start making a release of the thing: + system. When this is done you can run erl from within the source tree; + just type `$ERL_TOP/bin/erl` and you whould have the prompt. 4. `$ ./otp_build release -a` - Builds a commercial release tree from the - source tree, default is to put it in `$ERL_TOP/release/win32`, you can + source tree. The default is to put it in `$ERL_TOP/release/win32`. You can give any directory as parameter (Cygwin style), but it doesn't really - matter if you're going to build a self extracting installer too. You - could of course build release to the final directory and then run - `./Install.exe` standing in the directory where the release was put, - that will create a fully functional OTP installation. But let's make - the nifty installer: - -5. `$ ./otp_build installer_win32` - Create the self extracting installer - executable. The executable `otp_win32_%OTP-REL%.exe` will be placed + matter if you're going to build a self extracting installer too. + +5. `$ ./otp_build installer_win32` - Creates the self extracting installer executable. + The executable `otp_win32_%OTP-REL%.exe` or `otp_win64_%OTP-REL%.exe` will be placed in the top directory of the release created in the previous step. If no release directory is specified, the release is expected to have been built to `$ERL_TOP/release/win32`, which also will be the place @@ -824,7 +749,7 @@ Lets get into more detail: /tmp/erl_release`), you're expected to give the same parameter here, (i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have a full NSIS installation and `makensis.exe` in your path for this to - work of course. Once you have created the installer, you can run it to + work. Once you have created the installer, you can run it to install Erlang/OTP in the regular way, just run the executable and follow the steps in the installation wizard. To get all default settings in the installation without any questions asked, you run the executable @@ -844,37 +769,17 @@ Lets get into more detail: and after a while Erlang/OTP-%OTP-REL% will have been installed in `C:\Program Files\erl%ERTS-VSN%\`, with shortcuts in the menu etc. - The necessary setup of an Erlang installation is actually done by the - program `Install.exe`, which resides in the release top. That program - creates `.ini`-files and copies the correct boot scripts. If one has - the correct directory tree (like after a `./otp_build release -a`), only - the running of `Install.exe` is necessary to get a fully functional - OTP. What the self extracting installer adds is (of course) the - possibility to distribute the binary easily, together with adding - shortcuts to the Windows start menu. There is also some adding of - entries in the registry, to associate `.erl` and `.beam` files with - Erlang and get nifty icons, but that's not something you'll really need - to run Erlang. The registry is also used to store uninstall information, - but if one has not used the self extracting installer, one cannot - (need not) do any uninstall, one just scratches the release directory - and everything is gone. Erlang/OTP does not *need* to put anything - in the Windows registry at all, and does not if you don't use the self - extracting installer. In other words the installer is pure cosmetics. - -> *NOTE*: Beginning with R9C, the Windows installer does *not* add Erlang -> to the system wide path. If one wants to have Erlang in the path, one -> has to add it by hand. Development ----------- Once the system is built, you might want to change it. Having a test -release in some nice directory might be useful, but you also can run +release in some nice directory might be useful, but you can also run Erlang from within the source tree. The target `local_setup`, makes the program `$ERL_TOP/bin/erl.exe` usable and it also uses all the OTP libraries in the source tree. -If you hack the emulator, you can then build the emulator executable +If you hack the emulator, you can build the emulator executable by standing in `$ERL_TOP/erts/emulator` and do a simple $ make opt @@ -923,12 +828,12 @@ or even in the source directory... $ cd $ERL_TOP/lib/stdlib/src $ make opt -Note that you're expected o have a fresh Erlang in your path when +Note that you're expected to have a fresh Erlang in your path when doing this, preferably the plain %OTP-REL% you have built in the previous steps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before -rebuilding specific libraries, that would give you a good enough +rebuilding specific libraries. That would give you a good enough Erlang system to compile any OTP erlang code. Setting up the path -correctly is a little bit tricky, you still need to have +correctly is a little bit tricky. You still need to have `$ERL_TOP/erts/etc/win32/cygwin_tools/vc` and `$ERL_TOP/erts/etc/win32/cygwin_tools` *before* the actual emulator in the path. A typical setting of the path for using the bootstrap @@ -963,57 +868,27 @@ Remember that: That's basically all you need to get going. + Using GIT --------- -You might want to check out versions of the source code from GitHUB. That is possible directly in cygwin, but not in Msys. There is a project MsysGIT: +You might want to check out versions of the source code from GitHUB. That is possible directly in Cygwin, but not in MSYS. There is a project MsysGIT: URL:<http://code.google.com/p/msysgit/> that makes a nice Git port. The msys prompt you get from MsysGIT is however not compatible with the full version from MinGW, so you will need to check out files using MsysGIT's command prompt and then switch -to a common Msys command prompt for building. Also all test suites -cannot be built as MsysGIT/Msys does not handle symbolic links. To -build test suites on Windows, you will need Cygwin for now. Hopefully -all symbolic links will disappear from our repository soon and this -issue will disappear. +to a common MSYS command prompt for building. Also all test suites +cannot be built as MsysGIT/MSYS does not handle symbolic links. -Final Words ------------ -My hope is that the possibility to build the whole system on Windows -will open up for free development on this platform too. There are many -things one might want to do better in the Windows version, like the -window-style command prompt as well as pure Cygwin porting. Although i -realize it's a much larger step to start building on Windows (with all -the software you need) than for instance on Linux, I sincerely hope -that some of you will make the effort and start submitting Windows -friendly patches. - -The first build system for Erlang using Cygwin on Windows was created -by Per Bergkvist. I haven't used his build system, but it's rumored to -be good. The idea to do this came from his work, so credit is well -deserved. - -Of course this would have been completely impossible without the -excellent Cygwin. The guys at Cygnus solutions and -Redhat deserve a huge THANKS! as well as all the other people in the -free software community who have helped in creating the magnificent -software that constitutes Cygwin. - -Also the people developing the alternative command prompt Msys and -the MinGW compiler are worth huge THANKS! The 64bit port would have -been impossible without the 64bit MinGW compiler. - -Good luck and Happy Hacking, -Patrik, OTP Copyright and License --------------------- %CopyrightBegin% -Copyright Ericsson AB 2003-2014. All Rights Reserved. +Copyright Ericsson AB 2003-2015. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -1030,6 +905,8 @@ limitations under the License. %CopyrightEnd% - [1]: http://www.erlang.org/faq.html "mailing lists" + [1]: http://www.erlang.org/static/doc/mailinglist.html + [2]: http://bugs.erlang.org + [3]: https://github.com/erlang/otp [?TOC]: true diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot Binary files differindex 25c092961c..cd628918e0 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 25c092961c..cd628918e0 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 b25c33084f..6dcce01def 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_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam Binary files differindex 59084464a0..5d1e45fd72 100644 --- a/bootstrap/lib/compiler/ebin/beam_block.beam +++ b/bootstrap/lib/compiler/ebin/beam_block.beam diff --git a/bootstrap/lib/compiler/ebin/beam_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam Binary files differindex b63864c96c..7c5dca424f 100644 --- a/bootstrap/lib/compiler/ebin/beam_disasm.beam +++ b/bootstrap/lib/compiler/ebin/beam_disasm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam Binary files differindex 8dd6375403..630a370a94 100644 --- a/bootstrap/lib/compiler/ebin/beam_jump.beam +++ b/bootstrap/lib/compiler/ebin/beam_jump.beam diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam Binary files differindex 38b749d9ae..8b13cea141 100644 --- a/bootstrap/lib/compiler/ebin/beam_validator.beam +++ b/bootstrap/lib/compiler/ebin/beam_validator.beam diff --git a/bootstrap/lib/compiler/ebin/cerl_trees.beam b/bootstrap/lib/compiler/ebin/cerl_trees.beam Binary files differindex fc1a7e04f8..b23668fb2b 100644 --- a/bootstrap/lib/compiler/ebin/cerl_trees.beam +++ b/bootstrap/lib/compiler/ebin/cerl_trees.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex 1b5467a54b..cbdef8e1d7 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/kernel/ebin/application.beam b/bootstrap/lib/kernel/ebin/application.beam Binary files differindex d8e98c021b..97c6d9d415 100644 --- a/bootstrap/lib/kernel/ebin/application.beam +++ b/bootstrap/lib/kernel/ebin/application.beam diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam Binary files differindex 55d123c6a2..cbef1633ee 100644 --- a/bootstrap/lib/kernel/ebin/code.beam +++ b/bootstrap/lib/kernel/ebin/code.beam diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam Binary files differindex aa75ae9bd1..13ec972cc2 100644 --- a/bootstrap/lib/kernel/ebin/code_server.beam +++ b/bootstrap/lib/kernel/ebin/code_server.beam diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam Binary files differindex c92373c68e..f87dd4a45c 100644 --- a/bootstrap/lib/kernel/ebin/dist_util.beam +++ b/bootstrap/lib/kernel/ebin/dist_util.beam diff --git a/bootstrap/lib/kernel/ebin/file_io_server.beam b/bootstrap/lib/kernel/ebin/file_io_server.beam Binary files differindex be820676ed..b9c53bde49 100644 --- a/bootstrap/lib/kernel/ebin/file_io_server.beam +++ b/bootstrap/lib/kernel/ebin/file_io_server.beam diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam Binary files differindex fc12b6b194..8e2911cd13 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 a76806293f..75743c63cc 100644 --- a/bootstrap/lib/kernel/ebin/inet.beam +++ b/bootstrap/lib/kernel/ebin/inet.beam diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp.beam b/bootstrap/lib/kernel/ebin/inet6_tcp.beam Binary files differindex d080a1200b..96dd4739ea 100644 --- a/bootstrap/lib/kernel/ebin/inet6_tcp.beam +++ b/bootstrap/lib/kernel/ebin/inet6_tcp.beam diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam Binary files differindex 3f98206013..1be1dc1c57 100644 --- a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam +++ b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam Binary files differindex 8c7c6ba218..6401f0fcfa 100644 --- a/bootstrap/lib/kernel/ebin/inet_db.beam +++ b/bootstrap/lib/kernel/ebin/inet_db.beam diff --git a/bootstrap/lib/kernel/ebin/inet_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam Binary files differindex 0c5b6c73e1..b1c3bf3369 100644 --- a/bootstrap/lib/kernel/ebin/inet_dns.beam +++ b/bootstrap/lib/kernel/ebin/inet_dns.beam diff --git a/bootstrap/lib/kernel/ebin/inet_tcp.beam b/bootstrap/lib/kernel/ebin/inet_tcp.beam Binary files differindex 60e0d9f569..c2b42fef1c 100644 --- a/bootstrap/lib/kernel/ebin/inet_tcp.beam +++ b/bootstrap/lib/kernel/ebin/inet_tcp.beam diff --git a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam Binary files differindex a3635e5dde..1b389cbb4d 100644 --- a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam +++ b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam Binary files differindex 9a0bfa2ba4..e0bb445bf5 100644 --- a/bootstrap/lib/kernel/ebin/net_kernel.beam +++ b/bootstrap/lib/kernel/ebin/net_kernel.beam diff --git a/bootstrap/lib/stdlib/ebin/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam Binary files differindex abf4949465..d4f06cf9fd 100644 --- a/bootstrap/lib/stdlib/ebin/beam_lib.beam +++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam diff --git a/bootstrap/lib/stdlib/ebin/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam Binary files differindex 4d052a0c50..aaa080bd97 100644 --- a/bootstrap/lib/stdlib/ebin/edlin.beam +++ b/bootstrap/lib/stdlib/ebin/edlin.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex 16cacefb7c..35482f799b 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam Binary files differindex 0522f5c05e..4b0e853390 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 f38ba5fa71..d40913093a 100644 --- a/bootstrap/lib/stdlib/ebin/erl_pp.beam +++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam diff --git a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam Binary files differindex 5c1bc6045f..0b98a9ceed 100644 --- a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam +++ b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam diff --git a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam Binary files differindex 9711f57e43..565904b903 100644 --- a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam +++ b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam Binary files differindex 7d30fc9fc1..9ac333dbee 100644 --- a/bootstrap/lib/stdlib/ebin/ets.beam +++ b/bootstrap/lib/stdlib/ebin/ets.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam Binary files differindex bc3e71f6a7..d22f9ec402 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_fsm.beam b/bootstrap/lib/stdlib/ebin/gen_fsm.beam Binary files differindex 268b8798c8..119c20e1d7 100644 --- a/bootstrap/lib/stdlib/ebin/gen_fsm.beam +++ b/bootstrap/lib/stdlib/ebin/gen_fsm.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam Binary files differindex 1e1e530eea..d6e5d223fb 100644 --- a/bootstrap/lib/stdlib/ebin/gen_server.beam +++ b/bootstrap/lib/stdlib/ebin/gen_server.beam diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam Binary files differindex 52b13fb974..9e63d204b6 100644 --- a/bootstrap/lib/stdlib/ebin/otp_internal.beam +++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam Binary files differindex cb6a8d6049..0f732c8cae 100644 --- a/bootstrap/lib/stdlib/ebin/proc_lib.beam +++ b/bootstrap/lib/stdlib/ebin/proc_lib.beam diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam Binary files differindex 0e59d769a4..90bc537b85 100644 --- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam +++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam diff --git a/bootstrap/lib/stdlib/ebin/rand.beam b/bootstrap/lib/stdlib/ebin/rand.beam Binary files differindex b6e0d20bd7..6abb189f16 100644 --- a/bootstrap/lib/stdlib/ebin/rand.beam +++ b/bootstrap/lib/stdlib/ebin/rand.beam diff --git a/bootstrap/lib/stdlib/ebin/re.beam b/bootstrap/lib/stdlib/ebin/re.beam Binary files differindex 9e140def2c..875c4a5513 100644 --- a/bootstrap/lib/stdlib/ebin/re.beam +++ b/bootstrap/lib/stdlib/ebin/re.beam diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam Binary files differindex 3b2d0eb0fa..9ad6d68ebd 100644 --- a/bootstrap/lib/stdlib/ebin/shell.beam +++ b/bootstrap/lib/stdlib/ebin/shell.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam Binary files differindex 6dd01bf004..ce7b63a6c2 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam Binary files differindex 1ebc561ee5..4af6cc8f40 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam Binary files differindex e80b6ae0cd..83407cdb87 100644 --- a/bootstrap/lib/stdlib/ebin/zip.beam +++ b/bootstrap/lib/stdlib/ebin/zip.beam diff --git a/bootstrap/lib/stdlib/include/assert.hrl b/bootstrap/lib/stdlib/include/assert.hrl new file mode 100644 index 0000000000..f913760102 --- /dev/null +++ b/bootstrap/lib/stdlib/include/assert.hrl @@ -0,0 +1,261 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright (C) 2004-2014 Richard Carlsson, Mickaël Rémond +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-ifndef(ASSERT_HRL). +-define(ASSERT_HRL, true). + +%% Asserts are enabled unless NOASSERT is defined, and ASSERT can be used to +%% override it: if both ASSERT and NOASSERT are defined, then ASSERT takes +%% precedence, and NOASSERT will become undefined. +%% +%% Furthermore, if NODEBUG is defined, it implies NOASSERT, unless DEBUG or +%% ASSERT are defined. +%% +%% If asserts are disabled, all assert macros are defined to be the atom +%% 'ok'. If asserts are enabled, all assert macros are defined to yield 'ok' +%% as the result if the test succeeds, and raise an error exception if the +%% test fails. The error term will then have the form {Name, Info} where +%% Name is the name of the macro and Info is a list of tagged tuples. + +%% allow NODEBUG to imply NOASSERT, unless DEBUG +-ifdef(NODEBUG). +-ifndef(DEBUG). +-ifndef(NOASSERT). +-define(NOASSERT, true). +-endif. +-endif. +-endif. + +%% allow ASSERT to override NOASSERT +-ifdef(ASSERT). +-undef(NOASSERT). +-endif. + +%% Assert macros must not depend on any non-kernel or stdlib libraries. +%% +%% We must use fun-call wrappers ((fun () -> ... end)()) to avoid +%% exporting local variables, and furthermore we only use variable names +%% prefixed with "__", that hopefully will not be bound outside the fun. +%% It is not possible to nest assert macros. + +-ifdef(NOASSERT). +-define(assert(BoolExpr),ok). +-else. +%% The assert macro is written the way it is so as not to cause warnings +%% for clauses that cannot match, even if the expression is a constant. +-define(assert(BoolExpr), + begin + ((fun () -> + case (BoolExpr) of + true -> ok; + __V -> erlang:error({assert, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??BoolExpr)}, + {expected, true}, + case __V of false -> {value, __V}; + _ -> {not_boolean,__V} + end]}) + end + end)()) + end). +-endif. + +%% This is the inverse case of assert, for convenience. +-ifdef(NOASSERT). +-define(assertNot(BoolExpr),ok). +-else. +-define(assertNot(BoolExpr), + begin + ((fun () -> + case (BoolExpr) of + false -> ok; + __V -> erlang:error({assert, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??BoolExpr)}, + {expected, false}, + case __V of true -> {value, __V}; + _ -> {not_boolean,__V} + end]}) + end + end)()) + end). +-endif. + +%% This is mostly a convenience which gives more detailed reports. +%% Note: Guard is a guarded pattern, and can not be used for value. +-ifdef(NOASSERT). +-define(assertMatch(Guard, Expr), ok). +-else. +-define(assertMatch(Guard, Expr), + begin + ((fun () -> + case (Expr) of + Guard -> ok; + __V -> erlang:error({assertMatch, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {pattern, (??Guard)}, + {value, __V}]}) + end + end)()) + end). +-endif. + +%% This is the inverse case of assertMatch, for convenience. +-ifdef(NOASSERT). +-define(assertNotMatch(Guard, Expr), ok). +-else. +-define(assertNotMatch(Guard, Expr), + begin + ((fun () -> + __V = (Expr), + case __V of + Guard -> erlang:error({assertNotMatch, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {pattern, (??Guard)}, + {value, __V}]}); + _ -> ok + end + end)()) + end). +-endif. + +%% This is a convenience macro which gives more detailed reports when +%% the expected LHS value is not a pattern, but a computed value +-ifdef(NOASSERT). +-define(assertEqual(Expect, Expr), ok). +-else. +-define(assertEqual(Expect, Expr), + begin + ((fun (__X) -> + case (Expr) of + __X -> ok; + __V -> erlang:error({assertEqual, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {expected, __X}, + {value, __V}]}) + end + end)(Expect)) + end). +-endif. + +%% This is the inverse case of assertEqual, for convenience. +-ifdef(NOASSERT). +-define(assertNotEqual(Unexpected, Expr), ok). +-else. +-define(assertNotEqual(Unexpected, Expr), + begin + ((fun (__X) -> + case (Expr) of + __X -> erlang:error({assertNotEqual, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {value, __X}]}); + _ -> ok + end + end)(Unexpected)) + end). +-endif. + +%% Note: Class and Term are patterns, and can not be used for value. +%% Term can be a guarded pattern, but Class cannot. +-ifdef(NOASSERT). +-define(assertException(Class, Term, Expr), ok). +-else. +-define(assertException(Class, Term, Expr), + begin + ((fun () -> + try (Expr) of + __V -> erlang:error({assertException, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {pattern, + "{ "++(??Class)++" , "++(??Term) + ++" , [...] }"}, + {unexpected_success, __V}]}) + catch + Class:Term -> ok; + __C:__T -> + erlang:error({assertException, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {pattern, + "{ "++(??Class)++" , "++(??Term) + ++" , [...] }"}, + {unexpected_exception, + {__C, __T, + erlang:get_stacktrace()}}]}) + end + end)()) + end). +-endif. + +-define(assertError(Term, Expr), ?assertException(error, Term, Expr)). +-define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)). +-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)). + +%% This is the inverse case of assertException, for convenience. +%% Note: Class and Term are patterns, and can not be used for value. +%% Both Class and Term can be guarded patterns. +-ifdef(NOASSERT). +-define(assertNotException(Class, Term, Expr), ok). +-else. +-define(assertNotException(Class, Term, Expr), + begin + ((fun () -> + try (Expr) of + _ -> ok + catch + __C:__T -> + case __C of + Class -> + case __T of + Term -> + erlang:error({assertNotException, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {pattern, + "{ "++(??Class)++" , " + ++(??Term)++" , [...] }"}, + {unexpected_exception, + {__C, __T, + erlang:get_stacktrace() + }}]}); + _ -> ok + end; + _ -> ok + end + end + end)()) + end). +-endif. + +-endif. % ASSERT_HRL diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 170690ca89..7be2b77a3b 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -1231,11 +1231,11 @@ int erts_net_message(Port *prt, arg = erts_decode_dist_ext(&factory, &ede); if (is_non_value(arg)) { #ifdef ERTS_DIST_MSG_DBG - erts_fprintf(stderr, "DIST MSG DEBUG: erts_dist_ext_size(CTL) failed:\n"); + erts_fprintf(stderr, "DIST MSG DEBUG: erts_decode_dist_ext(CTL) failed:\n"); bw(buf, orig_len); #endif PURIFY_MSG("data error"); - goto data_error; + goto decode_error; } ctl_len = t - buf; @@ -1728,12 +1728,13 @@ int erts_net_message(Port *prt, erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg); erts_send_error_to_logger_nogl(dsbufp); } - data_error: +decode_error: PURIFY_MSG("data error"); erts_factory_close(&factory); if (ctl != ctl_default) { erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl); } +data_error: UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); erts_deliver_port_exit(prt, dep->cid, am_killed, 0); ERTS_SMP_CHK_NO_PROC_LOCKS; diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index a7d0511bf9..707de39556 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -752,6 +752,10 @@ erts_set_this_node(Eterm sysname, Uint creation) erts_this_dist_entry = erts_this_node->dist_entry; erts_refc_inc(&erts_this_dist_entry->refc, 2); + + erts_this_node_sysname = erts_this_node_sysname_BUFFER; + erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER), + "%T", sysname); } Uint diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam Binary files differindex df12c6f8e0..4a6fb6109f 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 863a5e61ef..cd2e7f18a2 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 dc8c711e1a..32d5d70122 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 73dfb3d351..9b0fc82bed 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 33c112f4de..c8166d5ed7 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 ebca6e7eea..ddcc3886a4 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 e8817d183e..97170551bf 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 8b87d1ae26..72065661c5 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 969239be98..2a0b33279d 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 281f668f8c..0d3d1d9343 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile index b9f2290289..1c05d454a5 100644 --- a/lib/inets/src/http_server/Makefile +++ b/lib/inets/src/http_server/Makefile @@ -137,7 +137,7 @@ release_spec: opt $(INSTALL_DIR) "$(RELSYSDIR)/src/http_server" $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/http_server" $(INSTALL_DIR) "$(RELSYSDIR)/ebin" - $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/http_server/httpd_custom_api.erl b/lib/inets/src/http_server/httpd_custom_api.erl index 282f3a6ee6..d5a6fa8715 100644 --- a/lib/inets/src/http_server/httpd_custom_api.erl +++ b/lib/inets/src/http_server/httpd_custom_api.erl @@ -23,7 +23,8 @@ -callback response_default_headers() -> [{Key::string(), Value::string()}]. -callback response_header({Key::string(), Value::string()}) -> - {true, {Key::string(), Value::string()}} | false. + {true, {Key::string(), Value::string()}} | false | + {true, string()}. %% Used internally to avoid traversing headers twice -callback request_header({Key::string(), Value::string()}) -> {true, {Key::string(), Value::string()}} | false. diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src index 2b9b8f5f32..883ba84e8e 100644 --- a/lib/inets/src/inets_app/inets.app.src +++ b/lib/inets/src/inets_app/inets.app.src @@ -65,6 +65,7 @@ httpd_connection_sup, httpd_conf, httpd_custom, + httpd_custom_api, httpd_esi, httpd_example, httpd_file, diff --git a/lib/sasl/doc/src/alarm_handler.xml b/lib/sasl/doc/src/alarm_handler.xml index b98f22d2a1..68076ba28d 100644 --- a/lib/sasl/doc/src/alarm_handler.xml +++ b/lib/sasl/doc/src/alarm_handler.xml @@ -37,94 +37,92 @@ <module>alarm_handler</module> <modulesummary>An Alarm Handling Process</modulesummary> <description> - <p>The alarm handler process is a <c>gen_event</c> event manager - process which receives alarms in the system. This process is not - intended to be a complete alarm handler. It defines a - place to which alarms can be sent. One simple event handler is - installed in the alarm handler at start-up, but users are - encouraged to write and install their own handlers. - </p> + <p>The alarm handler process is a + <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso> + event manager process that receives alarms in the system. + This process is not intended to be a complete alarm handler. + It defines a place to which alarms can be sent. One simple event + handler is installed in the alarm handler at startup, but users + are encouraged to write and install their own handlers.</p> <p>The simple event handler sends all alarms as info reports to - the error logger, and saves all of them in a list which can be - passed to a user defined event handler, which may be installed at - a later stage. The list can grow large if many alarms are - generated. So it is a good reason to install a better user defined - handler. - </p> - <p>There are functions to set and clear alarms. The format of - alarms are defined by the user. For example, an event handler - for SNMP could be defined, together with an alarm MIB. - </p> - <p>The alarm handler is part of the SASL application. - </p> + the error logger, and saves all in a list. This list can be + passed to a user-defined event handler, which can be installed + later. The list can grow large if many alarms are generated. + This is a good reason to install a better user-defined + handler.</p> + <p>Functions are provided to set and clear alarms. The alarm + format is defined by the user. For example, an event handler + for SNMP can be defined, together with an alarm Management + Information Base (MIB).</p> + <p>The alarm handler is part of the <c>SASL</c> application.</p> <p>When writing new event handlers for the alarm handler, the - following events must be handled: - </p> + following events must be handled:</p> <taglist> <tag><c>{set_alarm, {AlarmId, AlarmDescr}}</c></tag> <item> <p>This event is generated by - <c>alarm_handler:set_alarm({AlarmId, AlarmDecsr})</c>. - </p> + <c>alarm_handler:set_alarm({AlarmId, AlarmDecsr})</c>.</p> </item> <tag><c>{clear_alarm, AlarmId}</c></tag> <item> <p>This event is - generated by <c>alarm_handler:clear_alarm(AlarmId)</c>. - </p> + generated by <c>alarm_handler:clear_alarm(AlarmId)</c>.</p> </item> </taglist> <p>The default simple handler is called <c>alarm_handler</c> and - it may be exchanged by calling <c>gen_event:swap_handler/3</c> - as <c>gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, {NewHandler, Args})</c>. <c>NewHandler:init({Args, {alarm_handler, Alarms}})</c> is called. Refer to gen_event(3) - for further details. - </p> + it can be exchanged by calling + <seealso marker="stdlib:gen_event#swap_handler/3"><c>gen_event:swap_handler/3</c></seealso> + as <c>gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, + {NewHandler, Args})</c>. <c>NewHandler:init({Args, {alarm_handler, + Alarms}})</c> is called. For more details, see + <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso> + in <c>STDLIB</c>.</p> </description> + <funcs> <func> <name>clear_alarm(AlarmId) -> void()</name> - <fsummary>Clear the specified alarms</fsummary> + <fsummary>Clears the specified alarms.</fsummary> <type> <v>AlarmId = term()</v> </type> <desc> - <p>Sends the <c>clear_alarm</c> event to all event handlers.</p> + <p>Sends event <c>clear_alarm</c> to all event handlers.</p> <p>When receiving this event, the default simple handler - clears the latest received alarm with id <c>AlarmId</c>. - </p> + clears the latest received alarm with id <c>AlarmId</c>.</p> </desc> </func> + <func> <name>get_alarms() -> [alarm()]</name> - <fsummary>Get all active alarms</fsummary> + <fsummary>Gets all active alarms.</fsummary> <desc> <p>Returns a list of all active alarms. This function can only - be used when the simple handler is installed. - </p> + be used when the simple handler is installed.</p> </desc> </func> + <func> <name>set_alarm(alarm())</name> - <fsummary>Set an alarm with an id</fsummary> + <fsummary>Sets an alarm with an id.</fsummary> <type> <v>alarm() = {AlarmId, AlarmDescription}</v> <v>AlarmId = term()</v> <v>AlarmDescription = term()</v> </type> <desc> - <p>Sends the <c>set_alarm</c> event to all event handlers.</p> + <p>Sends event <c>set_alarm</c> to all event handlers.</p> <p>When receiving this event, the default simple handler - stores the alarm. The <c>AlarmId</c> identifies the alarm - and is used when the alarm is cleared. - </p> + stores the alarm. <c>AlarmId</c> identifies the alarm + and is used when the alarm is cleared.</p> </desc> </func> </funcs> <section> <title>See Also</title> - <p>error_logger(3), gen_event(3) - </p> + <p><seealso marker="kernel:error_logger"><c>error_logger(3)</c></seealso>, + <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso></p> </section> </erlref> diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml index 72333960ec..b54d2adb19 100644 --- a/lib/sasl/doc/src/appup.xml +++ b/lib/sasl/doc/src/appup.xml @@ -29,78 +29,85 @@ <rev></rev> </header> <file>appup</file> - <filesummary>Application upgrade file.</filesummary> + <filesummary>Application upgrade file</filesummary> <description> <p>The <em>application upgrade file</em> defines how an application is upgraded or downgraded in a running system.</p> - <p>This file is used by the functions in <c>systools</c> when - generating a release upgrade file <c>relup</c>.</p> + <p>This file is used by the functions in + <seealso marker="systools"><c>systools</c></seealso> + when generating a release upgrade file <c>relup</c>.</p> </description> <section> - <title>FILE SYNTAX</title> - <p>The application upgrade file should be called - <c>Application.appup</c> where <c>Application</c> is the name of - the application. The file should be located in the <c>ebin</c> + <title>File Syntax</title> + <p>The application upgrade file is to be called + <c>Application.appup</c>, where <c>Application</c> is the + application name. The file is to be located in the <c>ebin</c> directory for the application.</p> <p>The <c>.appup</c> file contains one single Erlang term, which defines the instructions used to upgrade or downgrade - the application. The file has the following syntax:</p> + the application. The file has the following syntax:</p> <code type="none"> {Vsn, [{UpFromVsn, Instructions}, ...], - [{DownToVsn, Instructions}, ...]}. - </code> - <list type="bulleted"> - <item> - <p><c>Vsn = string()</c> is the current version of - the application.</p> - </item> - <item> - <p><c>UpFromVsn = string() | binary()</c> is an earlier - version of the application to upgrade from. If it is a - string, it will be interpreted as a specific version - number. If it is a binary, it will be interpreted as a - regular expression which can match multiple version - numbers.</p> - </item> - <item> - <p><c>DownToVsn = string() | binary()</c> is an earlier - version of the application to downgrade to. If it is a - string, it will be interpreted as a specific version - number. If it is a binary, it will be interpreted as a - regular expression which can match multiple version - numbers.</p> - </item> - <item> - <p><c>Instructions</c> is a list of <em>release upgrade instructions</em>, see below. It is recommended to use + [{DownToVsn, Instructions}, ...]}.</code> + <taglist> + <tag><c>Vsn = string()</c></tag> + <item><p>Current application version.</p></item> + <tag><c>UpFromVsn = string() | binary()</c></tag> + <item><p>An earlier + application version to upgrade from. If it is a + string, it is interpreted as a specific version + number. If it is a binary, it is interpreted as a + regular expression that can match multiple version + numbers.</p></item> + <tag><c>DownToVsn = string() | binary()</c></tag> + <item><p>An earlier + application version to downgrade to. If it is a + string, it is interpreted as a specific version + number. If it is a binary, it is interpreted as a + regular expression that can match multiple version + numbers.</p></item> + <tag><c>Instructions</c></tag> + <item><p>A list of <em>release upgrade instructions</em>, see + <seealso marker="#Release Upgrade Instructions">Release + Upgrade Instructions</seealso>. It is recommended to use high-level instructions only. These are automatically translated to low-level instructions by <c>systools</c> when - creating the <c>relup</c> file.</p> - </item> - </list> - <p>In order to avoid duplication of upgrade instructions it is - allowed to use regular expressions to specify the <c>UpFromVsn</c> - and <c>DownToVsn</c>. To be considered a regular expression, the - version identifier must be specified as a binary, e.g.</p> - <code type="none"><<"2\\.1\\.[0-9]+">></code> - <p>will match all versions <c>2.1.x</c>, where x is any number.</p> - <p>Note that the regular expression must match the complete - version string, so the above example will work for for - e.g. <c>2.1.1</c>, but not for <c>2.1.1.1</c></p> + creating the <c>relup</c> file.</p></item> + </taglist> + <p>To avoid duplication of upgrade instructions, it is + allowed to use regular expressions to specify <c>UpFromVsn</c> + and <c>DownToVsn</c>. To be considered a regular expression, the + version identifier must be specified as a binary. For example, + the following match all versions <c>2.1.x</c>, where <c>x</c> is + any number:</p> + <code type="none"> +<<"2\\.1\\.[0-9]+">></code> + <p>Notice that the regular expression must match the complete + version string, so this example works for, for example, + <c>2.1.1</c>, but not for <c>2.1.1.1</c>.</p> </section> <section> - <title>RELEASE UPGRADE INSTRUCTIONS</title> + <marker id="Release Upgrade Instructions"></marker> + <title>Release Upgrade Instructions</title> <p>Release upgrade instructions are interpreted by the release handler when an upgrade or downgrade is made. For more - information about release handling, refer to <em>OTP Design Principles</em>.</p> - <p>A process is said to <em>use</em> a module <c>Mod</c>, if + information about release handling, see + <seealso marker="doc/design_principles:release_handling">OTP + Design Principles</seealso> in <em>System Documentation</em>.</p> + <p>A process is said to <em>use</em> a module <c>Mod</c> if <c>Mod</c> is listed in the <c>Modules</c> part of the child - specification used to start the process, see <c>supervisor(3)</c>. - In the case of gen_event, an event manager process is said to use - <c>Mod</c> if <c>Mod</c> is an installed event handler.</p> - <p><em>High-level instructions</em></p> + specification used to start the process, see + <seealso marker="stdlib:supervisor"><c>supervisor(3)</c></seealso>. + In the case of + <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso>, + an event manager process is said to use <c>Mod</c> if <c>Mod</c> + is an installed event handler.</p> + + <section> + <title>High-Level Instructions</title> <pre> {update, Mod} {update, Mod, supervisor} @@ -116,52 +123,68 @@ Change = soft | {advanced,Extra} Extra = term() PrePurge = PostPurge = soft_purge | brutal_purge - DepMods = [Mod] - </pre> - <p>Synchronized code replacement of processes using the module - <c>Mod</c>. All those processes are suspended using - <c>sys:suspend</c>, the new version of the module is loaded and - then the processes are resumed using <c>sys:resume</c>.</p> - <p><c>Change</c> defaults to <c>soft</c> and defines the type of - code change. If it is set to <c>{advanced,Extra}</c>, processes - implemented using gen_server, gen_fsm or gen_event will transform - their internal state by calling the callback function - <c>code_change</c>. Special processes will call the callback + DepMods = [Mod]</pre> + <p>Synchronized code replacement of processes using module + <c>Mod</c>.</p> + <p>All those processes are suspended using + <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso>, + the new module version is loaded, and + then the processes are resumed using + <seealso marker="stdlib:sys#resume/1"><c>sys:resume</c></seealso>.</p> + <taglist> + <tag><c>Change</c></tag> + <item><p>Defaults to <c>soft</c> and defines the type of + code change. If it is set to <c>{advanced,Extra}</c>, implemented + processes using + <seealso marker="stdlib:gen_server"><c>gen_server</c></seealso>, + <seealso marker="stdlib:gen_fsm"><c>gen_fsm</c></seealso>, or + <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso> + transform their internal state by calling the callback function + <c>code_change</c>. Special processes call the callback function <c>system_code_change/4</c>. In both cases, the term - <c>Extra</c> is passed as an argument to the callback function.</p> - <p><c>PrePurge</c> defaults to <c>brutal_purge</c> and controls - what action to take with processes that are executing old code - before loading the new version of the module. If the value + <c>Extra</c> is passed as an argument to the callback + function.</p></item> + <tag><c>PrePurge</c></tag> + <item><p>Defaults to <c>brutal_purge</c>. It controls + what action to take with processes executing old code + before loading the new module version. If the value is <c>brutal_purge</c>, the processes are killed. If the value is - <c>soft_purge</c>, <c>release_handler:install_release/1</c> - returns <c>{error,{old_processes,Mod}}</c>.</p> - <p><c>PostPurge</c> defaults to <c>brutal_purge</c> and controls + <c>soft_purge</c>, + <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1</c></seealso> + returns <c>{error,{old_processes,Mod}}</c>.</p></item> + <tag><c>PostPurge</c></tag> + <item><p>Defaults to <c>brutal_purge</c>. It controls what action to take with processes that are executing old code - when the new version of the module has been loaded. If the value + when the new module version has been loaded. If the value is <c>brutal_purge</c>, the code is purged when the release is made permanent and the processes are killed. If the value is - <c>soft_purge</c>, the release handler will purge the old code - when no remaining processes execute the code.</p> - <p><c>DepMods</c> defaults to [] and defines which other modules - <c>Mod</c> is dependent on. In <c>relup</c>, instructions for - suspending processes using <c>Mod</c> will come before + <c>soft_purge</c>, the release handler purges the old code + when no remaining processes execute the code.</p></item> + <tag><c>DepMods</c></tag> + <item><p>Defaults to <c>[]</c> and defines other modules that + <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions + for suspending processes using <c>Mod</c> come before instructions for suspending processes using modules in - <c>DepMods</c> when upgrading, and vice versa when downgrading. + <c>DepMods</c> when upgrading, and conversely when downgrading. In case of circular dependencies, the order of the instructions in - the <c>appup</c> script is kept.</p> - <p><c>Timeout</c> defines the timeout when suspending processes. - If no value or <c>default</c> is given, the default value for - <c>sys:suspend</c> is used.</p> - <p><c>ModType</c> defaults to <c>dynamic</c> and specifies if - the code is "dynamic", that is if a process using the module does - spontaneously switch to new code, or if it is "static". - When doing an advanced update and upgrading, the new version of a + the <c>appup</c> file is kept.</p></item> + <tag><c>Timeout</c></tag> + <item><p>Defines the time-out when suspending processes. + If no value or <c>default</c> is specified, the default value for + <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso> + is used.</p></item> + <tag><c>ModType</c></tag> + <item><p>Defaults to <c>dynamic</c>. It specifies if + the code is "dynamic", that is, if a process using the module + spontaneously switches to new code, or if it is "static". + When doing an advanced update and upgrade, the new version of a dynamic module is loaded before the process is asked to change code. When downgrading, the process is asked to change code before loading the new version. For static modules, the new version is loaded before the process is asked to change code, both in the case of upgrading and downgrading. Callback modules are - dynamic.</p> + dynamic.</p></item> + </taglist> <p><c>update</c> with argument <c>supervisor</c> is used when changing the start specification of a supervisor.</p> <pre> @@ -170,239 +193,229 @@ {load_module, Mod, PrePurge, PostPurge, DepMods} Mod = atom() PrePurge = PostPurge = soft_purge | brutal_purge - DepMods = [Mod] - </pre> + DepMods = [Mod]</pre> <p>Simple code replacement of the module <c>Mod</c>.</p> - <p>See <c>update</c> above for a description of <c>PrePurge</c> and - <c>PostPurge</c>.</p> - <p><c>DepMods</c> defaults to [] and defines which other modules - <c>Mod</c> is dependent on. In <c>relup</c>, instructions for - loading these modules will come before the instruction for loading - <c>Mod</c> when upgrading, and vice versa when downgrading.</p> + <p>For a description of <c>PrePurge</c> and <c>PostPurge</c>, + see <c>update</c> above.</p> + <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules + <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions for + loading these modules come before the instruction for loading + <c>Mod</c> when upgrading, and conversely when downgrading.</p> <pre> {add_module, Mod} {add_module, Mod, DepMods} Mod = atom() - DepMods = [Mod] - </pre> + DepMods = [Mod]</pre> <p>Loads a new module <c>Mod</c>.</p> - <p><c>DepMods</c> defaults to [] and defines which other modules - <c>Mod</c> is dependent on. In <c>relup</c>, instructions - related to these modules will come before the instruction for - loading <c>Mod</c> when upgrading, and vice versa when + <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules + <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions + related to these modules come before the instruction for + loading <c>Mod</c> when upgrading, and conversely when downgrading.</p> <pre> {delete_module, Mod} {delete_module, Mod, DepMods} - Mod = atom() - </pre> + Mod = atom()</pre> <p>Deletes a module <c>Mod</c> using the low-level instructions <c>remove</c> and <c>purge</c>.</p> - <p><c>DepMods</c> defaults to [] and defines which other modules - <c>Mod</c> is dependent on. In <c>relup</c>, instructions - related to these modules will come before the instruction for - removing <c>Mod</c> when upgrading, and vice versa when + <p><c>DepMods</c> defaults to <c>[]</c> and defines which other modules + <c>Mod</c> is dependent on. In the <c>relup</c> file, instructions + related to these modules come before the instruction for + removing <c>Mod</c> when upgrading, and conversely when downgrading.</p> <pre> {add_application, Application} {add_application, Application, Type} Application = atom() - Type = permanent | transient | temporary | load | none - </pre> + Type = permanent | transient | temporary | load | none</pre> <p>Adding an application means that the modules defined by the <c>modules</c> key in the <c>.app</c> file are loaded using <c>add_module</c>.</p> <p><c>Type</c> defaults to <c>permanent</c> and specifies the start type of the application. If <c>Type = permanent | transient | temporary</c>, - the application will be loaded and started in the corresponding way, - see <c>application(3)</c>. If <c>Type = load</c>, the application will - only be loaded. If <c>Type = none</c>, the application will be neither - loaded nor started, although the code for its modules will be loaded.</p> + the application is loaded and started in the corresponding way, see + <seealso marker="kernel:application"><c>application(3)</c></seealso>. + If <c>Type = load</c>, the application is only loaded. + If <c>Type = none</c>, the application is not loaded and not + started, although the code for its modules is loaded.</p> <pre> {remove_application, Application} - Application = atom() - </pre> + Application = atom()</pre> <p>Removing an application means that the application is stopped, - the modules are unloaded using <c>delete_module</c> and then + the modules are unloaded using <c>delete_module</c>, and then the application specification is unloaded from the application controller.</p> <pre> {restart_application, Application} - Application = atom() - </pre> + Application = atom()</pre> <p>Restarting an application means that the application is - stopped and then started again similar to using the instructions + stopped and then started again, similar to using the instructions <c>remove_application</c> and <c>add_application</c> in sequence.</p> - <p><em>Low-level instructions</em></p> + </section> + + <section> + <title>Low-Level Instructions</title> <pre> {load_object_code, {App, Vsn, [Mod]}} App = Mod = atom() - Vsn = string() - </pre> - <p>Reads each <c>Mod</c> from the directory <c>App-Vsn/ebin</c> as - a binary. It does not load the modules. The instruction should be - placed first in the script in order to read all new code from file - to make the suspend-load-resume cycle less time consuming. After - this instruction has been executed, the code server with the new - version of <c>App</c>.</p> + Vsn = string()</pre> + <p>Reads each <c>Mod</c> from directory <c>App-Vsn/ebin</c> as + a binary. It does not load the modules. The instruction is to be + placed first in the script to read all new code from the file + to make the suspend-load-resume cycle less time-consuming.</p> <pre> -point_of_no_return - </pre> +point_of_no_return</pre> <p>If a crash occurs after this instruction, the system cannot - recover and is restarted from the old version of the release. - The instruction must only occur once in a script. It should be + recover and is restarted from the old release version. + The instruction must only occur once in a script. It is to be placed after all <c>load_object_code</c> instructions.</p> <pre> {load, {Mod, PrePurge, PostPurge}} Mod = atom() - PrePurge = PostPurge = soft_purge | brutal_purge - </pre> + PrePurge = PostPurge = soft_purge | brutal_purge</pre> <p>Before this instruction occurs, <c>Mod</c> must have been loaded using <c>load_object_code</c>. This instruction loads the module. - <c>PrePurge</c> is ignored. See the high-level instruction - <c>update</c> for a description of <c>PostPurge</c>.</p> + <c>PrePurge</c> is ignored. For a description of <c>PostPurge</c>, + see the high-level instruction <c>update</c> earlier.</p> <pre> {remove, {Mod, PrePurge, PostPurge}} Mod = atom() - PrePurge = PostPurge = soft_purge | brutal_purge - </pre> + PrePurge = PostPurge = soft_purge | brutal_purge</pre> <p>Makes the current version of <c>Mod</c> old. - <c>PrePurge</c> is ignored. See the high-level instruction - <c>update</c> for a description of <c>PostPurge</c>.</p> + <c>PrePurge</c> is ignored. For a description of <c>PostPurge</c>, + see the high-level instruction <c>update</c> earlier.</p> <pre> {purge, [Mod]} - Mod = atom() - </pre> - <p>Purges each module <c>Mod</c>, that is removes the old code. - Note that any process executing purged code is killed.</p> + Mod = atom()</pre> + <p>Purges each module <c>Mod</c>, that is, removes the old code. + Notice that any process executing purged code is killed.</p> <pre> {suspend, [Mod | {Mod, Timeout}]} Mod = atom() - Timeout = int()>0 | default | infinity - </pre> + Timeout = int()>0 | default | infinity</pre> <p>Tries to suspend all processes using a module <c>Mod</c>. If a - process does not respond, it is ignored. This may cause + process does not respond, it is ignored. This can cause the process to die, either because it crashes when it spontaneously switches to new code, or as a result of a purge operation. If no <c>Timeout</c> is specified or <c>default</c> is - given, the default value for <c>sys:suspend</c> is used.</p> + specified, the default value for + <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso> + is used.</p> <pre> {resume, [Mod]} - Mod = atom() - </pre> + Mod = atom()</pre> <p>Resumes all suspended processes using a module <c>Mod</c>.</p> <pre> {code_change, [{Mod, Extra}]} {code_change, Mode, [{Mod, Extra}]} Mod = atom() Mode = up | down - Extra = term() - </pre> + Extra = term()</pre> <p><c>Mode</c> defaults to <c>up</c> and specifies if it is an - upgrade or downgrade.</p> - <p>This instruction sends a <c>code_change</c> system message to - all processes using a module <c>Mod</c> by calling the function - <c>sys:change_code</c>, passing the term <c>Extra</c> as argument.</p> + upgrade or downgrade. This instruction sends a <c>code_change</c> + system message to all processes using a module <c>Mod</c> by + calling function + <seealso marker="stdlib:sys#change_code/4"><c>sys:change_code</c></seealso>, + passing term <c>Extra</c> as argument.</p> <pre> {stop, [Mod]} - Mod = atom() - </pre> + Mod = atom()</pre> <p>Stops all processes using a module <c>Mod</c> by calling - <c>supervisor:terminate_child/2</c>. The instruction is useful + <seealso marker="stdlib:supervisor#terminate_child/2"><c>supervisor:terminate_child/2</c></seealso>. + This instruction is useful when the simplest way to change code is to stop and restart the - processes which run the code.</p> + processes that run the code.</p> <pre> {start, [Mod]} - Mod = atom() - </pre> + Mod = atom()</pre> <p>Starts all stopped processes using a module <c>Mod</c> by calling - <c>supervisor:restart_child/2</c>.</p> + <seealso marker="stdlib:supervisor#restart_child/2"><c>supervisor:restart_child/2</c></seealso>.</p> <pre> {sync_nodes, Id, [Node]} {sync_nodes, Id, {M, F, A}} Id = term() Node = node() M = F = atom() - A = [term()] - </pre> + A = [term()]</pre> <p><c>apply(M, F, A)</c> must return a list of nodes.</p> - <p>The instruction synchronizes the release installation with other - nodes. Each <c>Node</c> must evaluate this command, with the same + <p>This instruction synchronizes the release installation with other + nodes. Each <c>Node</c> must evaluate this command with the same <c>Id</c>. The local node waits for all other nodes to evaluate - the instruction before execution continues. In case a node goes + the instruction before execution continues. If a node goes down, it is considered to be an unrecoverable error, and the local node is restarted from the old release. There is no - timeout for this instruction, which means that it may hang + time-out for this instruction, which means that it can hang forever.</p> <pre> {apply, {M, F, A}} M = F = atom() - A = [term()] - </pre> - <p>Evaluates <c>apply(M, F, A)</c>. If the instruction appears - before the <c>point_of_no_return</c> instruction, a failure is - caught. <c>release_handler:install_release/1</c> then returns - <c>{error,{'EXIT',Reason}}</c>, unless <c>{error,Error}</c> is - thrown or returned. Then it returns <c>{error,Error}</c>.</p> - <p>If the instruction appears after the <c>point_of_no_return</c> - instruction, and the function call fails, the system is - restarted.</p> + A = [term()]</pre> + <p>Evaluates <c>apply(M, F, A)</c>.</p> + <p>If the instruction appears before instruction + <c>point_of_no_return</c>, a failure is caught. + <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1</c></seealso> + then returns <c>{error,{'EXIT',Reason}}</c>, unless <c>{error,Error}</c> + is thrown or returned. Then it returns <c>{error,Error}</c>.</p> + <p>If the instruction appears after instruction + <c>point_of_no_return</c> and the function call fails, the + system is restarted.</p> <pre> -restart_new_emulator - </pre> - <p>This instruction is used when erts, kernel, stdlib or sasl is +restart_new_emulator</pre> + <p>This instruction is used when the application <c>ERTS</c>, + <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c> is upgraded. It shuts down the current emulator and starts a new one. All processes are terminated gracefully, and the new - version of erts, kernel, stdlib and sasl are used when the - emulator restarts. Only one <c>restart_new_emulator</c> - instruction is allowed in the relup, and it shall be placed - first. <seealso marker="systools#make_relup/3">systools:make_relup/3,4</seealso> - will ensure this when the relup is generated. The rest of the - relup script is executed after the restart as a part of the boot - script.</p> - <p>An info report will be written when the upgrade is - completed. To programatically find out if the upgrade is - complete, + version of <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and + <c>SASL</c> are used when the emulator restarts. + Only one <c>restart_new_emulator</c> instruction is allowed + in the <c>relup</c> file, and it must be placed first. + <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso> + ensures this when the <c>relup</c> file is generated. The rest of the + instructions in the <c>relup</c> file is executed after the + restart as a part of the boot script.</p> + <p>An info report is written when the upgrade is completed. + To programmatically determine if the upgrade is complete, call <seealso marker="release_handler#which_releases/0"> - release_handler:which_releases/0,1</seealso> and check if the + <c>release_handler:which_releases/0,1</c></seealso> and check if the expected release has status <c>current</c>.</p> <p>The new release must still be made permanent after the upgrade - is completed. Otherwise, the old emulator is started in case of + is completed, otherwise the old emulator is started if there is an emulator restart.</p> <warning> - <p>As stated above, the <c>restart_new_emulator</c> - instruction causes the emulator to be restarted with new - versions of <c>erts</c>, <c>kernel</c>, <c>stdlib</c> and - <c>sasl</c>. All other applications, however, will at startup - be running their old versions in this new emulator. In most - cases this is no problem, but every now and then there will be - incompatible changes to the core applications which may cause - trouble in this setting. Such incompatible changes (when - functions are removed) are normally preceded by a deprecation - over two major releases. To make sure your application is not - crashed by an incompatible change, always remove any call to - deprecated functions as soon as possible.</p> + <p>As stated earlier, instruction <c>restart_new_emulator</c> + causes the emulator to be restarted with new versions of + <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and <c>SASL</c>. + However, all other applications do at startup run their old + versions in this new emulator. This is usually no problem, + but every now and then incompatible changes occur to the + core applications, which can cause + trouble in this setting. Such incompatible changes (when + functions are removed) are normally preceded by a deprecation + over two major releases. To ensure that your application is not + crashed by an incompatible change, always remove any call to + deprecated functions as soon as possible.</p> </warning> <pre> -restart_emulator - </pre> +restart_emulator</pre> <p>This instruction is similar to <c>restart_new_emulator</c>, - except it shall be placed at the end of the relup script. It is - not related to an upgrade of the emulator or the core + except it must be placed at the end of the <c>relup</c> file. + It is not related to an upgrade of the emulator or the core applications, but can be used by any application when a complete - reboot of the system is reqiured. When generating the - relup, <seealso marker="systools#make_relup/3">systools:make_relup/3,4</seealso> + reboot of the system is required.</p> + <p>When generating the <c>relup</c> file, + <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso> ensures that there is only one <c>restart_emulator</c> - instruction and that it is the last instruction of the - relup.</p> + instruction and that it is the last instruction in the + <c>relup</c> file.</p> + </section> </section> <section> - <title>SEE ALSO</title> - <p><seealso marker="relup">relup(4)</seealso>, - <seealso marker="release_handler">release_handler(3)</seealso>, - supervisor(3), - <seealso marker="systools">systools(3)</seealso></p> + <title>See Also</title> + <p><seealso marker="release_handler"><c>release_handler(3)</c></seealso>, + <seealso marker="relup"><c>relup(4)</c></seealso>, + <seealso marker="stdlib:supervisor"><c>supervisor(3)</c></seealso>, + <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </fileref> diff --git a/lib/sasl/doc/src/book.xml b/lib/sasl/doc/src/book.xml index 2bb5339d94..624c32a66f 100644 --- a/lib/sasl/doc/src/book.xml +++ b/lib/sasl/doc/src/book.xml @@ -22,7 +22,7 @@ </legalnotice> - <title>System Application Support Libraries (SASL)</title> + <title>System Architecture Support Libraries (SASL)</title> <prepared>OTP Team</prepared> <docno></docno> <date>1999-04-22</date> @@ -31,7 +31,7 @@ </header> <insidecover> </insidecover> - <pagetext>System Application Support Libraries (SASL)</pagetext> + <pagetext>System Architecture Support Libraries (SASL)</pagetext> <preamble> <contents level="2"></contents> </preamble> diff --git a/lib/sasl/doc/src/error_logging.xml b/lib/sasl/doc/src/error_logging.xml index 7c45b1970e..46b12f3872 100644 --- a/lib/sasl/doc/src/error_logging.xml +++ b/lib/sasl/doc/src/error_logging.xml @@ -31,89 +31,93 @@ <date>1999-04-13</date> <rev>B</rev> <file>error_logging.xml</file> - </header> - <p>The SASL application introduces three types of reports:</p> + </header> + <p>The <c>SASL</c> application introduces three types of reports:</p> <list type="bulleted"> - <item>supervisor report</item> - <item>progress report</item> - <item>crash report.</item> + <item>Supervisor report</item> + <item>Progress report</item> + <item>Crash report</item> </list> - <p>When the SASL application is started, it adds a handler that - formats and writes these reports, as specified in the - configuration parameters for sasl, i.e the environment variables - in the SASL application specification, which is found in the - <c>.app</c> file of SASL. See - <seealso marker="sasl_app">sasl(Application)</seealso>, and app(File) - in the Kernel Reference Manual - for the details.</p> + <p>When the <c>SASL</c> application is started, it adds a handler that + formats and writes these reports, as specified in the configuration + parameters for <c>SASL</c>, that is, the environment variables + in the <c>SASL</c> application specification, which is found in the + <c>.app</c> file of <c>SASL</c>. For details, see the + <seealso marker="sasl_app"><c>sasl(6)</c></seealso> application in the + Reference Manual and the <seealso marker="kernel:app"><c>app(4)</c></seealso> + file in the <c>Kernel</c> Reference Manual.</p> <section> <title>Supervisor Report</title> - <p>A supervisor report is issued when a supervised child terminates in - an unexpected way. A supervisor report contains the following + <p>A supervisor report is issued when a supervised child terminates + unexpectedly. A supervisor report contains the following items:</p> <taglist> - <tag>Supervisor.</tag> - <item>The name of the reporting supervisor.</item> - <tag>Context.</tag> - <item>Indicates in which phase the child terminated + <tag><c>Supervisor</c></tag> + <item><p>Name of the reporting supervisor.</p></item> + <tag><c>Context</c></tag> + <item><p>Indicates in which phase the child terminated from the supervisor's point of view. This can be - <c>start_error</c>, <c>child_terminated</c>, or - <c>shutdown_error</c>.</item> - <tag>Reason.</tag> - <item>The termination reason.</item> - <tag>Offender.</tag> - <item>The start specification for the child.</item> + <c>start_error</c>, <c>child_terminated</c>, or + <c>shutdown_error</c>.</p></item> + <tag><c>Reason</c></tag> + <item><p>Termination reason.</p></item> + <tag><c>Offender</c></tag> + <item><p>Start specification for the child.</p></item> </taglist> </section> <section> <title>Progress Report</title> - <p>A progress report is issued whenever a supervisor starts or - restarts. A progress report contains the following items:</p> + <p>A progress report is issued when a supervisor starts or + restarts a child. A progress report contains the following items:</p> <taglist> - <tag>Supervisor.</tag> - <item>The name of the reporting supervisor.</item> - <tag>Started.</tag> - <item>The start specification for the successfully - started child.</item> + <tag><c>Supervisor</c></tag> + <item><p>Name of the reporting supervisor.</p></item> + <tag><c>Started</c></tag> + <item><p>Start specification for the successfully + started child.</p></item> </taglist> <marker id="CRASH"></marker> </section> <section> <title>Crash Report</title> - <p>Processes started with the <c>proc_lib:spawn</c> or - <c>proc_lib:spawn_link</c> functions are wrapped within a - <c>catch</c>. A crash report is issued whenever such a process - terminates with an unexpected reason, which is any reason other - than <c>normal</c> or <c>shutdown</c>. Processes using the - <c>gen_server</c> and <c>gen_fsm</c> behaviours are examples of - such processes. A crash report contains the following items:</p> + <p>Processes started with functions + <seealso marker="stdlib:proc_lib#spawn/1"><c>proc_lib:spawn</c></seealso> or + <seealso marker="stdlib:proc_lib#spawn_link/1"><c>proc_lib:spawn_link</c></seealso> + are wrapped within a <c>catch</c>. A crash report is issued when such + a process terminates with an unexpected reason, which is any reason + other than <c>normal</c>, <c>shutdown</c>, or <c>{shutdown,Term}</c>. + Processes using behaviors + <seealso marker="stdlib:gen_server"><c>gen_server</c></seealso> or + <seealso marker="stdlib:gen_fsm"><c>gen_fsm</c></seealso> + are examples of such processes. A crash report contains the following items:</p> <taglist> - <tag>Crasher.</tag> - <item>Information about the crashing process is reported, such - as initial function call, exit reason, and message queue.</item> - <tag>Neighbours.</tag> - <item>Information about processes which are linked to the crashing + <tag><c>Crasher</c></tag> + <item><p>Information about the crashing process, such + as initial function call, exit reason, and message queue.</p></item> + <tag><c>Neighbours</c></tag> + <item><p>Information about processes that are linked to the crashing process and do not trap exits. These processes are the - neighbours which will terminate because of this process + neighbours that terminate because of this process crash. The information gathered is the same as the information - for Crasher, shown in the previous item.</item> + for Crasher, described in the previous item.</p></item> </taglist> <section> - <title>An Example</title> - <p>The following example shows the reports which are generated - when a process crashes. The example process is an + <title>Example</title> + <p>The following example shows the reports generated + when a process crashes. The example process is a <c>permanent</c> process supervised by the <c>test_sup</c> supervisor. A division by zero is executed and the error is first reported by the faulty process. A crash report is - generated as the process was started using the - <c>proc_lib:spawn/3</c> function. The supervisor generates a - supervisor report showing the process that has crashed, and then a + generated, as the process was started using function + <seealso marker="stdlib:proc_lib#spawn/3"><c>proc_lib:spawn/3</c></seealso>. + The supervisor generates a + supervisor report showing the crashed process. A progress report is generated when the process is finally - re-started.</p> + restarted.</p> <pre> =ERROR REPORT==== 27-May-1996::13:38:56 === <0.63.0>: Divide by zero ! @@ -146,7 +150,6 @@ {shutdown,200}, {child_type,worker}] - =PROGRESS REPORT==== 27-May-1996::13:38:56 === Supervisor: {local,test_sup} Started: [{pid,<0.64.0>}, @@ -154,64 +157,66 @@ {mfa,{test,t,[]}}, {restart_type,permanent}, {shutdown,200}, - {child_type,worker}] - </pre> + {child_type,worker}]</pre> </section> </section> <section> <title>Multi-File Error Report Logging</title> - <p>Multi-file error report logging is used to store error messages, - which are received by the <c>error_logger</c>. The error messages + <p>Multi-file error report logging is used to store error messages + received by <c>error_logger</c>. The error messages are stored in several files and each file is smaller than a - specified amount of kilobytes, and no more than a specified number - of files exist at the same time. The logging is very fast because + specified number of kilobytes. No more than a specified number + of files exist at the same time. The logging is very fast, as each error message is written as a binary term.</p> - <p>Refer to - <c>sasl</c> application in the Reference Manual for more details.</p> + <p>For more details, see the + <seealso marker="sasl_app"><c>sasl(6)</c></seealso> + application in the Reference Manual.</p> </section> <section> <title>Report Browser</title> <p>The report browser is used to browse and format error reports - written by the error logger handler <c>log_mf_h</c> defined in - <c>stdlib</c>.</p> + written by the error logger handler + <seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso> + defined in <c>STDLIB</c>.</p> <p>The <c>log_mf_h</c> handler writes all reports to a - report logging directory. This directory is specified when - configuring the SASL application.</p> + report logging directory, which is specified when + configuring the <c>SASL</c> application.</p> <p>If the report browser is - used off-line, the reports can be copied to another directory - which is specified when starting the browser. If no such directory - is specified, the browser reads reports from the SASL + used offline, the reports can be copied to another directory + specified when starting the browser. If no such directory + is specified, the browser reads reports from the <c>SASL</c> <c>error_logger_mf_dir</c>.</p> <section> - <title>Starting the Report Browser</title> - <p>Start the <c>rb_server</c> with the function - <c>rb:start([Options])</c> as shown in the following - example:</p> + <title>Starting Report Browser</title> + <p>Start the <c>rb_server</c> with function + <seealso marker="rb#start/1"><c>rb:start([Options])</c></seealso> + as shown in the following example:</p> <pre> - - 5><input>rb:start([{max, 20}]).</input> + 5> <input>rb:start([{max, 20}]).</input> rb: reading report...done. rb: reading report...done. rb: reading report...done. rb: reading report...done. - </pre> + {ok,<0.199.0>}</pre> </section> <section> - <title>On-line Help</title> - <p>Enter the command <em>rb:help().</em> to access the report - browser on-line help system.</p> + <title>Online Help</title> + <p>Enter command + <seealso marker="rb#help/0"><c>rb:help()</c></seealso> + to access the report browser online help system.</p> </section> <section> - <title>List Reports in the Server</title> - <p>The function <c>rb:list()</c> lists all loaded reports:</p> + <title>List Reports in Server</title> + <p>Use function + <seealso marker="rb#list/0"><c>rb:list()</c></seealso> + to list all loaded reports:</p> <pre> - - 4><input>rb:list().</input> + 4> <input>rb:list().</input> No Type Process Date Time == ==== ======= ==== ==== 20 progress <0.17.0> 1996-10-16 16:14:54 @@ -234,17 +239,15 @@ 3 progress <0.14.0> 1996-10-16 16:16:36 2 error <0.15.0> 1996-10-16 16:17:04 1 progress <0.14.0> 1996-10-16 16:17:09 - ok - </pre> + ok</pre> </section> <section> <title>Show Reports</title> - <p>To show details of a specific report, use the function - <c>rb:show(Number)</c>:</p> + <p>Use function + <seealso marker="rb#show/1"><c>rb:show(Number)</c></seealso> + to show details of a specific report:</p> <pre> - -10> <input>rb:show(1).</input> 7> <input>rb:show(4).</input> PROGRESS REPORT <0.20.0> 1996-10-16 16:16:36 @@ -259,7 +262,7 @@ started {child_type,worker}] ok -8> rb:show(9). +8> <input>rb:show(9).</input> CRASH REPORT <0.24.0> 1996-10-16 16:16:21 =============================================================================== @@ -287,19 +290,17 @@ heap_size 610 stack_size 142 reductions 54 -ok - </pre> +ok</pre> </section> <section> - <title>Search the Reports</title> - <p>It is possible to show all reports which contain a common - pattern. Suppose a process crashes because it tries to call a - non-existing function <c>release_handler:mbj_func.</c> We could - then show reports as follows:</p> + <title>Search Reports</title> + <p>All reports containing a common pattern can be shown. + Suppose a process crashes because it tries to call a + non-existing function <c>release_handler:mbj_func/1</c>. + The reports can then be shown as follows:</p> <pre> - -12><input>rb:grep("mbj_func").</input> +12> <input>rb:grep("mbj_func").</input> Found match in report number 11 ERROR REPORT <0.24.0> 1996-10-16 16:16:21 @@ -368,19 +369,17 @@ restart_type permanent shutdown 2000 child_type worker -ok - </pre> +ok</pre> </section> <section> - <title>Stop the Server</title> - <p>Stop the <c>rb_server</c> with the function - <c>rb:stop()</c>:</p> + <title>Stop Server</title> + <p>Use function + <seealso marker="rb#stop/0"><c>rb:stop()</c></seealso> + to stop the <c>rb_server</c>:</p> <pre> - -13><input>rb:stop().</input> -ok - </pre> +13> <input>rb:stop().</input> +ok</pre> </section> </section> </chapter> diff --git a/lib/sasl/doc/src/overload.xml b/lib/sasl/doc/src/overload.xml index 35877220ab..5c3d00afeb 100644 --- a/lib/sasl/doc/src/overload.xml +++ b/lib/sasl/doc/src/overload.xml @@ -35,98 +35,88 @@ <module>overload</module> <modulesummary>An Overload Regulation Process</modulesummary> <description> - <p><c>overload</c> is a process which indirectly regulates CPU + <p><c>overload</c> is a process that indirectly regulates the CPU usage in the system. The idea is that a main application calls - the <c>request/0</c> function before starting a major job, and + function + <seealso marker="#request/0"><c>request/0</c></seealso> + before starting a major job and proceeds with the job if the return value is positive; otherwise - the job must not be started. - </p> - <p><c>overload</c> is part of the <c>sasl</c> application, and all - configuration parameters are defined there. - </p> - <p>A set of two intensities are maintained, the <c>total intensity</c> and the <c>accept intensity</c>. For that purpose - there are two configuration parameters, the <c>MaxIntensity</c> - and the <c>Weight</c> value (both are measured in 1/second). - </p> + the job must not be started.</p> + <p><c>overload</c> is part of the <c>SASL</c> application and all + configuration parameters are defined there.</p> + <p>A set of two intensities are maintained, the <c>total intensity</c> + and the <c>accept intensity</c>. For that purpose, + there are two configuration parameters, <c>MaxIntensity</c> + and <c>Weight</c>; both are measured in 1/second.</p> <p>Then total and accept intensities are calculated as follows. Assume that the time of the current call to - <c>request/0</c> is <c>T(n)</c>, and that the time of the - previous call was <c>T(n-1)</c>. - </p> + <c>request/0</c> is <c>T(n)</c> and that the time of the + previous call was <c>T(n-1)</c>.</p> <list type="bulleted"> <item> <p>The current <c>total intensity</c>, denoted - <c>TI(n)</c>, is calculated according to the formula, - </p> - <p><c>TI(n) = exp(-Weight*(T(n) - T(n-1)) * TI(n-1) + Weight</c>, - </p> - <p>where <c>TI(n-1)</c> is the previous total intensity. - </p> + <c>TI(n)</c>, is calculated according to the formula</p> + <p><c>TI(n) = exp(-Weight*(T(n) - T(n-1)) * TI(n-1) + Weight</c>,</p> + <p>where <c>TI(n-1)</c> is the previous <c>total intensity</c>.</p> </item> <item> <p>The current <c>accept intensity</c>, denoted - <c>AI(n)</c>, is determined by the formula, - </p> - <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1) + Weight</c>, - </p> - <p>where <c>AI(n-1)</c> is the previous accept intensity, - provided that the value of <c>exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c> is less than <c>MaxIntensity</c>; otherwise the - value is - </p> - <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c>. - </p> + <c>AI(n)</c>, is determined by the formula</p> + <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1) + Weight</c>,</p> + <p>where <c>AI(n-1)</c> is the previous <c>accept intensity</c>, + if the value of <c>exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c> + is less than <c>MaxIntensity</c>. Otherwise the value is</p> + <p><c>AI(n) = exp(-Weight*(T(n) - T(n-1)) * AI(n-1)</c></p> </item> </list> <p>The value of configuration parameter <c>Weight</c> controls the - speed with which the calculations of intensities will react to + speed with which the calculations of intensities react to changes in the underlying input intensity. The inverted value of - <c>Weight</c>, - </p> - <p><c>T = 1/Weight</c></p> - <p>can be thought of as the "time constant" - of the intensity calculation formulas. For example, if <c>Weight = 0.1</c>, then a change in the underlying input intensity will be - reflected in the <c>total</c> and <c>accept intensities</c> within - approximately 10 seconds. - </p> + <c>Weight</c>, <c>T = 1/Weight</c>, can be thought of as the + "time constant" of the intensity calculation formulas. For example, + if <c>Weight = 0.1</c>, a change in the underlying input intensity is + reflected in <c>total intensity</c> and <c>accept intensity</c> within + about 10 seconds.</p> <p>The overload process defines one alarm, which it sets using - <c>alarm_handler:set_alarm(Alarm)</c>. <c>Alarm</c> is defined - as: - </p> + <c>alarm_handler:set_alarm(Alarm)</c>. <c>Alarm</c> is defined + as follows:</p> <taglist> <tag><c>{overload, []}</c></tag> <item> - <p>This alarm is set when the current accept intensity exceeds - <c>MaxIntensity</c>. - </p> + <p>This alarm is set when the current <c>accept intensity</c> exceeds + <c>MaxIntensity</c>.</p> </item> </taglist> - <p>A new overload alarm is not set until the current accept - intensity has fallen below <c>MaxIntensity</c>. To prevent the - overload process from generating a lot of set/reset alarms, the - alarm is not reset until the current accept intensity has fallen - below 75% of <c>MaxIntensity</c>, and it is not until then that - the alarm can be set again. - </p> + <p>A new request is not accepted until the current <c>accept + intensity</c> has fallen below <c>MaxIntensity</c>. To prevent the + overload process from generating many set/reset alarms, the + alarm is not reset until the current <c>accept intensity</c> has fallen + below 75% of <c>MaxIntensity</c>; it is not until then that + the alarm can be set again.</p> </description> + <funcs> <func> <name>request() -> accept | reject</name> - <fsummary>Request to proceed with current job</fsummary> + <fsummary>Requests to proceed with current job.</fsummary> <desc> <p>Returns <c>accept</c> or <c>reject</c> depending on the - current value of the accept intensity. </p> + current value of the <c>accept intensity</c>.</p> <p>The application - calling this function should be processed with the job in + calling this function is to proceed with the job in question if the return value is <c>accept</c>; otherwise it - should not continue with that job. - </p> + is not to continue with that job.</p> </desc> </func> + <func> <name>get_overload_info() -> OverloadInfo</name> - <fsummary>Return current overload information data</fsummary> + <fsummary>Returns current overload information data.</fsummary> <type> - <v>OverloadInfo = [{total_intensity, TotalIntensity}, {accept_intensity, AcceptIntensity}, {max_intensity, MaxIntensity}, {weight, Weight}, {total_requests, TotalRequests}, {accepted_requests, AcceptedRequests}].</v> + <v>OverloadInfo = [{total_intensity, TotalIntensity}, + {accept_intensity, AcceptIntensity}, {max_intensity, + MaxIntensity}, {weight, Weight}, {total_requests, + TotalRequests}, {accepted_requests, AcceptedRequests}].</v> <v>TotalIntensity = float() > 0</v> <v>AcceptIntensity = float() > 0</v> <v>MaxIntensity = float() > 0</v> @@ -135,18 +125,22 @@ <v>AcceptedRequests = integer()</v> </type> <desc> - <p>Returns the current total and accept intensities, the - configuration parameters, and absolute counts of the total - number of requests, and accepted number of requests (since - the overload process was started).</p> + <p>Returns:</p> + <list type="bulleted"> + <item>Current total and accept intensities</item> + <item>Configuration parameters</item> + <item>Absolute counts of the total number of requests</item> + <item>Accepted number of requests (since the overload + process was started)</item> + </list> </desc> </func> </funcs> <section> <title>See Also</title> - <p>alarm_handler(3), sasl(3) - </p> + <p><seealso marker="alarm_handler"><c>alarm_handler(3)</c></seealso>, + <seealso marker="sasl_app"><c>sasl(6)</c></seealso></p> </section> </erlref> diff --git a/lib/sasl/doc/src/part.xml b/lib/sasl/doc/src/part.xml index bcd345a7c4..2f47a8ad80 100644 --- a/lib/sasl/doc/src/part.xml +++ b/lib/sasl/doc/src/part.xml @@ -30,8 +30,9 @@ <file>part.xml</file> </header> <description> - <p>The System Architecture Support Libraries, <em>SASL</em>, - provides support for alarm and release handling etc.</p> + <p>The System Architecture Support Libraries <c>SASL</c> application + provides support for alarm handling, release handling, and + related functions.</p> </description> <xi:include href="sasl_intro.xml"/> <xi:include href="error_logging.xml"/> diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml index 85252fc088..e16e9f5a62 100644 --- a/lib/sasl/doc/src/rb.xml +++ b/lib/sasl/doc/src/rb.xml @@ -35,241 +35,252 @@ <module>rb</module> <modulesummary>The Report Browser Tool</modulesummary> <description> - <p>The Report Browser (RB) tool makes it possible to browse and + <p>The Report Browser (RB) tool is used to browse and format error reports written by the error logger handler - <c>log_mf_h</c>. - </p> + <seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso> + in <c>STDLIB</c>.</p> </description> + <funcs> <func> <name>filter(Filters)</name> <name>filter(Filters, Dates)</name> - <fsummary>Filter reports and displays them on the screen</fsummary> + <fsummary>Filters reports and displays them on the screen.</fsummary> <type> <v>Filters = [filter()]</v> - <v>filter() = {Key, Value} | {Key, Value, no} | {Key, RegExp, re} | {Key, RegExp, re, no}</v> + <v>filter() = {Key, Value} | {Key, Value, no} | {Key, RegExp, re} | + {Key, RegExp, re, no}</v> <v>Key = term()</v> <v>Value = term()</v> - <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v> + <v>RegExp = string() | {string(), Options} | re:mp() | {re:mp(), Options}</v> <v>Dates = {DateFrom, DateTo} | {DateFrom, from} | {DateTo, to}</v> - <v>DateFrom = DateTo = {date(), time()}</v> - <v>date() and time() are the same type as in the <c>calendar</c> module</v> + <v>DateFrom = DateTo = calendar:datetime()</v> </type> <desc> - <p>This function displays the reports that match the provided filters.</p> - <p> - When a filter includes the <c>no</c> atom it will exclude the reports that match - that filter. - </p> - <p> - The reports are matched using the <c>proplists</c> module. The report must be a proplist - to be matched against any of the <c>filters()</c>. - </p> - <p> - If the filter is of the form <c>{Key, RegExp, re}</c> the report must contain an element with - <c>key = Key</c> and <c>Value</c> must match the RegExp regular expression. - </p> - <p> - If the Dates parameter is provided, then the reports are filtered according to the date - when they occurred. If Dates is of the form <c>{DateFrom, from}</c> then reports that occurred - after DateFrom are displayed. - </p> - <p> - If Dates is of the form <c>{DateTo, to}</c> then reports that occurred before DateTo - are displayed. - </p> - <p> - If two Dates are provided, then reports that occurred between those dates are returned. - </p> - <p> - If you only want to filter only by dates, then you can provide the empty list as the Filters - parameter. - </p> - <p> - See <c>rb:grep/1</c> for more information on the RegExp parameter. - </p> + <p>Displays the reports that match the provided filters.</p> + <p>When a filter includes the <c>no</c> atom, it excludes the + reports that match that filter.</p> + <p>The reports are matched using the + <seealso marker="stdlib:proplists"><c>proplists</c></seealso> + module in <c>STDLIB</c>. The report must be a proplist + to be matched against any of the filters.</p> + <p>If the filter has the form <c>{Key, RegExp, re}</c>, the + report must contain an element with key equal to <c>Key</c> and + the value must match the regular expression <c>RegExp</c>.</p> + <p>If parameter <c>Dates</c> is specified, the reports are filtered + according to the date when they occurred. If <c>Dates</c> has + the form <c>{DateFrom, from}</c>, reports that occurred after + <c>DateFrom</c> are displayed.</p> + <p>If <c>Dates</c> has the form <c>{DateTo, to}</c>, reports that + occurred before <c>DateTo</c> are displayed.</p> + <p>If two <c>Dates</c> are specified, reports that occurred between + those dates are returned.</p> + <p>To filter only by dates, specify the empty list as the <c>Filters</c> + parameter.</p> + <p>For details about parameter <c>RegExp</c>, see <c>rb:grep/1</c>.</p> + <p>For details about data type <c>mp()</c>, see + <seealso marker="stdlib:re#type-mp"><c>re:mp()</c></seealso>.</p> + <p>For details about data type <c>datetime()</c>, see + <seealso marker="stdlib:calendar#type-datetime"><c>calendar:datetime()</c></seealso>.</p> </desc> </func> + <func> <name>grep(RegExp)</name> - <fsummary>Search the reports for a regular expression</fsummary> + <fsummary>Searches the reports for a regular expression.</fsummary> <type> - <v>RegExp = string() | {string, Options} | mp(), {mp(), Options}</v> + <v>RegExp = string() | {string(), Options} | re:mp() | {re:mp(), Options}</v> </type> <desc> - <p>All reports containing the regular expression <c>RegExp</c> - are printed. - </p> - <p><c>RegExp</c> can be a string containing the regular - expression; a tuple with the string and the options for - compilation; a compiled regular expression; a compiled - regular expression and the options for running it. - Refer to the module <c>re</c> and specially the function <c>re:run/3</c> - for a definition of valid regular expressions and options. - </p> + <p>All reports matching the regular expression <c>RegExp</c> + are displayed. <c>RegExp</c> can be any of the following:</p> + <list type="bulleted"> + <item>A string containing the regular expression</item> + <item>A tuple with the string and the options for compilation</item> + <item>A compiled regular expression</item> + <item>A compiled regular expression and the options for running it</item> + </list> + <p>For a definition of valid regular expressions and options, see + the <seealso marker="stdlib:re"><c>re</c></seealso> module in + <c>STDLIB</c> and in particular function <c>re:run/3</c>.</p> + <p>For details about data type <c>mp()</c>, see + <seealso marker="stdlib:re#type-mp"><c>re:mp()</c></seealso>.</p> </desc> </func> + <func> <name>h()</name> <name>help()</name> - <fsummary>Print help information</fsummary> + <fsummary>Displays help information.</fsummary> <desc> - <p>Prints the on-line help information. - </p> + <p>Displays online help information.</p> </desc> </func> + <func> <name>list()</name> <name>list(Type)</name> - <fsummary>List all reports</fsummary> + <fsummary>Lists all reports.</fsummary> <type> <v>Type = type()</v> <v>type() = error | error_report | info_msg | info_report | - warning_msg | warning_report | crash_report | - supervisor_report | progress</v> + warning_msg | warning_report | crash_report | + supervisor_report | progress</v> </type> <desc> - <p>This function lists all reports loaded in the + <p>Lists all reports loaded in <c>rb_server</c>. Each report is given a unique number that - can be used as a reference to the report in the - <c>show/1</c> function. - </p> - <p>If no <c>Type</c> is given, all reports are listed. - </p> + can be used as a reference to the report in function + <seealso marker="#show/1"><c>show/1</c></seealso>.</p> + <p>If no <c>Type</c> is specified, all reports are listed.</p> </desc> </func> + <func> <name>log_list()</name> <name>log_list(Type)</name> - <fsummary>Log reports list</fsummary> + <fsummary>Logs report lists.</fsummary> <type> <v>Type = type()</v> <v>type() = error | error_report | info_msg | info_report | - warning_msg | warning_report | crash_report | - supervisor_report | progress</v> + warning_msg | warning_report | crash_report | + supervisor_report | progress</v> </type> <desc> - <p>Same as <c>list/0</c> or <c>list/1</c> functions - but result is printed to logfile, if set, otherwise to standard_io. - </p> - <p>If no <c>Type</c> is given, all reports are listed. - </p> + <p>Same as functions + <seealso marker="#list/0"><c>list/0</c></seealso> or + <seealso marker="#list/1"><c>list/1</c></seealso>, + but the result is printed to a log file, if set; otherwise + to <c>standard_io</c>.</p> + <p>If no <c>Type</c> is specified, all reports are listed.</p> </desc> </func> + <func> <name>rescan()</name> <name>rescan(Options)</name> - <fsummary>Rescan the report directory</fsummary> + <fsummary>Rescans the report directory.</fsummary> <type> <v>Options = [opt()]</v> </type> <desc> <p>Rescans the report directory. <c>Options</c> is the same as - for <c>start()</c>. - </p> + for function + <seealso marker="#start/1"><c>start/1</c></seealso>.</p> </desc> </func> + <func> <name>show()</name> <name>show(Report)</name> - <fsummary>Show reports</fsummary> + <fsummary>Displays reports.</fsummary> <type> - <v>Report = int() | type()</v> + <v>Report = integer() | type()</v> </type> <desc> - <p>If a type argument is given, all loaded reports of this - type are printed. If an integer argument is given, the - report with this reference number is printed. If no argument - is given, all reports are shown. - </p> + <p>If argument <c>type</c> is specified, all loaded reports of this + type are displayed. If an integer argument is specified, the + report with this reference number is displayed. If no argument + is specified, all reports are displayed.</p> </desc> </func> + <func> <name>start()</name> <name>start(Options)</name> - <fsummary>Start the RB server</fsummary> + <fsummary>Starts the <c>rb_server</c>.</fsummary> <type> <v>Options = [opt()]</v> - <v>opt() = {start_log, FileName} | {max, MaxNoOfReports} | {report_dir, DirString} | {type, ReportType} | {abort_on_error, Bool}</v> + <v>opt() = {start_log, FileName} | {max, MaxNoOfReports} | + {report_dir, DirString} | {type, ReportType} | + {abort_on_error, Bool}</v> <v>FileName = string() | atom() | pid()</v> - <v>MaxNoOfReports = int() | all</v> + <v>MaxNoOfReports = integer() | all</v> <v>DirString = string()</v> <v>ReportType = type() | [type()] | all</v> - <v>Bool = true | false</v> + <v>Bool = boolean()</v> </type> <desc> - <p>The function <c>start/1</c> starts the <c>rb_server</c> - with the specified options, while <c>start/0</c> starts with - default options. The <c>rb_server</c> must be started before - reports can be browsed. When the <c>rb_server</c> is + <p>Function <c>start/1</c> starts <c>rb_server</c> with the + specified options, whereas function <c>start/0</c> starts with + default options. <c>rb_server</c> must be started before + reports can be browsed. When <c>rb_server</c> is started, the files in the specified directory are scanned. The other functions assume that the server has - started. - </p> - <p><c>{start_log, FileName}</c> starts logging to file, - registered name or io_device. All reports will be printed - to the named file. The default is <c>standard_io</c>. - The option {start_log, standard_error} is not allowed and - will be replaced by default standard_io. - </p> - <p><c>{max, MaxNoOfReports}</c>. Controls how many reports the - <c>rb_server</c> should read on start-up. This option is - useful as the directory may contain 20.000 reports. If this - option is given, the <c>MaxNoOfReports</c> latest reports - will be read. The default is 'all'. - </p> - <p><c>{report_dir, DirString}</c>. Defines the directory where - the error log files are located. The default is <c>{sasl, error_logger_mf_dir}</c>. </p> - <p><c>{type, ReportType}</c>. Controls what kind of reports the - <c>rb_server</c> should read on start-up. <c>ReportType</c> - is a supported type, 'all', or a list of supported - types. The default is 'all'. - </p> - <p><c>{abort_on_error, Bool}</c>. This option specifies whether - or not logging should be aborted if rb encounters an unprintable - report. (You may get a report on incorrect form if the - <c>error_logger</c> function <c>error_msg</c> or - <c>info_msg</c> has been called with an invalid format string). - If <c>Bool</c> is <c>true</c>, rb will stop logging (and print an - error message to stdout) if it encounters a badly formatted report. - If logging to file is enabled, an error message will be appended to - the log file as well. - If <c>Bool</c> is <c>false</c> (which is the default value), rb will - print an error message to stdout for every bad report it - encounters, but the logging process is never aborted. All printable - reports will be written. If logging to file is enabled, rb prints - <c>* UNPRINTABLE REPORT *</c> in the log file at the location of an - unprintable report. - </p> + started.</p> + <p><em>Options:</em></p> + <taglist> + <tag><c>{start_log, FileName}</c></tag> + <item><p>Starts logging to file, + registered name, or <c>io_device</c>. All reports are printed + to the specified destination. Default is <c>standard_io</c>. + Option <c>{start_log, standard_error}</c> is not allowed and + will be replaced by default <c>standard_io</c>.</p></item> + <tag><c>{max, MaxNoOfReports}</c></tag> + <item><p>Controls how many reports + <c>rb_server</c> is to read at startup. This option is + useful, as the directory can contain a large amount of reports. If this + option is specified, the <c>MaxNoOfReports</c> latest reports + are read. Default is <c>all</c>.</p></item> + <tag><c>{report_dir, DirString}</c></tag> + <item><p>Defines the directory where + the error log files are located. Default is + the directory specified by application environment + variable <c>error_logger_mf_dir</c>, + see <seealso marker="sasl_app">sasl(6)</seealso>.</p></item> + <tag><c>{type, ReportType}</c></tag> + <item><p>Controls what kind of reports + <c>rb_server</c> is to read at startup. <c>ReportType</c> + is a supported type, <c>all</c>, or a list of supported + types. Default is <c>all</c>.</p></item> + <tag><c>{abort_on_error, Bool}</c></tag> + <item><p>Specifies if + logging is to be ended if <c>rb</c> encounters an unprintable + report. (You can get a report with an incorrect form if function + <c>error_logger</c>, <c>error_msg</c>, or + <c>info_msg</c> has been called with an invalid format string)</p> + <list type="bulleted"> + <item>If <c>Bool</c> is <c>true</c>, <c>rb</c> stops logging + (and prints an error message to <c>stdout</c>) if it encounters + a badly formatted report. If logging to file is enabled, an + error message is appended to the log file as well.</item> + <item>If <c>Bool</c> is <c>false</c> (the default value), <c>rb</c> + prints an error message to <c>stdout</c> for every bad report it + encounters, but the logging process is never ended. All printable + reports are written. If logging to file is enabled, <c>rb</c> prints + <c>* UNPRINTABLE REPORT *</c> in the log file at the location of an + unprintable report.</item> + </list></item> + </taglist> </desc> </func> + <func> <name>start_log(FileName)</name> - <fsummary>Redirect all output to <c>FileName</c></fsummary> + <fsummary>Redirects all output to <c>FileName</c>.</fsummary> <type> <v>FileName = string() | atom() | pid()</v> </type> <desc> <p>Redirects all report output from the RB tool to the - specified file, registered name or io_device. - </p> + specified file, registered name, or <c>io_device</c>.</p> </desc> </func> + <func> <name>stop()</name> - <fsummary>Stop the RB server</fsummary> + <fsummary>Stops the <c>rb_server</c>.</fsummary> <desc> - <p>Stops the <c>rb_server</c>. - </p> + <p>Stops <c>rb_server</c>.</p> </desc> </func> + <func> <name>stop_log()</name> - <fsummary>Stop logging to file</fsummary> + <fsummary>Stops logging to file.</fsummary> <desc> - <p>Closes the log file. The output from the RB tool will be - directed to <c>standard_io</c>. - </p> + <p>Closes the log file. The output from the RB tool is + directed to <c>standard_io</c>.</p> </desc> </func> </funcs> diff --git a/lib/sasl/doc/src/ref_man.xml b/lib/sasl/doc/src/ref_man.xml index 2b608c7c51..a80e5a2a00 100644 --- a/lib/sasl/doc/src/ref_man.xml +++ b/lib/sasl/doc/src/ref_man.xml @@ -30,8 +30,8 @@ <file>application.xml</file> </header> <description> - <p>The System Architecture Support Libraries application, <em>SASL</em>, - provides support for alarm and release handling etc.</p> + <p>The <c>SASL</c> application provides support for alarm handling, + release handling, and related functions.</p> </description> <xi:include href="sasl_app.xml"/> <xi:include href="alarm_handler.xml"/> diff --git a/lib/sasl/doc/src/rel.xml b/lib/sasl/doc/src/rel.xml index a16db24295..d5f3c7310a 100644 --- a/lib/sasl/doc/src/rel.xml +++ b/lib/sasl/doc/src/rel.xml @@ -33,74 +33,65 @@ <file>rel</file> <filesummary>Release resource file</filesummary> <description> - <p>The <em>release resource file</em> specifies which applications are + <p>The <em>release resource file</em> specifies which applications are included in a release (system) based on Erlang/OTP.</p> - <p>This file is used by the functions in <c>systools</c> when generating - start scripts (<c>.script</c>, <c>.boot</c>) and release upgrade - files (<c>relup</c>).</p> + <p>This file is used by the functions in + <seealso marker="systools"><c>systools</c></seealso> + when generating start scripts (<c>.script</c>, <c>.boot</c>) and + release upgrade files (<c>relup</c>).</p> </description> <section> - <title>FILE SYNTAX</title> - <p>The release resource file should be called <c>Name.rel</c>.</p> + <title>File Syntax</title> + <p>The release resource file is to be called <c>Name.rel</c>.</p> <p>The <c>.rel</c> file contains one single Erlang term, which is - called a <em>release specification</em>. The file has the + called a <em>release specification</em>. The file has the following syntax:</p> <code type="none"> {release, {RelName,Vsn}, {erts, EVsn}, [{Application, AppVsn} | {Application, AppVsn, Type} | {Application, AppVsn, IncApps} | - {Application, AppVsn, Type, IncApps}]}. - </code> - <list type="bulleted"> - <item> - <p><c>RelName = string()</c> is the name of the release.</p> - </item> - <item> - <p><c>Vsn = string()</c> is the version of the release.</p> - </item> - <item> - <p><c>EVsn = string()</c> is the version of ERTS the release is - intended for.</p> - </item> - <item> - <p><c>Application = atom()</c> is the name of an application - included in the release.</p> - </item> - <item> - <p><c>AppVsn = string()</c> is the version of an application - included in the release.</p> - </item> - <item> - <p><c>Type = permanent | transient | temporary | load | none</c> - is the start type of an application included in the release.</p> - <p>If <c>Type = permanent | transient | temporary</c>, - the application will be loaded and started in the corresponding - way, see <c>application(3)</c>. If <c>Type = load</c>, - the application will only be loaded. If <c>Type = none</c>, - the application will be neither loaded nor started, although - the code for its modules will be loaded. - Defaults to <c>permanent</c></p> - </item> - <item> - <p><c>IncApps = [atom()]</c> is a list of applications that are - included by an application included in the release.</p> - <p>The list must be a subset of the included applications + {Application, AppVsn, Type, IncApps}]}.</code> + <taglist> + <tag><c>RelName = string()</c></tag> + <item><p>Release name.</p></item> + <tag><c>Vsn = string()</c></tag> + <item><p>Release version.</p></item> + <tag><c>EVsn = string()</c></tag> + <item><p><c>ERTS</c> version the release is intended for.</p></item> + <tag><c>Application = atom()</c></tag> + <item><p>Name of an application included in the release.</p></item> + <tag><c>AppVsn = string()</c></tag> + <item><p>Version of an application included in the release.</p></item> + <tag><c>Type = permanent | transient | temporary | load | none</c></tag> + <item><p>Start type of an application included in the release.</p> + <p>If <c>Type = permanent | transient | temporary</c>, the + application is loaded and started in the corresponding way, see + <seealso marker="kernel:application"><c>application(3)</c></seealso>.</p> + <p>If <c>Type = load</c>, the application is only loaded.</p> + <p>If <c>Type = none</c>, the application is not loaded and not + started, although the code for its modules is loaded.</p> + <p>Defaults to <c>permanent</c></p></item> + <tag><c>IncApps = [atom()]</c></tag> + <item><p>A list of applications that are included by an application + included in the release. The list must be a subset of the + included applications specified in the application resource file (<c>Application.app</c>) and overrides this value. Defaults - to the same value as in the application resource file.</p> - </item> - </list> + to the same value as in the application resource file.</p></item> + </taglist> <note> - <p>The list of applications must contain the <c>kernel</c> and - <c>stdlib</c> applications.</p> + <p>The list of applications must contain the <c>Kernel</c> and + <c>STDLIB</c> applications.</p> </note> </section> <section> - <title>SEE ALSO</title> - <p>application(3), relup(4), systools(3)</p> + <title>See Also</title> + <p><seealso marker="kernel:application"><c>application(3)</c></seealso>, + <seealso marker="relup"><c>relup(4)</c></seealso>, + <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </fileref> diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml index 692159d7bf..162707676c 100644 --- a/lib/sasl/doc/src/release_handler.xml +++ b/lib/sasl/doc/src/release_handler.xml @@ -31,109 +31,115 @@ <module>release_handler</module> <modulesummary>Unpacking and Installation of Release Packages</modulesummary> <description> - <p>The <em>release handler</em> is a process belonging to the SASL - application which is responsible for <em>release handling</em>, + <p>The <em>release handler</em> process belongs to the <c>SASL</c> + application, which is responsible for <em>release handling</em>, that is, unpacking, installation, and removal of release packages.</p> - <p>An introduction to release handling and a usage example can be - found in - <seealso marker="doc/design_principles:release_handling">Design Principles</seealso>. - </p> + <p>An introduction to release handling and an example is provided in + <seealso marker="doc/design_principles:release_handling">OTP Design + Principles</seealso> in <em>System Documentation</em>.</p> <p>A <em>release package</em> is a compressed tar file containing code for a certain version of a release, created by calling - <seealso marker="systools#make_tar/1">systools:make_tar/1,2</seealso>. - The release package should be placed in the <c>$ROOT/releases</c> - directory of the previous version of the release where + <seealso marker="systools#make_tar/1"><c>systools:make_tar/1,2</c></seealso>. + The release package is to be located in the <c>$ROOT/releases</c> + directory of the previous version of the release, where <c>$ROOT</c> is the installation root directory, - <c>code:root_dir()</c>. - Another <c>releases</c> directory can be specified using the SASL - configuration parameter <c>releases_dir</c>, or the OS environment + <seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso>. + Another <c>releases</c> directory can be specified using the <c>SASL</c> + configuration parameter <c>releases_dir</c> or the OS environment variable <c>RELDIR</c>. The release handler must have write access - to this directory in order to install the new release. + to this directory to install the new release. The persistent state of the release handler is stored there in a file called <c>RELEASES</c>.</p> - <p>A release package should always contain the release resource file - <c>Name.rel</c> and a boot script <c>Name.boot</c>. It may contain - a release upgrade file <c>relup</c> and a system configuration - file <c>sys.config</c>. The <c>.rel</c> file contains information - about the release: its name, version, and which ERTS and - application versions it uses. The <c>relup</c> file contains - scripts for how to upgrade to, or downgrade from, this version of - the release.</p> + <p>A release package is always to contain:</p> + <list type="bulleted"> + <item>A release resource file, <c>Name.rel</c></item> + <item>A boot script, <c>Name.boot</c></item> + </list> + <p>The <c>.rel</c> file contains information about the release: its name, + version, and which <c>ERTS</c> and application versions it uses.</p> + <p>A release package can also contain:</p> + <list type="bulleted"> + <item>A release upgrade file, <c>relup</c></item> + <item>A system configuration file, <c>sys.config</c></item> + </list> + <p>The <c>relup</c> file contains instructions for how to upgrade + to, or downgrade from, this version of the release.</p> <p>The release package can be <em>unpacked</em>, which extracts the files. An unpacked release can be <em>installed</em>. The currently used version of the release is then upgraded or downgraded to the specified version by evaluating the instructions - in <c>relup</c>. An installed release can be made - <em>permanent</em>. There can only be one permanent release in - the system, and this is the release that is used if the system + in the <c>relup</c> file. An installed release can be made + <em>permanent</em>. Only one permanent release can exist in + the system, and this release is used if the system is restarted. An installed release, except the permanent one, can be <em>removed</em>. When a release is removed, all files - that belong to that release only are deleted.</p> - <p>Each version of the release has a status. The status can be + belonging to that release only are deleted.</p> + <p>Each release version has a status, which can be <c>unpacked</c>, <c>current</c>, <c>permanent</c>, or <c>old</c>. - There is always one latest release which either has status - <c>permanent</c> (normal case), or <c>current</c> (installed, but - not yet made permanent). The following table illustrates - the meaning of the status values:</p> + There is always one latest release, which either has status + <c>permanent</c> (normal case) or <c>current</c> (installed, but + not yet made permanent). The meaning of the status values are + illustrated in the following table:</p> <pre> -Status Action NextStatus -------------------------------------------- - - unpack unpacked -unpacked install current - remove - -current make_permanent permanent - install other old - remove - -permanent make other permanent old - install permanent -old reboot_old permanent - install current - remove - - </pre> + Status Action NextStatus + ------------------------------------------- + - unpack unpacked + unpacked install current + remove - + current make_permanent permanent + install other old + remove - + permanent make other permanent old + install permanent + old reboot_old permanent + install current + remove -</pre> <p>The release handler process is a locally registered process on each node. When a release is installed in a distributed system, the release handler on each node must be called. The release - installation may be synchronized between nodes. From an operator - view, it may be unsatisfactory to specify each node. The aim is + installation can be synchronized between nodes. From an operator + view, it can be unsatisfactory to specify each node. The aim is to install one release package in the system, no matter how many - nodes there are. If this is the case, it is recommended that - software management functions are written which take care of - this problem. Such a function may have knowledge of the system + nodes there are. It is recommended that + software management functions are written that take care of + this problem. Such a function can have knowledge of the system architecture, so it can contact each individual release handler to install the package.</p> - <p>For release handling to work properly, the runtime system needs - to have knowledge about which release it is currently running. It - must also be able to change (in run-time) which boot script and - system configuration file should be used if the system is + <p>For release handling to work properly, the runtime system must + know which release it is running. It + must also be able to change (in runtime) which boot script and + system configuration file are to be used if the system is restarted. This is taken care of automatically if Erlang is - started as an embedded system. Read about this in <em>Embedded System</em>. In this case, the system configuration file - <c>sys.config</c> is mandatory.</p> - <p>The installation of a new release may restart the system. Which - program to use is specified by the SASL configuration - parameter <c>start_prg</c> which defaults + started as an embedded system. Read about this in + <seealso marker="doc/embedded:users_guide">Embedded System</seealso> in + <em>System Documentation</em>. In this case, the system + configuration file <c>sys.config</c> is mandatory.</p> + <p>The installation of a new release can restart the system. Which + program to use is specified by the <c>SASL</c> configuration + parameter <c>start_prg</c>, which defaults to <c>$ROOT/bin/start</c>.</p> <p>The emulator restart on Windows NT expects that the system is started using the <c>erlsrv</c> program (as a service). - Furthermore the release handler expects that the service is named - <em>NodeName</em>_<em>Release</em>, where <em>NodeName</em> is - the first part of the Erlang nodename (up to, but not including - the "@") and <em>Release</em> is the current version of - the release. The release handler furthermore expects that a + Furthermore, the release handler expects that the service is named + <c>NodeName</c>_<c>Release</c>, where <c>NodeName</c> is + the first part of the Erlang node name (up to, but not including + the "@") and <c>Release</c> is the current release version. + The release handler furthermore expects that a program like <c>start_erl.exe</c> is specified as "machine" to - <c>erlsrv</c>. During upgrading with restart, a new service will - be registered and started. The new service will be set to - automatic and the old service removed as soon as the new release + <c>erlsrv</c>. During upgrading with restart, a new service + is registered and started. The new service is set to + automatic and the old service is removed when the new release is made permanent.</p> - <p>The release handler at a node which runs on a diskless machine, + <p>The release handler at a node running on a diskless machine, or with a read-only file system, must be configured accordingly - using the following <c>sasl</c> configuration parameters (see - <seealso marker="sasl_app">sasl(6)</seealso> for details):</p> + using the following <c>SASL</c> configuration parameters (for + details, see <seealso marker="sasl_app">sasl(6)</seealso>):</p> <taglist> <tag><c>masters</c></tag> <item> - <p>This node uses a number of master nodes in order to store - and fetch release information. All master nodes must be up - and running whenever release information is written by this + <p>This node uses some master nodes to store + and fetch release information. All master nodes must be + operational whenever release information is written by this node.</p> </item> <tag><c>client_directory</c></tag> @@ -145,24 +151,25 @@ old reboot_old permanent <item> <p>This parameter specifies if the Erlang emulator is statically installed at the client node. A node with a static - emulator cannot dynamically switch to a new emulator because + emulator cannot dynamically switch to a new emulator, as the executable files are statically written into memory.</p> </item> </taglist> - <p>It is also possible to use the release handler to unpack and + <p>The release handler can also be used to unpack and install release packages when not running Erlang as an embedded - system, but in this case the user must somehow make sure that + system. However, in this case the user must somehow ensure that correct boot scripts and configuration files are used if - the system needs to be restarted.</p> - <p>There are additional functions for using another file structure + the system must be restarted.</p> + <p>Functions are provided for using another file structure than the structure defined in OTP. These functions can be used to test a release upgrade locally.</p> </description> + <funcs> <func> <name>check_install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}</name> <name>check_install_release(Vsn,Opts) -> {ok, OtherVsn, Descr} | {error, Reason}</name> - <fsummary>Check installation of a release in the system.</fsummary> + <fsummary>Checks installation of a release in the system.</fsummary> <type> <v>Vsn = OtherVsn = string()</v> <v>Opts = [Opt]</v> @@ -173,27 +180,29 @@ old reboot_old permanent <desc> <p>Checks if the specified version <c>Vsn</c> of the release can be installed. The release must not have status - <c>current</c>. Issues warnings if <c>relup</c> or - <c>sys.config</c> are not present. If <c>relup</c> is present, + <c>current</c>. Issues warnings if <c>relup</c> file or + <c>sys.config</c> is not present. If <c>relup</c> file is present, its contents are checked and <c>{error,Reason}</c> is returned if an error is found. Also checks that all required - applications are present and that all new code can be loaded, - or <c>{error,Reason}</c> is returned.</p> - <p>This function evaluates all instructions that occur before + applications are present and that all new code can be loaded; + <c>{error,Reason}</c> is returned if an error is found.</p> + <p>Evaluates all instructions that occur before the <c>point_of_no_return</c> instruction in the release upgrade script.</p> - <p>Returns the same as <c>install_release/1</c>. <c>Descr</c> - defaults to "" if no <c>relup</c> file is found.</p> - <p>If the option <c>purge</c> is given, all old code that can - be soft purged will be purged after all other checks are - successfully completed. This can be useful in order to + <p>Returns the same as + <seealso marker="#install_release/1"><c>install_release/1</c></seealso>. + <c>Descr</c> defaults to "" if no <c>relup</c> file is found.</p> + <p>If option <c>purge</c> is specified, all old code that can + be soft-purged is purged after all other checks are + successfully completed. This can be useful to reduce the time needed by <seealso - marker="#install_release/1">install_release</seealso>.</p> + marker="#install_release/1"><c>install_release/1</c></seealso>.</p> </desc> </func> + <func> <name>create_RELEASES(Root, RelDir, RelFile, AppDirs) -> ok | {error, Reason}</name> - <fsummary>Create an initial RELEASES file.</fsummary> + <fsummary>Creates an initial <c>RELEASES</c> file.</fsummary> <type> <v>Root = RelDir = RelFile = string()</v> <v>AppDirs = [{App, Vsn, Dir}]</v> @@ -202,52 +211,55 @@ old reboot_old permanent <v>Reason = term()</v> </type> <desc> - <p>Creates an initial RELEASES file to be used by the release - handler. This file must exist in order to install new + <p>Creates an initial <c>RELEASES</c> file to be used by the + release handler. This file must exist to install new releases.</p> <p><c>Root</c> is the root of the installation (<c>$ROOT</c>) as - described above. <c>RelDir</c> is the the directory where - the <c>RELEASES</c> file should be created (normally + described earlier. <c>RelDir</c> is the directory where + the <c>RELEASES</c> file is to be created (normally <c>$ROOT/releases</c>). <c>RelFile</c> is the name of the <c>.rel</c> file that describes the initial release, including the extension <c>.rel</c>.</p> <p><c>AppDirs</c> can be used to specify from where the modules - for the specified applications should be loaded. <c>App</c> is + for the specified applications are to be loaded. <c>App</c> is the name of an application, <c>Vsn</c> is the version, and <c>Dir</c> is the name of the directory where <c>App-Vsn</c> - is located. The corresponding modules should be located under + is located. The corresponding modules are to be located under <c>Dir/App-Vsn/ebin</c>. The directories for applications not specified in <c>AppDirs</c> are assumed to be located in <c>$ROOT/lib</c>.</p> </desc> </func> + <func> <name>install_file(Vsn, File) -> ok | {error, Reason}</name> - <fsummary>Install a release file in the release structure.</fsummary> + <fsummary>Installs a release file in the release structure.</fsummary> <type> <v>Vsn = File = string()</v> <v>Reason = term()</v> </type> <desc> - <p>Installs a release dependent file in the release structure. - A release dependent file is a file that must be in + <p>Installs a release-dependent file in the release structure. + The release-dependent file must be in the release structure when a new release is installed: - <c>start.boot</c>, <c>relup</c> and <c>sys.config</c>.</p> + <c>start.boot</c>, <c>relup</c>, and <c>sys.config</c>.</p> <p>The function can be called, for example, when these files - are generated at the target. It should be called after - <c>set_unpacked/2</c> has been called.</p> + are generated at the target. The function is to be called after + <seealso marker="#set_unpacked/2"><c>set_unpacked/2</c></seealso> + has been called.</p> </desc> </func> + <func> <name>install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}</name> <name>install_release(Vsn, [Opt]) -> {ok, OtherVsn, Descr} | {continue_after_restart, OtherVsn, Descr} | {error, Reason}</name> - <fsummary>Install a release in the system.</fsummary> + <fsummary>Installs a release in the system.</fsummary> <type> <v>Vsn = OtherVsn = string()</v> <v>Opt = {error_action, Action} | {code_change_timeout, Timeout}</v> <v> | {suspend_timeout, Timeout} | {update_paths, Bool}</v> <v> Action = restart | reboot</v> - <v> Timeout = default | infinity | int()>0</v> + <v> Timeout = default | infinity | pos_integer()</v> <v> Bool = boolean()</v> <v>Descr = term()</v> <v>Reason = {illegal_option, Opt} | {already_installed, Vsn} | {change_appl_data, term()} | {missing_base_app, OtherVsn, App} | {could_not_create_hybrid_boot, term()} | term()</v> @@ -262,7 +274,7 @@ old reboot_old permanent version and a script <c>{Vsn,Descr2,Instructions2}</c> in this file for downgrading to <c>Vsn</c>.</p> <p>If a script is found, the first thing that happens is that - the applications specifications are updated according to + the application specifications are updated according to the <c>.app</c> files and <c>sys.config</c> belonging to the release version <c>Vsn</c>.</p> <p>After the application specifications have been updated, @@ -271,101 +283,120 @@ old reboot_old permanent <c>OtherVsn</c> and <c>Descr</c> are the version (<c>UpFromVsn</c> or <c>Vsn</c>) and description (<c>Descr1</c> or <c>Descr2</c>) as specified in the script.</p> - <p>If <c>{continue_after_restart,OtherVsn,Descr}</c> is - returned, it means that the emulator will be restarted - before the upgrade instructions are executed. This will - happen if the emulator or any of the applications kernel, - stdlib or sasl are updated. The new version of the emulator - and these core applications will execute after the restart, - but for all other applications the old versions will be - started and the upgrade will be performed as normal by + <p>If <c>{continue_after_restart,OtherVsn,Descr}</c> is + returned, the emulator is restarted + before the upgrade instructions are executed. This + occurs if the emulator or any of the applications + <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c> + are updated. The new emulator version + and these core applications execute after the restart. + For all other applications the old versions are + started and the upgrade is performed as normal by executing the upgrade instructions.</p> <p>If a recoverable error occurs, the function returns <c>{error,Reason}</c> and the original application specifications are restored. If a non-recoverable error occurs, the system is restarted.</p> - <p>The option <c>error_action</c> defines if the node should be - restarted (<c>init:restart()</c>) or rebooted - (<c>init:reboot()</c>) in case of an error during - the installation. Default is <c>restart</c>.</p> - <p>The option <c>code_change_timeout</c> defines the timeout - for all calls to <c>sys:change_code</c>. If no value is - specified or <c>default</c> is given, the default value - defined in <c>sys</c> is used.</p> - <p>The option <c>suspend_timeout</c> defines the timeout for - all calls to <c>sys:suspend</c>. If no value is specified, - the values defined by the <c>Timeout</c> parameter of - the <c>upgrade</c> or <c>suspend</c> instructions are used. - If <c>default</c> is specified, the default value defined in - <c>sys</c> is used.</p> - <p>The option <c>{update_paths,Bool}</c> indicates if all - application code paths should be updated (<c>Bool==true</c>), - or if only code paths for modified applications should be - updated (<c>Bool==false</c>, default). This option only has - effect for other application directories than the default - <c>$ROOT/lib/App-Vsn</c>, that is, application directories - provided in the <c>AppDirs</c> argument in a call to - <c>create_RELEASES/4</c> or <c>set_unpacked/2</c>.</p> - <p>Example: In the current version <c>CurVsn</c> of a release, - the application directory of <c>myapp</c> is - <c>$ROOT/lib/myapp-1.0</c>. A new version <c>NewVsn</c> is - unpacked outside the release handler, and the release handler - is informed about this with a call to:</p> - <code type="none"> + <p><em>Options</em>:</p> + <taglist> + <tag><c>error_action</c></tag> + <item><p>Defines if the node is to be + restarted + (<seealso marker="erts:init#restart/0"><c>init:restart()</c></seealso>) + or rebooted + (<seealso marker="erts:init#reboot/0"><c>init:reboot()</c></seealso>) + if there is an error during + the installation. Default is <c>restart</c>.</p></item> + <tag><c>code_change_timeout</c></tag> + <item><p>Defines the time-out + for all calls to + <seealso marker="stdlib:sys#change_code/4"><c>stdlib:sys:change_code</c></seealso>. + If no value is specified or <c>default</c> is specified, the + default value defined in <c>sys</c> is used.</p></item> + <tag><c>suspend_timeout</c></tag> + <item><p>Defines the time-out for + all calls to + <seealso marker="stdlib:sys#suspend/1"><c>stdlib:sys:suspend</c></seealso>. + If no value is specified, the values defined by the <c>Timeout</c> + parameter of the <c>upgrade</c> or <c>suspend</c> instructions are used. + If <c>default</c> is specified, the default value defined in + <c>sys</c> is used.</p></item> + <tag><c>{update_paths,Bool}</c></tag> + <item><p>Indicates if all + application code paths are to be updated (<c>Bool==true</c>) + or if only code paths for modified applications are to be + updated (<c>Bool==false</c>, default). This option has only + effect for other application directories than the default + <c>$ROOT/lib/App-Vsn</c>, that is, application directories + specified in argument <c>AppDirs</c> in a call to + <seealso marker="#create_RELEASES/4"><c>create_RELEASES/4</c></seealso> or + <seealso marker="#set_unpacked/2"><c>set_unpacked/2</c></seealso>.</p> + <p><em>Example:</em></p> + <p>In the current version <c>CurVsn</c> of a release, the + application directory of <c>myapp</c> is + <c>$ROOT/lib/myapp-1.0</c>. A new version <c>NewVsn</c> is + unpacked outside the release handler and the release + handler is informed about this with a call as follows:</p> + <code type="none"> release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). -=> {ok,NewVsn} - </code> - <p>If <c>NewVsn</c> is installed with the option - <c>{update_paths,true}</c>, afterwards - <c>code:lib_dir(myapp)</c> will return - <c>/home/user/myapp-1.0</c>.</p> +=> {ok,NewVsn}</code> + <p>If <c>NewVsn</c> is installed with option + <c>{update_paths,true}</c>, then + <seealso marker="kernel:code#lib_dir/1"><c>kernel:code:lib_dir(myapp)</c></seealso> + returns <c>/home/user/myapp-1.0</c>.</p></item> + </taglist> <note> - <p>Installing a new release might be quite time consuming if + <p>Installing a new release can be time consuming if there are many processes in the system. The reason is that each process must be checked for references to old code - before a module can be purged. This check might lead to + before a module can be purged. This check can lead to garbage collections and copying of data.</p> - <p>If you wish to speed up the execution of - <c>install_release</c>, then you may call <seealso - marker="#check_install_release/1">check_install_release</seealso> - first, using the option <c>purge</c>. This will do the same - check for old code, and then purge all modules that can be - soft purged. The purged modules will then no longer have any - old code, and <c>install_release</c> will not need to do the + <p>To speed up the execution of + <seealso marker="#install_release/1"><c>install_release</c></seealso>, + first call <seealso + marker="#check_install_release/1"><c>check_install_release</c></seealso>, + using option <c>purge</c>. This does the same + check for old code. Then purges all modules that can be + soft-purged. The purged modules do then no longer have any + old code, and + <seealso marker="#install_release/1"><c>install_release</c></seealso> + does not need to do the checks.</p> - <p>Obviously, this will not reduce the overall time for the - upgrade, but it will allow checks and purge to be executed + <p>This does not reduce the overall time for the + upgrade, but it allows checks and purge to be executed in the background before the real upgrade is started.</p> </note> <note> <p>When upgrading the emulator from a version older than OTP - R15, there will be an attempt to load new application beam - code into the old emulator. In some cases, the new beam - format can not be read by the old emulator, and so the code - loading will fail and terminate the complete upgrade. To - overcome this problem, the new application code should be - compiled with the old emulator. See <seealso - marker="doc/design_principles:appup_cookbook">Design - Principles</seealso> for more information about emulator - upgrade from pre OTP R15 versions.</p> + R15, an attempt is made to load new application beam + code into the old emulator. Sometimes the new beam + format cannot be read by the old emulator, so the code + loading fails and the complete upgrade is terminated. To + overcome this problem, the new application code is to be + compiled with the old emulator. For more information about + emulator upgrade from pre OTP R15 versions, see + <seealso marker="doc/design_principles:appup_cookbook">Design + Principles</seealso> in <em>System Documentation</em>.</p> </note> </desc> </func> + <func> <name>make_permanent(Vsn) -> ok | {error, Reason}</name> - <fsummary>Make the specified release version permanent.</fsummary> + <fsummary>Makes the specified release version permanent.</fsummary> <type> <v>Vsn = string()</v> <v>Reason = {bad_status, Status} | term()</v> </type> <desc> - <p>Makes the specified version <c>Vsn</c> of the release + <p>Makes the specified release version <c>Vsn</c> permanent.</p> </desc> </func> + <func> <name>remove_release(Vsn) -> ok | {error, Reason}</name> - <fsummary>Remove a release from the system.</fsummary> + <fsummary>Removes a release from the system.</fsummary> <type> <v>Vsn = string()</v> <v>Reason = {permanent, Vsn} | client_node | term()</v> @@ -375,23 +406,26 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). The release must not be the permanent release. Removes only the files and directories not in use by another release.</p> </desc> + </func> <func> <name>reboot_old_release(Vsn) -> ok | {error, Reason}</name> - <fsummary>Reboot the system from an old release.</fsummary> + <fsummary>Reboots the system from an old release.</fsummary> <type> <v>Vsn = string()</v> <v>Reason = {bad_status, Status} | term()</v> </type> <desc> <p>Reboots the system by making the old release permanent, and - calls <c>init:reboot()</c> directly. The release must have - status <c>old</c>.</p> + calls + <seealso marker="erts:init#reboot/0"><c>init:reboot()</c></seealso> + directly. The release must have status <c>old</c>.</p> </desc> </func> + <func> <name>set_removed(Vsn) -> ok | {error, Reason}</name> - <fsummary>Mark a release as removed.</fsummary> + <fsummary>Marks a release as removed.</fsummary> <type> <v>Vsn = string()</v> <v>Reason = {permanent, Vsn} | term()</v> @@ -403,9 +437,10 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). not delete any files.</p> </desc> </func> + <func> <name>set_unpacked(RelFile, AppDirs) -> {ok, Vsn} | {error, Reason}</name> - <fsummary>Mark a release as unpacked.</fsummary> + <fsummary>Marks a release as unpacked.</fsummary> <type> <v>RelFile = string()</v> <v>AppDirs = [{App, Vsn, Dir}]</v> @@ -419,18 +454,19 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). the release is unpacked. <c>Vsn</c> is extracted from the release resource file <c>RelFile</c>.</p> <p><c>AppDirs</c> can be used to specify from where the modules - for the specified applications should be loaded. <c>App</c> is + for the specified applications are to be loaded. <c>App</c> is the name of an application, <c>Vsn</c> is the version, and <c>Dir</c> is the name of the directory where <c>App-Vsn</c> - is located. The corresponding modules should be located under + is located. The corresponding modules are to be located under <c>Dir/App-Vsn/ebin</c>. The directories for applications not specified in <c>AppDirs</c> are assumed to be located in <c>$ROOT/lib</c>.</p> </desc> </func> + <func> <name>unpack_release(Name) -> {ok, Vsn} | {error, Reason}</name> - <fsummary>Unpack a release package.</fsummary> + <fsummary>Unpacks a release package.</fsummary> <type> <v>Name = Vsn = string()</v> <v>Reason = client_node | term()</v> @@ -438,14 +474,15 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Unpacks a release package <c>Name.tar.gz</c> located in the <c>releases</c> directory.</p> - <p>Performs some checks on the package - for example checks - that all mandatory files are present - and extracts its + <p>Performs some checks on the package, for example, checks + that all mandatory files are present, and extracts its contents.</p> </desc> </func> + <func> <name>which_releases() -> [{Name, Vsn, Apps, Status}]</name> - <fsummary>Return all known releases</fsummary> + <fsummary>Returns all known releases.</fsummary> <type> <v>Name = Vsn = string()</v> <v>Apps = ["App-Vsn"]</v> @@ -455,16 +492,18 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <p>Returns all releases known to the release handler.</p> </desc> </func> + <func> <name>which_releases(Status) -> [{Name, Vsn, Apps, Status}]</name> - <fsummary>Return all known releases of a specific status</fsummary> + <fsummary>Returns all known releases of a specific status.</fsummary> <type> <v>Name = Vsn = string()</v> <v>Apps = ["App-Vsn"]</v> <v>Status = unpacked | current | permanent | old</v> </type> <desc> - <p>Returns all releases known to the release handler of a specific status.</p> + <p>Returns all releases, known to the release handler, of a + specific status.</p> </desc> </func> </funcs> @@ -473,7 +512,8 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <title>Application Upgrade/Downgrade</title> <p>The following functions can be used to test upgrade and downgrade of single applications (instead of upgrading/downgrading an entire - release). A script corresponding to <c>relup</c> is created + release). A script corresponding to the instructions in the + <c>relup</c> file is created on-the-fly, based on the <c>.appup</c> file for the application, and evaluated exactly in the same way as <c>release_handler</c> does.</p> @@ -482,20 +522,22 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). of <c>.appup</c> files. They are not run within the context of the <c>release_handler</c> process. They must therefore <em>not</em> be used together with calls to - <c>install_release/1,2</c>, as this will cause + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>, + as this causes the <c>release_handler</c> to end up in an inconsistent state.</p> - <p>No persistent information is updated, why these functions can + <p>No persistent information is updated, so these functions can be used on any Erlang node, embedded or not. Also, using these - functions does not affect which code will be loaded in case of + functions does not affect which code is loaded if there is a reboot.</p> - <p>If the upgrade or downgrade fails, the application may end up + <p>If the upgrade or downgrade fails, the application can end up in an inconsistent state.</p> </warning> </section> + <funcs> <func> <name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> - <fsummary>Upgrade to a new application version</fsummary> + <fsummary>Upgrades to a new application version.</fsummary> <type> <v>App = atom()</v> <v>Dir = string()</v> @@ -506,39 +548,46 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Upgrades an application <c>App</c> from the current version to a new version located in <c>Dir</c> according to - the <c>.appup</c> script.</p> + the <c>.appup</c> file.</p> <p><c>App</c> is the name of the application, which must be started. <c>Dir</c> is the new library directory of - <c>App</c>, the corresponding modules as well as - the <c>.app</c> and <c>.appup</c> files should be located + <c>App</c>. The corresponding modules as well as + the <c>.app</c> and <c>.appup</c> files are to be located under <c>Dir/ebin</c>.</p> <p>The function looks in the <c>.appup</c> file and tries to find an upgrade script from the current version of the application using - <seealso marker="#upgrade_script/2">upgrade_script/2</seealso>. + <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso>. This script is evaluated using - <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>, + <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>, exactly in the same way as - <seealso marker="#install_release/1">install_release/1,2</seealso> + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso> does.</p> - <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is - successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_emulator</c> if this instruction is - encountered in the script, or <c>{error, Reason}</c> if - an error occurred when finding or evaluating the script.</p> + <p>Returns one of the following:</p> + <list type="bulleted"> + <item><c>{ok, Unpurged}</c> if evaluating the script is + successful, where <c>Unpurged</c> is a list of unpurged + modules</item> + <item><c>restart_emulator</c> if this instruction is + encountered in the script</item> + <item><c>{error, Reason}</c> if an error occurred when + finding or evaluating the script</item> + </list> <p>If the <c>restart_new_emulator</c> instruction is found in - the script, <c>upgrade_app/2</c> will return - <c>{error,restart_new_emulator}</c>. The reason for this is - that this instruction requires that a new version of the - emulator is started before the rest of the upgrade - instructions can be executed, and this can only be done by - <c>install_release/1,2</c>.</p> + the script, + <seealso marker="#upgrade_app/2"><c>upgrade_app/2</c></seealso> + returns <c>{error,restart_new_emulator}</c>. This because + <c>restart_new_emulator</c> requires a new version of the + emulator to be started before the rest of the upgrade + instructions can be executed, and this can only be done by + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>.</p> </desc> </func> + <func> <name>downgrade_app(App, Dir) -></name> <name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> - <fsummary>Downgrade to a previous application version</fsummary> + <fsummary>Downgrades to a previous application version.</fsummary> <type> <v>App = atom()</v> <v>Dir = OldVsn = string()</v> @@ -549,110 +598,124 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Downgrades an application <c>App</c> from the current version to a previous version <c>OldVsn</c> located in - <c>Dir</c> according to the <c>.appup</c> script.</p> + <c>Dir</c> according to the <c>.appup</c> file.</p> <p><c>App</c> is the name of the application, which must be - started. <c>OldVsn</c> is the previous version of - the application and can be omitted if <c>Dir</c> is of + started. <c>OldVsn</c> is the previous application version + and can be omitted if <c>Dir</c> is of the format <c>"App-OldVsn"</c>. <c>Dir</c> is the library - directory of this previous version of <c>App</c>, - the corresponding modules as well as the old <c>.app</c> file - should be located under <c>Dir/ebin</c>. The <c>.appup</c> - file should be located in the <c>ebin</c> directory of + directory of the previous version of <c>App</c>. + The corresponding modules and the old <c>.app</c> file + are to be located under <c>Dir/ebin</c>. The <c>.appup</c> + file is to be located in the <c>ebin</c> directory of the <em>current</em> library directory of the application - (<c>code:lib_dir(App)</c>).</p> + (<seealso marker="kernel:code#lib_dir/1"><c>code:lib_dir(App)</c></seealso>).</p> <p>The function looks in the <c>.appup</c> file and tries to - find an downgrade script to the previous version of + find a downgrade script to the previous version of the application using - <seealso marker="#downgrade_script/3">downgrade_script/3</seealso>. + <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso>. This script is evaluated using - <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>, + <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>, exactly in the same way as - <seealso marker="#install_release/1">install_release/1,2</seealso> + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso> does.</p> - <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is - successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_emulator</c> if this instruction is - encountered in the script, or <c>{error, Reason}</c> if - an error occurred when finding or evaluating the script.</p> + <p>Returns one of the following:</p> + <list type="bulleted"> + <item><c>{ok, Unpurged}</c> if evaluating the script is + successful, where <c>Unpurged</c> is a list of unpurged + modules</item> + <item><c>restart_emulator</c> if this instruction is + encountered in the script</item> + <item><c>{error, Reason}</c> if an error occurred when + finding or evaluating the script</item> + </list> </desc> </func> + <func> <name>upgrade_script(App, Dir) -> {ok, NewVsn, Script}</name> - <fsummary>Find an application upgrade script</fsummary> + <fsummary>Finds an application upgrade script.</fsummary> <type> <v>App = atom()</v> <v>Dir = string()</v> <v>NewVsn = string()</v> - <v>Script = Instructions -- see appup(4)</v> + <v>Script = Instructions</v> </type> <desc> <p>Tries to find an application upgrade script for <c>App</c> from the current version to a new version located in <c>Dir</c>.</p> <p>The upgrade script can then be evaluated using - <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>. + <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>. It is recommended to use - <seealso marker="#upgrade_app/2">upgrade_app/2</seealso> - instead, but this function is useful in order to inspect - the contents of the script.</p> + <seealso marker="#upgrade_app/2"><c>upgrade_app/2</c></seealso> + instead, but this function (<c>upgrade_script</c>) is useful + to inspect the contents of the script.</p> <p><c>App</c> is the name of the application, which must be started. <c>Dir</c> is the new library directory of - <c>App</c>, the corresponding modules as well as - the <c>.app</c> and <c>.appup</c> files should be located + <c>App</c>. The corresponding modules as well as + the <c>.app</c> and <c>.appup</c> files are to be located under <c>Dir/ebin</c>.</p> <p>The function looks in the <c>.appup</c> file and tries to - find an upgrade script from the current version of - the application. High-level instructions are translated to - low-level instructions and the instructions are sorted in - the same manner as when generating a <c>relup</c> script.</p> + find an upgrade script from the current application version. + High-level instructions are translated to + low-level instructions. The instructions are sorted in + the same manner as when generating a <c>relup</c> file.</p> <p>Returns <c>{ok, NewVsn, Script}</c> if successful, where - <c>NewVsn</c> is the new application version.</p> + <c>NewVsn</c> is the new application version. + For details about <c>Script</c>, see + <seealso marker="appup"><c>appup(4)</c></seealso>.</p> <p>Failure: If a script cannot be found, the function fails with an appropriate error reason.</p> </desc> </func> + <func> <name>downgrade_script(App, OldVsn, Dir) -> {ok, Script}</name> - <fsummary>Find an application downgrade script</fsummary> + <fsummary>Finds an application downgrade script.</fsummary> <type> <v>App = atom()</v> <v>OldVsn = Dir = string()</v> - <v>Script = Instructions -- see appup(4)</v> + <v>Script = Instructions</v> </type> <desc> <p>Tries to find an application downgrade script for <c>App</c> from the current version to a previous version <c>OldVsn</c> located in <c>Dir</c>.</p> <p>The downgrade script can then be evaluated using - <seealso marker="#eval_appup_script/4">eval_appup_script/4</seealso>. + <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso>. It is recommended to use - <seealso marker="#downgrade_app/2">downgrade_app/2,3</seealso> - instead, but this function is useful in order to inspect - the contents of the script.</p> + <seealso marker="#downgrade_app/2"><c>downgrade_app/2,3</c></seealso> + instead, but this function (<c>downgrade_script</c>) is useful + to inspect the contents of the script.</p> <p><c>App</c> is the name of the application, which must be started. <c>Dir</c> is the previous library directory of - <c>App</c>, the corresponding modules as well as - the old <c>.app</c> file should be located under - <c>Dir/ebin</c>. The <c>.appup</c> file should be located in + <c>App</c>. The corresponding modules and + the old <c>.app</c> file are to be located under + <c>Dir/ebin</c>. The <c>.appup</c> file is to be located in the <c>ebin</c> directory of the <em>current</em> library - directory of the application (<c>code:lib_dir(App)</c>).</p> + directory of the application + (<seealso marker="kernel:code#lib_dir/1"><c>code:lib_dir(App)</c>)</seealso>.</p> <p>The function looks in the <c>.appup</c> file and tries to - find an downgrade script from the current version of - the application. High-level instructions are translated to - low-level instructions and the instructions are sorted in - the same manner as when generating a <c>relup</c> script.</p> - <p>Returns <c>{ok, Script}</c> if successful.</p> + find a downgrade script from the current application version. + High-level instructions are translated to + low-level instructions. The instructions are sorted in + the same manner as when generating a <c>relup</c> file.</p> + <p>Returns <c>{ok, Script}</c> if successful. + For details about <c>Script</c>, see + <seealso marker="appup"><c>appup(4)</c></seealso>.</p> <p>Failure: If a script cannot be found, the function fails with an appropriate error reason.</p> </desc> </func> + <func> <name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> - <fsummary>Evaluate an application upgrade or downgrade script</fsummary> + <fsummary>Evaluates an application upgrade or downgrade script.</fsummary> <type> <v>App = atom()</v> <v>ToVsn = ToDir = string()</v> - <v>Script -- see upgrade_script/2, downgrade_script/3</v> + <v>Script</v> + <d>See <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso>, <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso></d> <v>Unpurged = [Module]</v> <v> Module = atom()</v> <v>Reason = term()</v> @@ -660,114 +723,100 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Evaluates an application upgrade or downgrade script <c>Script</c>, the result from calling - <seealso marker="#upgrade_app/2">upgrade_script/2</seealso> or - <seealso marker="#downgrade_app/3">downgrade_script/3</seealso>, + <seealso marker="#upgrade_script/2"><c>upgrade_script/2</c></seealso> or + <seealso marker="#downgrade_script/3"><c>downgrade_script/3</c></seealso>, exactly in the same way as - <seealso marker="#install_release/1">install_release/1,2</seealso> + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso> does.</p> <p><c>App</c> is the name of the application, which must be started. <c>ToVsn</c> is the version to be upgraded/downgraded to, and <c>ToDir</c> is the library directory of this version. The corresponding modules as well as the <c>.app</c> and - <c>.appup</c> files should be located under <c>Dir/ebin</c>.</p> - <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is - successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_emulator</c> if this instruction is - encountered in the script, or <c>{error, Reason}</c> if - an error occurred when evaluating the script.</p> - <p>If the <c>restart_new_emulator</c> instruction is found in - the script, <c>eval_appup_script/4</c> will return - <c>{error,restart_new_emulator}</c>. The reason for this is - that this instruction requires that a new version of the - emulator is started before the rest of the upgrade - instructions can be executed, and this can only be done by - <c>install_release/1,2</c>.</p> + <c>.appup</c> files are to be located under <c>Dir/ebin</c>.</p> + <p>Returns one of the following:</p> + <list type="bulleted"> + <item><c>{ok, Unpurged}</c> if evaluating the script is + successful, where <c>Unpurged</c> is a list of unpurged + modules</item> + <item><c>restart_emulator</c> if this instruction is + encountered in the script</item> + <item><c>{error, Reason}</c> if an error occurred when + finding or evaluating the script</item> + </list> + <p>If the <c>restart_new_emulator</c> instruction is found in + the script, + <seealso marker="#eval_appup_script/4"><c>eval_appup_script/4</c></seealso> + returns <c>{error,restart_new_emulator}</c>. This because + <c>restart_new_emulator</c> requires a new version of the + emulator to be started before the rest of the upgrade + instructions can be executed, and this can only be done by + <seealso marker="#install_release/1"><c>install_release/1,2</c></seealso>.</p> </desc> </func> </funcs> <section> <title>Typical Error Reasons</title> - <list type="bulleted"> - <item> - <p><c>{bad_masters, Masters}</c> - The master nodes - <c>Masters</c> are not alive.</p> - </item> - <item> - <p><c>{bad_rel_file, File}</c> - Specified <c>.rel</c> file - <c>File</c> can not be read, or does not contain a single - term.</p> - </item> - <item> - <p><c>{bad_rel_data, Data}</c> - Specified <c>.rel</c> file - does not contain a recognized release specification, but - another term <c>Data</c>.</p> - </item> - <item> - <p><c>{bad_relup_file, File}</c> - Specified <c>relup</c> file - <c>Relup</c> contains bad data.</p> - </item> - <item> - <p><c>{cannot_extract_file, Name, Reason}</c> - Problems when - extracting from a tar file, <c>erl_tar:extract/2</c> returned - <c>{error, {Name, Reason}}</c>.</p> - </item> - <item> - <p><c>{existing_release, Vsn}</c> - Specified release version - <c>Vsn</c> is already in use.</p> - </item> - <item> - <p><c>{Master, Reason, When}</c> - Some operation, indicated by - the term <c>When</c>, failed on the master node <c>Master</c> - with the specified error reason <c>Reason</c>.</p> - </item> - <item> - <p><c>{no_matching_relup, Vsn, CurrentVsn}</c> - Cannot find a - script for up/downgrading between <c>CurrentVsn</c> and - <c>Vsn</c>.</p> - </item> - <item> - <p><c>{no_such_directory, Path}</c> - The directory <c>Path</c> - does not exist.</p> - </item> - <item> - <p><c>{no_such_file, Path}</c> - The path <c>Path</c> (file or - directory) does not exist.</p> - </item> - <item> - <p><c>{no_such_file, {Master, Path}}</c> - The path <c>Path</c> - (file or directory) does not exist at the master node - <c>Master</c>.</p> - </item> - <item> - <p><c>{no_such_release, Vsn}</c> - The specified version - <c>Vsn</c> of the release does not exist.</p> - </item> - <item> - <p><c>{not_a_directory, Path}</c> - <c>Path</c> exists, but is - not a directory.</p> - </item> - <item> - <p><c>{Posix, File}</c> - Some file operation failed for - <c>File</c>. <c>Posix</c> is an atom named from the Posix - error codes, such as <c>enoent</c>, <c>eacces</c> or - <c>eisdir</c>. See <c>file(3)</c>.</p> - </item> - <item> - <p><c>Posix</c> - Some file operation failed, as above.</p> - </item> - </list> + <taglist> + <tag><c>{bad_masters, Masters}</c></tag> + <item><p>The master nodes <c>Masters</c> are not alive.</p></item> + <tag><c>{bad_rel_file, File}</c></tag> + <item><p>Specified <c>.rel</c> file <c>File</c> cannot be read or + does not contain a single term.</p></item> + <tag><c>{bad_rel_data, Data}</c></tag> + <item><p>Specified <c>.rel</c> file does not contain a recognized + release specification, but another term <c>Data</c>.</p></item> + <tag><c>{bad_relup_file, File}</c></tag> + <item><p>Specified <c>relup</c> file <c>Relup</c> contains bad + data.</p></item> + <tag><c>{cannot_extract_file, Name, Reason}</c></tag> + <item><p>Problems when extracting from a tar file, + <seealso marker="stdlib:erl_tar#extract/2"><c>erl_tar:extract/2</c></seealso> + returned <c>{error, {Name, Reason}}</c>.</p></item> + <tag><c>{existing_release, Vsn}</c></tag> + <item><p>Specified release version <c>Vsn</c> is already + in use.</p></item> + <tag><c>{Master, Reason, When}</c></tag> + <item><p>Some operation, indicated by the term <c>When</c>, failed + on the master node <c>Master</c> with the specified error + reason <c>Reason</c>.</p></item> + <tag><c>{no_matching_relup, Vsn, CurrentVsn}</c></tag> + <item><p>Cannot find a script for upgrading/downgrading between + <c>CurrentVsn</c> and <c>Vsn</c>.</p></item> + <tag><c>{no_such_directory, Path}</c></tag> + <item><p>The directory <c>Path</c>does not exist.</p></item> + <tag><c>{no_such_file, Path}</c></tag> + <item><p>The path <c>Path</c> (file or directory) does not + exist.</p></item> + <tag><c>{no_such_file, {Master, Path}}</c></tag> + <item><p>The path <c>Path</c> (file or directory) does not exist at + the master node <c>Master</c>.</p></item> + <tag><c>{no_such_release, Vsn}</c></tag> + <item><p>The specified release version <c>Vsn</c> does not + exist.</p></item> + <tag><c>{not_a_directory, Path}</c></tag> + <item><p><c>Path</c> exists but is not a directory.</p></item> + <tag><c>{Posix, File}</c></tag> + <item><p>Some file operation failed for <c>File</c>. <c>Posix</c> + is an atom named from the Posix error codes, such as + <c>enoent</c>, <c>eacces</c>, or <c>eisdir</c>. See + <seealso marker="kernel:file"><c>file(3)</c></seealso> + in <c>Kernel</c>.</p></item> + <tag><c>Posix</c></tag> + <item><p>Some file operation failed, as for the previous item in + the list.</p></item> + </taglist> </section> <section> - <title>SEE ALSO</title> - <p><seealso marker="doc/design_principles:release_handling">OTP Design Principles</seealso>, - <seealso marker="kernel:config">config(4)</seealso>, - <seealso marker="relup">relup(4)</seealso>, - <seealso marker="rel">rel(4)</seealso>, - <seealso marker="script">script(4)</seealso>, - <seealso marker="stdlib:sys">sys(3)</seealso>, - <seealso marker="systools">systools(3)</seealso></p> + <title>See Also</title> + <p><seealso marker="doc/design_principles:users_guide">OTP Design Principles</seealso>, + <seealso marker="kernel:config"><c>config(4)</c></seealso>, + <seealso marker="rel"><c>rel(4)</c></seealso>, + <seealso marker="relup"><c>relup(4)</c></seealso>, + <seealso marker="script"><c>script(4)</c></seealso>, + <seealso marker="stdlib:sys"><c>sys(3)</c></seealso>, + <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </erlref> diff --git a/lib/sasl/doc/src/relup.xml b/lib/sasl/doc/src/relup.xml index 8eecf3fce2..58918fc8e8 100644 --- a/lib/sasl/doc/src/relup.xml +++ b/lib/sasl/doc/src/relup.xml @@ -36,59 +36,53 @@ <p>The <em>release upgrade file</em> describes how a release is upgraded in a running system.</p> <p>This file is automatically generated by - <c>systools:make_relup/3,4</c>, using a release resource file - (<c>.rel</c>), application resource files (<c>.app</c>) and + <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>, + using a release resource file + (<c>.rel</c>), application resource files (<c>.app</c>), and application upgrade files (<c>.appup</c>) as input.</p> </description> <section> - <title>FILE SYNTAX</title> - <p>In a target system, the release upgrade file should be located in - the <c>OTP_ROOT/erts-EVsn/Vsn</c> directory.</p> + <title>File Syntax</title> + <p>In a target system, the release upgrade file is to be located in + directory <c>$ROOT/releases/Vsn</c>.</p> <p>The <c>relup</c> file contains one single Erlang term, which defines the instructions used to upgrade the release. The file has the following syntax:</p> <code type="none"> {Vsn, [{UpFromVsn, Descr, Instructions}, ...], - [{DownToVsn, Descr, Instructions}, ...]}. - </code> - <list type="bulleted"> - <item> - <p><c>Vsn = string()</c> is the current version of the release.</p> - </item> - <item> - <p><c>UpFromVsn = string()</c> is an earlier version of the release - to upgrade from.</p> - </item> - <item> - <p><c>Descr = term()</c> is a user defined parameter passed - from the <c>systools:make_relup/3,4</c> function. It will - be used in the return value of - <c>release_handler:install_release/1,2</c>.</p> - </item> - <item> - <p><c>Instructions</c> is a list of low-level release upgrade - instructions, see <c>appup(4)</c>.</p> - <p>It consists of the release upgrade instructions from + [{DownToVsn, Descr, Instructions}, ...]}.</code> + <taglist> + <tag><c>Vsn = string()</c></tag> + <item><p>Current release version.</p></item> + <tag><c>UpFromVsn = string()</c></tag> + <item><p>Earlier version of the release to upgrade from.</p></item> + <tag><c>Descr = term()</c></tag> + <item><p>A user-defined parameter passed + from the function + <seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>. + It is used in the return value of + <seealso marker="release_handler#install_release/1"><c>release_handler:install_release/1,2</c></seealso>.</p></item> + <tag><c>Instructions</c></tag> + <item><p>A list of low-level release upgrade instructions, see + <seealso marker="appup"><c>appup(4)</c></seealso>. + It consists of the release upgrade instructions from the respective application upgrade files (high-level instructions are translated to low-level instructions), in the same order - as in the start script.</p> - </item> - <item> - <p><c>DownToVsn = string()</c> is an earlier version of the release - to downgrade to.</p> - </item> - </list> - <p>When upgrading from <c>UpFromVsn</c> with - <c>release_handler:install_release/1,2</c>, there does not have to be - an exact match of versions, but <c>UpFromVsn</c> can be a sub-string - of the current release version.</p> + as in the start script.</p></item> + <tag><c>DownToVsn = string()</c></tag> + <item><p>Earlier version of the release to downgrade to.</p></item> + </taglist> </section> <section> - <title>SEE ALSO</title> - <p>app(4), appup(4), rel(4), release_handler(3), systools(3)</p> + <title>See Also</title> + <p><seealso marker="kernel:app"><c>app(4)</c></seealso>, + <seealso marker="appup"><c>appup(4)</c></seealso>, + <seealso marker="rel"><c>rel(4)</c></seealso>, + <seealso marker="release_handler"><c>release_handler(3)</c></seealso>, + <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </fileref> diff --git a/lib/sasl/doc/src/sasl_app.xml b/lib/sasl/doc/src/sasl_app.xml index fe38e69ce3..8d79251c7e 100644 --- a/lib/sasl/doc/src/sasl_app.xml +++ b/lib/sasl/doc/src/sasl_app.xml @@ -27,12 +27,11 @@ <docno></docno> <date></date> <rev></rev> - </header> - <app>sasl</app> - <appsummary>The SASL Application</appsummary> - <description> - <p>This section describes the SASL (System Architecture Support Libraries) - application which provides the following services:</p> + </header> + <app>sasl</app> + <appsummary>The SASL application</appsummary> + <description> + <p>The <c>SASL</c> application provides the following services:</p> <list type="bulleted"> <item><c>alarm_handler</c></item> <item><c>overload</c></item> @@ -40,138 +39,147 @@ <item><c>release_handler</c></item> <item><c>systools</c></item> </list> - <p>The SASL application also includes <c>error_logger</c> event - handlers for formatting SASL error and crash reports.</p> - + <p>The <c>SASL</c> application also includes <c>error_logger</c> event + handlers for formatting <c>SASL</c> error and crash reports.</p> <note> - <p>The SASL application in OTP has nothing to do with + <p>The <c>SASL</c> application in OTP has nothing to do with "Simple Authentication and Security Layer" (RFC 4422).</p> </note> - </description> <section> <title>Error Logger Event Handlers</title> <p>The following error logger event handlers are used by - the SASL application.</p> + the <c>SASL</c> application.</p> <taglist> <tag><c>sasl_report_tty_h</c></tag> <item> - <p>Formats and writes <em>supervisor reports</em>, <em>crash reports</em> and <em>progress reports</em> to <c>stdio</c>. - This error logger event handler will use + <p>Formats and writes <em>supervisor reports</em>, <em>crash + reports</em>, and <em>progress reports</em> to <c>stdio</c>. + This error logger event handler uses <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso> - in the Kernel application to limit how much detail are printed to - for crash and supervisor reports.</p> + in the <c>Kernel</c> application to limit how much detail is + printed in crash and supervisor reports.</p> </item> <tag><c>sasl_report_file_h</c></tag> <item> - <p>Formats and writes <em>supervisor reports</em>, <em>crash report</em> and <em>progress report</em> to a single file. - This error logger event handler will use + <p>Formats and writes <em>supervisor reports</em>, <em>crash + report</em>, and <em>progress report</em> to a single file. + This error logger event handler uses <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso> - in the Kernel application to limit how much detail are printed to - for crash and supervisor reports.</p> + in the <c>Kernel</c> application to limit the details + printed in crash and supervisor reports.</p> </item> <tag><c>log_mf_h</c></tag> <item> - <p>This error logger writes <em>all</em> events sent to - the error logger to disk.</p> - <p>To activate this event handler, the following three sasl - configuration parameters must be set: - <c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c> - and <c>error_logger_mf_maxfiles</c>. See below for more - information about the configuration parameters.</p> + <p>This error logger writes <em>all</em> events sent to the + error logger to disk. Multiple files and log rotation are + used. For efficiency reasons, each event is written as a + binary. For more information about this handler, + see <seealso marker="stdlib:log_mf_h">the <c>STDLIB</c> Reference + Manual</seealso>.</p> + <p>To activate this event handler, three <c>SASL</c> + configuration parameters must be set, + <c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c>, + and <c>error_logger_mf_maxfiles</c>. The next section provides + more information about the configuration parameters.</p> </item> </taglist> </section> <section> <title>Configuration</title> - <p>The following configuration parameters are defined for the SASL - application. See <c>app(4)</c> for more information about - configuration parameters:</p> + <p>The following configuration parameters are defined for the <c>SASL</c> + application. For more information about configuration parameters, see + <seealso marker="kernel:app"><c>app(4)</c></seealso> in <c>Kernel</c>.</p> + <p>All configuration parameters are optional.</p> <taglist> - <tag><c><![CDATA[sasl_error_logger = Value <optional>]]></c></tag> + <tag><c><![CDATA[sasl_error_logger = Value ]]></c></tag> <item> - <p><c>Value</c> is one of:</p> + <p><c>Value</c> is one of the following:</p> <taglist> <tag><c>tty</c></tag> - <item>Installs <c>sasl_report_tty_h</c> in the error logger. - This is the default option.</item> + <item><p>Installs <c>sasl_report_tty_h</c> in the error logger. + This is the default option.</p></item> <tag><c>{file,FileName}</c></tag> - <item>Installs <c>sasl_report_file_h</c> in the error logger. - This makes all reports go to the file <c>FileName</c>. - <c>FileName</c> is a string.</item> + <item><p>Installs <c>sasl_report_file_h</c> in the error logger. + All reports go to file <c>FileName</c>, which is a + string.</p></item> <tag><c>{file,FileName,Modes}</c></tag> - <item>Same as <c>{file,FileName}</c> except that the <c>Modes</c> - allows to specify the modes used for opening the <c>FileName</c> - given to the <seealso marker="kernel:file#open/2">file:open/2</seealso> - call. When not specified, the <c>Modes</c> defaults to <c>[write]</c>. - Use <c>[append]</c> for having the <c>FileName</c> open in append mode. - <c>FileName</c> is a string.</item> + <item><p>Same as <c>{file,FileName}</c>, except that <c>Modes</c> + allows you to specify the modes used for opening the <c>FileName</c> + given to the <seealso marker="kernel:file#open/2">file:open/2</seealso> + call. When not specified, <c>Modes</c> defaults to <c>[write]</c>. + Use <c>[append]</c> to have the <c>FileName</c> open in append mode. + <c>FileName</c> is a string.</p></item> <tag><c>false</c></tag> - <item> - <p>No SASL error logger handler is installed.</p> - </item> + <item><p>No <c>SASL</c> error logger handler is installed.</p></item> </taglist> </item> - <tag><c><![CDATA[errlog_type = error | progress | all <optional>]]></c></tag> + <tag><c><![CDATA[errlog_type = error | progress | all ]]></c></tag> <item> <p>Restricts the error logging performed by the specified - <c>sasl_error_logger</c> to error reports, progress reports, + <c>sasl_error_logger</c> to error reports or progress reports, or both. Default is <c>all</c>.</p> </item> - <tag><c><![CDATA[error_logger_mf_dir = string() | false<optional>]]></c></tag> + <tag><c><![CDATA[error_logger_mf_dir = string() | false ]]></c></tag> <item> - <p>Specifies in which directory the files are stored. If this - parameter is undefined or <c>false</c>, + <p>Specifies in which directory <c>log_mf_h</c> is to store + its files. If this parameter is undefined or <c>false</c>, the <c>log_mf_h</c> handler is not installed.</p> </item> - <tag><c><![CDATA[error_logger_mf_maxbytes = integer() <optional>]]></c></tag> + <tag><c><![CDATA[error_logger_mf_maxbytes = integer() ]]></c></tag> <item> - <p>Specifies how large each individual file can be. If this - parameter is undefined, the <c>log_mf_h</c> handler is not - installed.</p> + <p>Specifies the maximum size of each individual file written + by <c>log_mf_h</c>. If this parameter is undefined, + the <c>log_mf_h</c> handler is not installed.</p> </item> - <tag><c><![CDATA[error_logger_mf_maxfiles = 0<integer()<256 <optional>]]></c></tag> + <tag><c><![CDATA[error_logger_mf_maxfiles = 0<integer()<256 ]]></c></tag> <item> - <p>Specifies how many files are used. If this parameter is - undefined, the <c>log_mf_h</c> handler is not installed.</p> + <p>Specifies the number of files used by <c>log_mf_h</c>. If + this parameter is undefined, the <c>log_mf_h</c> handler is + not installed.</p> </item> - <tag><c><![CDATA[overload_max_intensity = float() > 0 <optional>]]></c></tag> + <tag><c><![CDATA[overload_max_intensity = float() > 0 ]]></c></tag> <item> - <p>Specifies the maximum intensity for <c>overload</c>. Default + <p>Specifies the maximum intensity + for <seealso marker="overload"><c>overload</c></seealso>. Default is <c>0.8</c>.</p> </item> - <tag><c><![CDATA[overload_weight = float() > 0 <optional>]]></c></tag> + <tag><c><![CDATA[overload_weight = float() > 0 ]]></c></tag> <item> - <p>Specifies the <c>overload</c> weight. Default is <c>0.1</c>.</p> + <p>Specifies the <seealso marker="overload"><c>overload</c></seealso> + weight. Default is <c>0.1</c>.</p> </item> - <tag><c><![CDATA[start_prg = string() <optional>]]></c></tag> + <tag><c><![CDATA[start_prg = string() ]]></c></tag> <item> - <p>Specifies which program should be used when restarting - the system. Default is <c>$OTP_ROOT/bin/start</c>.</p> + <p>Specifies the program to be used when restarting the system + during release installation. Default is + <c>$OTP_ROOT/bin/start</c>.</p> </item> - <tag><c><![CDATA[masters = [atom()] <optional>]]></c></tag> + <tag><c><![CDATA[masters = [atom()] ]]></c></tag> <item> - <p>Specifies which nodes this node uses to read/write release - information. This parameter is ignored if - the <c>client_directory</c> parameter is not set.</p> + <p>Specifies the nodes used by this node to read/write release + information. This parameter is ignored if parameter + <c>client_directory</c> is not set.</p> </item> - <tag><c><![CDATA[client_directory = string() <optional>]]></c></tag> + <tag><c><![CDATA[client_directory = string() ]]></c></tag> <item> <p>This parameter specifies the client directory at the master - nodes. Refer to Release Handling in <em>OTP Design Principles</em> for more information. This parameter is - ignored if the <c>masters</c> parameter is not set.</p> + nodes. For details, see + <seealso marker="doc/design_principles:release_handling">Release Handling</seealso> + in <em>OTP Design Principles</em>. This parameter is + ignored if parameter <c>masters</c> is not set.</p> </item> - <tag><c><![CDATA[static_emulator = true | false <optional>]]></c></tag> + <tag><c><![CDATA[static_emulator = true | false ]]></c></tag> <item> <p>Indicates if the Erlang emulator is statically installed. A node with a static emulator cannot switch dynamically to a - new emulator as the executable files are written into memory - statically. This parameter is ignored if the <c>masters</c> - and <c>client_directory</c> parameters are not set.</p> + new emulator, as the executable files are written into memory + statically. This parameter is ignored if parameters <c>masters</c> + and <c>client_directory</c> are not set.</p> </item> - <tag><c><![CDATA[releases_dir = string() <optional>]]></c></tag> + <tag><c><![CDATA[releases_dir = string() ]]></c></tag> <item> <p>Indicates where the <c>releases</c> directory is located. The release handler writes all its files to this directory. @@ -179,7 +187,7 @@ <c>RELDIR</c> is used. By default, this is <c>$OTP_ROOT/releases</c>.</p> </item> - <tag><c><![CDATA[utc_log = true | false <optional>]]></c></tag> + <tag><c><![CDATA[utc_log = true | false ]]></c></tag> <item> <p>If set to <c>true</c>, all dates in textual log outputs are displayed in Universal Coordinated Time with the string @@ -190,13 +198,13 @@ <section> <title>See Also</title> - <p><seealso marker="alarm_handler">alarm_handler(3)</seealso>, - error_logger(3), - log_mf_h(3), - <seealso marker="overload">overload(3)</seealso>, - <seealso marker="rb">rb(3)</seealso>, - <seealso marker="release_handler">release_handler(3)</seealso>, - <seealso marker="systools">systools(3)</seealso></p> + <p><seealso marker="alarm_handler"><c>alarm_handler(3)</c></seealso>, + <seealso marker="kernel:error_logger"><c>error_logger(3)</c></seealso>, + <seealso marker="stdlib:log_mf_h"><c>log_mf_h(3)</c></seealso>, + <seealso marker="overload"><c>overload(3)</c></seealso>, + <seealso marker="rb"><c>rb(3)</c></seealso>, + <seealso marker="release_handler"><c>release_handler(3)</c></seealso>, + <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </appref> diff --git a/lib/sasl/doc/src/sasl_intro.xml b/lib/sasl/doc/src/sasl_intro.xml index 2dc3efebc1..bbc9457103 100644 --- a/lib/sasl/doc/src/sasl_intro.xml +++ b/lib/sasl/doc/src/sasl_intro.xml @@ -31,22 +31,32 @@ </header> <section> - <title>About This Document</title> - <p>The SASL (System Architecture Support Libraries) - application provides support for:</p> + <title>Scope</title> + <p>The <c>SASL</c> application provides support for:</p> <list type="bulleted"> - <item>error logging</item> - <item>alarm handling</item> - <item>overload regulation</item> - <item>release handling</item> - <item>report browsing.</item> + <item>Error logging</item> + <item>Alarm handling</item> + <item>Overload regulation</item> + <item>Release handling</item> + <item>Report browsing</item> </list> - <p>In this document, "SASL Error Logging" describes the error - handler which produces the supervisor, progress, and crash - reports which can be written to screen, or to a specified file. - It also describes the report browser <c>rb</c>.</p> - <p>The chapters about release structure and release handling have - been moved to <em>OTP Design Principles</em>.</p> + <p>Section + <seealso marker="error_logging">SASL Error Logging</seealso> + describes the error + handler that produces the supervisor, progress, and crash + reports, which can be written to screen or to a specified file. + It also describes the Report Browser (RB).</p> + <p>The sections about release structure and release handling have + been moved to section + <seealso marker="doc/design_principles:users_guide">OTP Design Principles</seealso> + in <em>System Documentation</em>.</p> </section> + + <section> + <title>Prerequisites</title> + <p>It is assumed that the reader is familiar with the Erlang + programming language.</p> + </section> + </chapter> diff --git a/lib/sasl/doc/src/script.xml b/lib/sasl/doc/src/script.xml index 838efe69bb..db3ea0f487 100644 --- a/lib/sasl/doc/src/script.xml +++ b/lib/sasl/doc/src/script.xml @@ -37,25 +37,21 @@ <file>script</file> <filesummary>Boot script</filesummary> <description> - <p>The <em>boot script</em> describes how the Erlang runtime system is - started. It contains instructions on which code to load and - which processes and applications to start. - </p> - <p>The command <c>erl -boot Name</c> starts the system with a boot + <p>The <em>boot script</em> describes how the Erlang runtime system + is started. It contains instructions on which code to load and + which processes and applications to start.</p> + <p>Command <c>erl -boot Name</c> starts the system with a boot file called <c>Name.boot</c>, which is generated from the - <c>Name.script</c> file, using <c>systools:script2boot/1</c>. - </p> + <c>Name.script</c> file, using + <seealso marker="systools#script2boot/1"><c>systools:script2boot/1</c></seealso>.</p> <p>The <c>.script</c> file is generated by <c>systools</c> from a - <c>.rel</c> file and <c>.app</c> files. - </p> + <c>.rel</c> file and from <c>.app</c> files.</p> </description> <section> - <title>FILE SYNTAX</title> - <p>The boot script is stored in a file with the extension - <c>.script</c></p> - <p>The file has the following syntax: - </p> + <title>File Syntax</title> + <p>The boot script is stored in a file with extension + <c>.script</c>. The file has the following syntax:</p> <code type="none"> {script, {Name, Vsn}, [ @@ -70,100 +66,97 @@ ... {apply, {Mod, Func, Args}}, ... - {progress, started}]}. </code> - <list type="bulleted"> - <item><c>Name = string()</c> defines the name of the system. - </item> - <item><c>Vsn = string()</c> defines the version of the system. - </item> - <item><c>{progress, Term}</c> sets the "progress" of the - initialization program. The function <c>init:get_status()</c> - returns the current value of the progress, which is - <c>{InternalStatus,Term}</c>. - </item> - <item> - <p><c>{path, [Dir]}</c> where <c>Dir</c> is a string. This + {progress, started}]}.</code> + <taglist> + <tag><c>Name = string()</c></tag> + <item><p>Defines the system name.</p></item> + <tag><c>Vsn = string()</c></tag> + <item><p>Defines the system version.</p></item> + <tag><c>{progress, Term}</c></tag> + <item><p>Sets the "progress" of the initialization + program. The + <seealso marker="erts:init#get_status/0"><c>init:get_status/0</c></seealso> + function returns the current value of the progress, which is + <c>{InternalStatus,Term}</c>.</p></item> + <tag><c>{path, [Dir]}</c></tag> + <item><p><c>Dir</c> is a string. This argument sets the load path of the system to <c>[Dir]</c>. The load path used to load modules is obtained from the initial load path, which is given in the script file, together with - any path flags which were supplied in the command line - arguments. The command line arguments modify the path as + any path flags that were supplied in the command-line + arguments. The command-line arguments modify the path as follows:</p> <list type="bulleted"> <item><c>-pa Dir1 Dir2 ... DirN</c> adds the directories <c>Dir1, Dir2, ..., DirN</c> to the front of the initial - load path. - </item> + load path.</item> <item><c>-pz Dir1 Dir2 ... DirN</c> adds the directories <c>Dir1, Dir2, ..., DirN</c> to the end of the initial - load path. - </item> + load path.</item> <item> <p><c>-path Dir1 Dir2 ... DirN</c> defines a set of - directories <c>Dir1, Dir2, ..., DirN</c> which replaces + directories <c>Dir1, Dir2, ..., DirN</c>, which replace the search path given in the script file. Directory names in the path are interpreted as follows:</p> <list type="bulleted"> <item>Directory names starting with <c>/</c> are assumed - to be absolute path names. - </item> + to be absolute path names.</item> <item>Directory names not starting with <c>/</c> are - assumed to be relative the current working directory. - </item> + assumed to be relative the current working directory.</item> <item>The special <c>$ROOT</c> variable can only be used - in the script, not as a command line argument. The + in the script, not as a command-line argument. The given directory is relative the Erlang installation - directory. - </item> + directory.</item> </list> </item> </list> - </item> - <item><c>{primLoad, [Mod]}</c> loads the modules <c>[Mod]</c> - from the directories specified in <c>Path</c>. The script - interpreter fetches the appropriate module by calling the - function <c>erl_prim_loader:get_file(Mod)</c>. A fatal error - which terminates the system will occur if the module cannot be - located. - </item> - <item><c>{kernel_load_completed}</c> indicates that all modules - which <em>must</em> be loaded <em>before</em> any processes - are started are loaded. In interactive mode, all - <c>{primLoad,[Mod]}</c> commands interpreted after this - command are ignored, and these modules are loaded on demand. - In embedded mode, <c>kernel_load_completed</c> is ignored, and - all modules are loaded during system start. - </item> - <item><c>{kernelProcess, Name, {Mod, Func, Args}}</c> starts a - "kernel process". The kernel process <c>Name</c> is started - by evaluating <c>apply(Mod, Func, Args)</c> which is expected - to return <c>{ok, Pid}</c> or <c>ignore</c>. The <c>init</c> - process monitors the behaviour of <c>Pid</c> and terminates - the system if <c>Pid</c> dies. Kernel processes are key - components of the runtime system. Users do not normally add - new kernel processes. - </item> - <item><c>{apply, {Mod, Func, Args}}</c>. The init process simply - evaluates <c>apply(Mod, Func, Args)</c>. The system - terminates if this results in an error. The boot procedure - hangs if this function never returns. - </item> - </list> + </item> + <tag><c>{primLoad, [Mod]}</c></tag> + <item><p>Loads the modules <c>[Mod]</c> + from the directories specified in <c>Path</c>. The script + interpreter fetches the appropriate module by calling + <seealso marker="erts:erl_prim_loader#get_file/1"> + <c>erl_prim_loader:get_file(Mod)</c></seealso>. A fatal error + that terminates the system occurs if the module cannot be + located.</p></item> + <tag><c>{kernel_load_completed}</c></tag> + <item><p>Indicates that all modules + that <em>must</em> be loaded <em>before</em> any processes + are started are loaded. In interactive mode, all + <c>{primLoad,[Mod]}</c> commands interpreted after this + command are ignored, and these modules are loaded on demand. + In embedded mode, <c>kernel_load_completed</c> is ignored, and + all modules are loaded during system start.</p></item> + <tag><c>{kernelProcess, Name, {Mod, Func, Args}}</c></tag> + <item><p>Starts the + "kernel process" <c>Name</c> + by evaluating <c>apply(Mod, Func, Args)</c>. The start function is + to return <c>{ok, Pid}</c> or <c>ignore</c>. The <c>init</c> + process monitors the behavior of <c>Pid</c> and terminates + the system if <c>Pid</c> dies. Kernel processes are key + components of the runtime system. Users do not normally add + new kernel processes.</p></item> + <tag><c>{apply, {Mod, Func, Args}}</c>.</tag> + <item><p>The init process + evaluates <c>apply(Mod, Func, Args)</c>. The system + terminates if this results in an error. The boot procedure + hangs if this function never returns.</p></item> + </taglist> <note> - <p>In the <c>interactive</c> system the code loader provides - demand driven code loading, but in the <c>embedded</c> system - the code loader loads all the code immediately. The same - version of <c>code</c> is used in both cases. The code server - calls <c>init:get_argument(mode)</c> to find out if it should - run in demand mode, or non-demand driven mode. - </p> + <p>In an interactive system, the code loader provides + demand-driven code loading, but in an embedded system + the code loader loads all code immediately. The same + version of <seealso marker="kernel:code"><c>code</c></seealso> + is used in both cases. The code server calls + <seealso marker="erts:init#get_argument/1"><c>init:get_argument(mode)</c></seealso> + to determine if it is to run in demand mode or non-demand + driven mode.</p> </note> </section> <section> - <title>SEE ALSO</title> - <p>systools(3) - </p> + <title>See Also</title> + <p><seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </fileref> diff --git a/lib/sasl/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml index 11d99fa595..1a5119a5cf 100644 --- a/lib/sasl/doc/src/systools.xml +++ b/lib/sasl/doc/src/systools.xml @@ -31,17 +31,18 @@ <rev></rev> </header> <module>systools</module> - <modulesummary>A Set of Release Handling Tools.</modulesummary> + <modulesummary>A Set of Release Handling Tools</modulesummary> <description> <p>This module contains functions to generate boot scripts - (<c>.boot</c>, <c>.script</c>), release upgrade scripts + (<c>.boot</c>, <c>.script</c>), a release upgrade file (<c>relup</c>), and release packages.</p> </description> + <funcs> <func> <name>make_relup(Name, UpFrom, DownTo) -> Result</name> <name>make_relup(Name, UpFrom, DownTo, [Opt]) -> Result</name> - <fsummary>Generate a release upgrade file <c>relup</c>.</fsummary> + <fsummary>Generates a release upgrade file <c>relup</c>.</fsummary> <type> <v>Name = string()</v> <v>UpFrom = DownTo = [Name | {Name,Descr}]</v> @@ -50,93 +51,94 @@ | warnings_as_errors</v> <v> Dir = string()</v> <v>Result = ok | error | {ok,Relup,Module,Warnings} | {error,Module,Error}</v> - <v> Relup - see relup(4)</v> + <v> Relup, see relup(4)</v> <v> Module = atom()</v> <v> Warnings = Error = term()</v> </type> <desc> - <p>Generates a release upgrade file <c>relup</c> containing a - script which describes how to upgrade the system from a number - of previous releases, and how to downgrade to a number of - previous releases. The script is used by - <c>release_handler</c> when installing a new version of a - release in run-time.</p> - <p>By default, <c>relup</c> is placed in the current working - directory. If the option <c>{outdir,Dir}</c> is provided, - <c>relup</c> is placed in <c>Dir</c> instead.</p> + <p>Generates a release upgrade file <c>relup</c> containing instructions + for upgrading from or downgrading to one or more previous releases. + The instructions are used by + <seealso marker="release_handler"><c>release_handler</c></seealso> + when installing a new version of a release in runtime.</p> + <p>By default, <c>relup</c> file is located in the current working + directory. If option <c>{outdir,Dir}</c> is specified, + the <c>relup</c> file is located in <c>Dir</c> instead.</p> <p>The release resource file <c>Name.rel</c> is compared with - all release resource files <c>Name2.rel</c> specified in - <c>UpFrom</c> and <c>DownTo</c>. For each such pair, it is - deducted:</p> + all release resource files <c>Name2.rel</c>, specified in + <c>UpFrom</c> and <c>DownTo</c>. For each such pair, the + following is deducted:</p> <list type="bulleted"> <item> - <p>Which applications should be deleted, that is - applications which are listed in <c>Name.rel</c> but not - in <c>Name2.rel</c>.</p> + <p>Which applications to be deleted, that is, + applications listed in <c>Name.rel</c> but not + in <c>Name2.rel</c></p> </item> <item> - <p>Which applications should be added, that is applications - which are listed in <c>Name2.rel</c> but not in - <c>Name.rel</c>.</p> + <p>Which applications to be added, that is, applications + listed in <c>Name2.rel</c> but not in <c>Name.rel</c></p> </item> <item> - <p>Which applications should be upgraded/downgraded, that - is applications listed in both <c>Name.rel</c> and - <c>Name2.rel</c>, but with different versions.</p> + <p>Which applications to be upgraded/downgraded, that + is, applications listed in both <c>Name.rel</c> and + <c>Name2.rel</c> but with different versions</p> </item> <item> <p>If the emulator needs to be restarted after upgrading or - downgrading, that is if the ERTS version differs between - <c>Name.rel</c> and <c>Name2.rel</c>.</p> + downgrading, that is, if the <c>ERTS</c> version differs + between <c>Name.rel</c> and <c>Name2.rel</c></p> </item> </list> - <p>Instructions for this are added to the <c>relup</c> script in + <p>Instructions for this are added to the <c>relup</c> file in the above order. Instructions for upgrading or downgrading between application versions are fetched from the relevant application upgrade files <c>App.appup</c>, sorted in the same order as when generating a boot script, see - <c>make_script/1,2</c>. High-level instructions are translated - into low-level instructions and the result is printed to - <c>relup</c>.</p> - <p>The optional <c>Descr</c> parameter is included as-is in - the <c>relup</c> script, see <c>relup(4)</c>. Defaults to + <seealso marker="#make_script/1"><c>make_script/1,2</c></seealso>. + High-level instructions are translated + into low-level instructions and the result is printed to the + <c>relup</c> file.</p> + <p>The optional <c>Descr</c> parameter is included "as is" in + the <c>relup</c> file, see + <seealso marker="relup"><c>relup(4)</c></seealso>. Defaults to the empty list.</p> <p>All the files are searched for in the code path. It is - assumed that the <c>.app</c> and <c>.appup</c> file for an - application is located in the same directory.</p> - <p>If the option <c>{path,[Dir]}</c> is provided, this path is - appended to the current path. The wildcard <c>*</c> is - expanded to all matching directories. - Example: <c>lib/*/ebin</c>.</p> - <p>If the <c>restart_emulator</c> option is supplied, a + assumed that the <c>.app</c> and <c>.appup</c> files for an + application are located in the same directory.</p> + <p>If option <c>{path,[Dir]}</c> is specified, this path is + appended to the current path. Wildcard <c>*</c> is + expanded to all matching directories, for example, + <c>lib/*/ebin</c>.</p> + <p>If option <c>restart_emulator</c> is specified, a low-level instruction to restart the emulator is appended to - the relup scripts. This ensures that a complete reboot of + the <c>relup</c> file. This ensures that a complete reboot of the system is done when the system is upgraded or downgraded.</p> - <p>If an upgrade includes a change from an emulator earlier - than OTP R15 to OTP R15 or later, the warning - <c>pre_R15_emulator_upgrade</c> is issued. See <seealso - marker="doc/design_principles:appup_cookbook">Design - Principles</seealso> for more information about this.</p> + <p>If an upgrade includes a change from an emulator earlier + than OTP R15 to OTP R15 or later, the warning + <c>pre_R15_emulator_upgrade</c> is issued. For more information + about this, see + <seealso marker="doc/design_principles:appup_cookbook">Design + Principles</seealso> in <em>System Documentation</em>.</p> <p>By default, errors and warnings are printed to tty and - the function returns <c>ok</c> or <c>error</c>. If the option - <c>silent</c> is provided, the function instead returns - <c>{ok,Relup,Module,Warnings}</c> where <c>Relup</c> is - the release upgrade script, or it returns - <c>{error,Module,Error}</c>. Warnings and errors can be - converted to strings by calling + the function returns <c>ok</c> or <c>error</c>. If option + <c>silent</c> is specified, the function instead either returns + <c>{ok,Relup,Module,Warnings}</c>, where <c>Relup</c> is + the release upgrade file, or <c>{error,Module,Error}</c>. + Warnings and errors can be converted to strings by calling <c>Module:format_warning(Warnings)</c> or <c>Module:format_error(Error)</c>.</p> - <p>If the option <c>noexec</c> is provided, the function returns + <p>If option <c>noexec</c> is specified, the function returns the same values as for <c>silent</c> but no <c>relup</c> file is created.</p> - <p>If the option <c>warnings_as_errors</c> is provided, warnings - are treated as errors.</p> + <p>If option <c>warnings_as_errors</c> is specified, warnings + are treated as errors.</p> </desc> </func> + <func> <name>make_script(Name) -> Result</name> <name>make_script(Name, [Opt]) -> Result</name> - <fsummary>Generate a boot script <c>.script/.boot</c>.</fsummary> + <fsummary>Generates a boot script <c>.script/.boot</c>.</fsummary> <type> <v>Name = string()</v> <v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref | @@ -153,114 +155,117 @@ <desc> <p>Generates a boot script <c>Name.script</c> and its binary version, the boot file <c>Name.boot</c>. The boot file - specifies which code should be loaded and which applications - should be started when the Erlang runtime system is started. - See <c>script(4)</c>.</p> - <p>The release resource file <c>Name.rel</c> is read to find - out which applications are included in the release. Then - the relevant application resource files <c>App.app</c> are - read to find out which modules should be loaded and if and - how the application should be started. (Keys <c>modules</c> - and <c>mod</c>, see <c>app(4)</c>).</p> - <p>By default, the boot script and boot file are placed in + specifies which code to be loaded and which applications + to be started when the Erlang runtime system is started. + See <seealso marker="script"><c>script(4)</c></seealso>.</p> + <p>The release resource file <c>Name.rel</c> is read to determine + which applications are included in the release. Then + the relevant application resource files <c>App.app</c> are read + to determine which modules to be loaded, and if and + how the applications are to be started. (Keys <c>modules</c> + and <c>mod</c>, see + <seealso marker="kernel:app"><c>app(4)</c></seealso>.</p> + <p>By default, the boot script and boot file are located in the same directory as <c>Name.rel</c>. That is, in the current working directory unless <c>Name</c> contains a path. If - the option <c>{outdir,Dir}</c> is provided, they are placed + option <c>{outdir,Dir}</c> is specified, they are located in <c>Dir</c> instead.</p> - <p>The correctness of each application is checked:</p> + <p>The correctness of each application is checked as follows:</p> <list type="bulleted"> <item> <p>The version of an application specified in - the <c>.rel</c> file should be the same as the version + the <c>.rel</c> file is to be the same as the version specified in the <c>.app</c> file.</p> </item> <item> - <p>There should be no undefined applications, that is, - dependencies to applications which are not included in - the release. (Key <c>applications</c> in <c>.app</c> + <p>There are to be no undefined applications, that is, + dependencies to applications that are not included in + the release. (Key <c>applications</c> in the <c>.app</c> file).</p> </item> <item> - <p>There should be no circular dependencies among + <p>There are to be no circular dependencies among the applications.</p> </item> <item> - <p>There should be no duplicated modules, that is, modules with + <p>There are to be no duplicated modules, that is, modules with the same name but belonging to different applications.</p> </item> <item> - <p>If the <c>src_tests</c> option is specified, a + <p>If option <c>src_tests</c> is specified, a warning is issued if the source code for a module is - missing or newer than the object code.</p> + missing or is newer than the object code.</p> </item> </list> <p>The applications are sorted according to the dependencies between the applications. Where there are no dependencies, the order in the <c>.rel</c> file is kept.</p> - <p>The function will fail if the mandatory - applications <c>kernel</c> and <c>stdlib</c> are not - included in the <c>.rel</c> file and have start - type <c>permanent</c> (default).</p> - <p>If <c>sasl</c> is not included as an application in - the <c>.rel</c> file, a warning is emitted because such a - release can not be used in an upgrade. To turn off this - warning, add the option <c>no_warn_sasl</c>.</p> + <p>The function fails if the mandatory + applications <c>Kernel</c> and <c>STDLIB</c> are not + included in the <c>.rel</c> file and have start + type <c>permanent</c> (which is default).</p> + <p>If <c>SASL</c> is not included as an application in + the <c>.rel</c> file, a warning is issued because such a + release cannot be used in an upgrade. To turn off this + warning, add option <c>no_warn_sasl</c>.</p> <p>All files are searched for in the current path. It is assumed that the <c>.app</c> and <c>.beam</c> files for an - application is located in the same directory. The <c>.erl</c> + application are located in the same directory. The <c>.erl</c> files are also assumed to be located in this directory, unless - it is an <c>ebin</c> directory in which case they may be + it is an <c>ebin</c> directory in which case they can be located in the corresponding <c>src</c> directory.</p> - <p>If the option <c>{path,[Dir]}</c> is provided, this path is + <p>If option <c>{path,[Dir]}</c> is specified, this path is appended to the current path. A directory in the path can be - given with a wildcard <c>*</c>, this is expanded to all + specified with a wildcard <c>*</c>, this is expanded to all matching directories. Example: <c>"lib/*/ebin"</c>.</p> <p>In the generated boot script all application directories are - structured as <c>App-Vsn/ebin</c> and assumed to be located + structured as <c>App-Vsn/ebin</c>. They are assumed to be located in <c>$ROOT/lib</c>, where <c>$ROOT</c> is the root directory - of the installed release. If the <c>local</c> option is - supplied, the actual directories where the applications were + of the installed release. If option <c>local</c> is + specified, the actual directories where the applications were found are used instead. This is a useful way to test a generated boot script locally.</p> - <p>The <c>variables</c> option can be used to specify an + <p>Option <c>variables</c> can be used to specify an installation directory other than <c>$ROOT/lib</c> for some of the applications. If a variable <c>{VarName,Prefix}</c> is specified and an application is found in a directory - <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application will get + <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application gets the path <c>VarName/Rest/App-Vsn/ebin</c> in the boot script. If an application is found in a directory <c>Prefix/Rest</c>, - the path will be <c>VarName/Rest/App-Vsn/ebin</c>. When + the path is <c>VarName/Rest/App-Vsn/ebin</c>. When starting Erlang, all variables <c>VarName</c> are given - values using the <c>boot_var</c> command line flag.</p> - <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is - supplied, and <c>myapp.app</c> is found in - <c>lib/myapp/ebin</c>, then the path to this application in - the boot script will be <c>"$TEST/myapp-1/ebin"</c>. If - <c>myapp.app</c> is found in <c>lib/test</c>, then the path - will be <c>$TEST/test/myapp-1/ebin</c>.</p> + values using command-line flag <c>boot_var</c>.</p> + <p><em>Example:</em> If option <c>{variables,[{"TEST","lib"}]}</c> + is specified and <c>myapp.app</c> is found in + <c>lib/myapp/ebin</c>, the path to this application in + the boot script is <c>"$TEST/myapp-1/ebin"</c>. If + <c>myapp.app</c> is found in <c>lib/test</c>, the path + is <c>$TEST/test/myapp-1/ebin</c>.</p> <p>The checks performed before the boot script is generated can be extended with some cross reference checks by specifying - the <c>exref</c> option. These checks are performed with + option <c>exref</c>. These checks are performed with the Xref tool. All applications, or the applications specified with <c>{exref,[App]}</c>, are checked by Xref and - warnings are generated for calls to undefined functions.</p> + warnings are issued for calls to undefined functions.</p> <p>By default, errors and warnings are printed to tty and - the function returns <c>ok</c> or <c>error</c>. If the option - <c>silent</c> is provided, the function instead returns + the function returns <c>ok</c> or <c>error</c>. If option + <c>silent</c> is specified, the function instead returns <c>{ok,Module,Warnings}</c> or <c>{error,Module,Error}</c>. Warnings and errors can be converted to strings by calling <c>Module:format_warning(Warnings)</c> or <c>Module:format_error(Error)</c>.</p> - <p>If the option <c>warnings_as_errors</c> is provided, warnings - are treated as errors.</p> - <p>If the option <c>no_dot_erlang</c> is provided, the instruction to - load the <c>.erlang</c> file during boot is <em>NOT</em> included.</p> + <p>If option <c>warnings_as_errors</c> is specified, warnings + are treated as errors.</p> + <p>If option <c>no_dot_erlang</c> is specified, the instruction to + load the <c>.erlang</c> file during boot is <em>not</em> + included.</p> </desc> </func> + <func> <name>make_tar(Name) -> Result</name> <name>make_tar(Name, [Opt]) -> Result</name> - <fsummary>Create a release package.</fsummary> + <fsummary>Creates a release package.</fsummary> <type> <v>Name = string()</v> <v>Opt = {dirs,[IncDir]} | {path,[Dir]} | {variables,[Var]} | {var_tar,VarTar} | {erts,Dir} | src_tests | exref | {exref,[App]} | silent | {outdir,Dir}</v> @@ -276,90 +281,91 @@ <v> Warning = Error = term()</v> </type> <desc> - <p>Creates a release package file <c>Name.tar.gz</c>. file. + <p>Creates a release package file <c>Name.tar.gz</c>. This file must be uncompressed and unpacked on the target - system using the <c>release_handler</c>, before the new - release can be installed.</p> - <p>The release resource file <c>Name.rel</c> is read to find out + system using + <seealso marker="release_handler"><c>release_handler</c></seealso> + before the new release can be installed.</p> + <p>The release resource file <c>Name.rel</c> is read to determine which applications are included in the release. Then the relevant application resource files <c>App.app</c> are - read to find out the version and modules of each application. - (Keys <c>vsn</c> and <c>modules</c>, see <c>app(4)</c>).</p> - <p>By default, the release package file is placed in the same + read to determine the version and modules of each application + (keys <c>vsn</c> and <c>modules</c>, see + <seealso marker="kernel:app"><c>app(4)</c></seealso>).</p> + <p>By default, the release package file is located in the same directory as <c>Name.rel</c>. That is, in the current working - directory unless <c>Name</c> contains a path. If the option - <c>{outdir,Dir}</c> is provided, it is placed in <c>Dir</c> + directory unless <c>Name</c> contains a path. If option + <c>{outdir,Dir}</c> is specified, it is located in <c>Dir</c> instead.</p> <p>By default, the release package contains the directories <c>lib/App-Vsn/ebin</c> and <c>lib/App-Vsn/priv</c> for each - included application. If more directories, the option - <c>dirs</c> is supplied. Example: + included application. If more directories are to be included, + option <c>dirs</c> is specified, for example, <c>{dirs,[src,examples]}</c>.</p> <p>All these files are searched for in the current path. If - the option <c>{path,[Dir]}</c> is provided, this path is - appended to the current path. The wildcard <c>*</c> is + option <c>{path,[Dir]}</c> is specified, this path is + appended to the current path. Wildcard <c>*</c> is expanded to all matching directories. Example: <c>"lib/*/ebin"</c>.</p> - <p>The <c>variables</c> option can be used to specify an + <p>Option <c>variables</c> can be used to specify an installation directory other than <c>lib</c> for some of - the applications. If a variable <c>{VarName,Prefix}</c> is - specified and an application is found in a directory - <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application will be + the applications. If variable <c>{VarName,Prefix}</c> is + specified and an application is found in directory + <c>Prefix/Rest/App[-Vsn]/ebin</c>, this application is packed into a separate <c>VarName.tar.gz</c> file as <c>Rest/App-Vsn/ebin</c>.</p> - <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is - supplied, and <c>myapp.app</c> is found in - <c>lib/myapp-1/ebin</c>, the the application <c>myapp</c> is + <p><em>Example:</em> If option <c>{variables,[{"TEST","lib"}]}</c> + is specified and <c>myapp.app</c> is located in + <c>lib/myapp-1/ebin</c>, application <c>myapp</c> is included in <c>TEST.tar.gz</c>:</p> <pre> % <input>tar tf TEST.tar</input> myapp-1/ebin/myapp.app -... - </pre> - <p>The <c>{var_tar,VarTar}</c> option can be used to specify if - and where a separate package should be stored. In this option, - <c>VarTar</c> is:</p> - <list type="bulleted"> - <item> - <p><c>include</c>. Each separate (variable) package is - included in the main <c>ReleaseName.tar.gz</c> file. This - is the default.</p> - </item> - <item> - <p><c>ownfile</c>. Each separate (variable) package is - generated as separate files in the same directory as - the <c>ReleaseName.tar.gz</c> file.</p> - </item> - <item> - <p><c>omit</c>. No separate (variable) packages are - generated and applications which are found underneath a - variable directory are ignored.</p> - </item> - </list> - <p>A directory called <c>releases</c> is also included in +...</pre> + <p>Option <c>{var_tar,VarTar}</c> can be used to specify if + and where a separate package is to be stored. In this option + <c>VarTar</c> is one of the following:</p> + <taglist> + <tag><c>include</c></tag> + <item><p>Each separate (variable) package is included in the + main <c>ReleaseName.tar.gz</c> file. This is the + default.</p></item> + <tag><c>ownfile</c></tag> + <item><p>Each separate (variable) package is + generated as a separate file in the same directory as + the <c>ReleaseName.tar.gz</c> file.</p></item> + <tag><c>omit</c></tag> + <item><p>No separate (variable) packages are + generated. Applications that are found underneath a + variable directory are ignored.</p></item> + </taglist> + <p>A directory <c>releases</c> is also included in the release package, containing <c>Name.rel</c> and a - subdirectory called <c>RelVsn</c>. <c>RelVsn</c> is + subdirectory <c>RelVsn</c>. <c>RelVsn</c> is the release version as specified in <c>Name.rel</c>.</p> <p><c>releases/RelVsn</c> contains the boot script <c>Name.boot</c> renamed to <c>start.boot</c> and, if found, the files <c>relup</c> and <c>sys.config</c>. These files are searched for in the same directory as <c>Name.rel</c>, in the current working directory, and in any directories - specified using the <c>path</c> option.</p> - <p>If the release package should contain a new Erlang runtime + specified using option <c>path</c>.</p> + <p>If the release package is to contain a new Erlang runtime system, the <c>bin</c> directory of the specified runtime system <c>{erts,Dir}</c> is copied to <c>erts-ErtsVsn/bin</c>.</p> - <p>All checks performed with the <c>make_script</c> function - are performed before the release package is created. The - <c>src_tests</c> and <c>exref</c> options are also + <p>All checks with function + <seealso marker="#make_script/1"><c>make_script</c></seealso> + are performed before the release package is created. + Options <c>src_tests</c> and <c>exref</c> are also valid here.</p> <p>The return value and the handling of errors and warnings - are the same as described for <c>make_script</c> above.</p> + are the same as described for + <seealso marker="#make_script/1"><c>make_script</c></seealso>.</p> </desc> </func> + <func> <name>script2boot(File) -> ok | error</name> - <fsummary>Generate a binary version of a boot script.</fsummary> + <fsummary>Generates a binary version of a boot script.</fsummary> <type> <v>File = string()</v> </type> @@ -367,17 +373,24 @@ myapp-1/ebin/myapp.app <p>The Erlang runtime system requires that the contents of the script used to boot the system is a binary Erlang term. This function transforms the <c>File.script</c> boot script - to a binary term which is stored in the file <c>File.boot</c>.</p> - <p>A boot script generated using the <c>make_script</c> - function is already transformed to the binary form.</p> + to a binary term, which is stored in the <c>File.boot</c> + file.</p> + <p>A boot script generated using + <seealso marker="#make_script/1"><c>make_script</c></seealso> + is already transformed to the binary form.</p> </desc> </func> </funcs> <section> - <title>SEE ALSO</title> - <p>app(4), appup(4), erl(1), rel(4), release_handler(3), relup(4), - script(4)</p> + <title>See Also</title> + <p><seealso marker="kernel:app"><c>app(4)</c></seealso>, + <seealso marker="appup"><c>appup(4)</c></seealso>, + <seealso marker="erts:erl"><c>erl(1)</c></seealso>, + <seealso marker="rel"><c>rel(4)</c></seealso>, + <seealso marker="release_handler"><c>release_handler(3)</c></seealso>, + <seealso marker="relup"><c>relup(4)</c></seealso>, + <seealso marker="script"><c>script(4)</c></seealso></p> </section> </erlref> diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index f2936c0c1d..77418f920f 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -29,7 +29,7 @@ %% {update, snmpa_local_db, soft, soft_purge, soft_purge, []} %% {add_module, snmpm_net_if_mt} [ - {"5.3", [{load_module, snmp_conf, soft_purge, soft_purge, []}]}, + {"5.2", [{load_module, snmp_conf, soft_purge, soft_purge, []}]}, {"5.1.2", [ % Only runtime dependencies change ]}, {"5.1.1", [{restart_application, snmp}]}, @@ -51,6 +51,7 @@ %% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} [ + {"5.2", [{load_module, snmp_conf, soft_purge, soft_purge, []}]}, {"5.1.2", [ % Only runtime dependencies change ]}, {"5.1.1", [{restart_application, snmp}]}, diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index a468c131ce..b2b85eaf8d 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -212,7 +212,7 @@ hello(Hello = #client_hello{client_version = ClientVersion, client_ecc = {EllipticCurves, EcPointFormats}, negotiated_protocol = Protocol}, ?MODULE) end; -hello(Hello, +hello(Hello = #server_hello{}, #state{connection_states = ConnectionStates0, negotiated_version = ReqVersion, role = client, diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl index 3a9f21ea99..75b639b23b 100644 --- a/lib/ssl/test/ssl_ECC_SUITE.erl +++ b/lib/ssl/test/ssl_ECC_SUITE.erl @@ -248,10 +248,13 @@ start_client(openssl, Port, CA, OwnCa, Cert, Key, Config) -> PrivDir = ?config(priv_dir, Config), NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -verify 2 -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ Cert ++ " -CAfile " ++ NewCA - ++ " -key " ++ Key ++ " -host localhost -msg -debug", - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_client", "-verify", "2", "-port", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", Cert, "-CAfile", NewCA, + "-key", Key, "-host","localhost", "-msg", "-debug"], + + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, "Hello world"), OpenSslPort; start_client(erlang, Port, CA, _, Cert, Key, Config) -> @@ -270,10 +273,11 @@ start_server(openssl, CA, OwnCa, Cert, Key, Config) -> Port = ssl_test_lib:inet_port(node()), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -verify 2 -cert " ++ Cert ++ " -CAfile " ++ NewCA - ++ " -key " ++ Key ++ " -msg -debug", - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version), + "-verify", "2", "-cert", Cert, "-CAfile", NewCA, + "-key", Key, "-msg", "-debug"], + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, "Hello world"), {OpenSslPort, Port}; start_server(erlang, CA, _, Cert, Key, Config) -> diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 69972c44ed..05b040a2ab 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -136,6 +136,7 @@ api_tests() -> shutdown_both, shutdown_error, hibernate, + hibernate_right_away, listen_socket, ssl_accept_timeout, ssl_recv_timeout, @@ -2923,6 +2924,43 @@ hibernate(Config) -> ssl_test_lib:close(Client). %%-------------------------------------------------------------------- + +hibernate_right_away() -> + [{doc,"Check that an SSL connection that is configured to hibernate " + "after 0 or 1 milliseconds hibernates as soon as possible and not " + "crashes"}]. + +hibernate_right_away(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + StartServerOpts = [{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, ServerOpts}], + StartClientOpts = [return_socket, + {node, ClientNode}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}], + + Server1 = ssl_test_lib:start_server(StartServerOpts), + Port1 = ssl_test_lib:inet_port(Server1), + {Client1, #sslsocket{}} = ssl_test_lib:start_client(StartClientOpts ++ + [{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]), + ssl_test_lib:close(Server1), + ssl_test_lib:close(Client1), + + Server2 = ssl_test_lib:start_server(StartServerOpts), + Port2 = ssl_test_lib:inet_port(Server2), + {Client2, #sslsocket{}} = ssl_test_lib:start_client(StartClientOpts ++ + [{port, Port2}, {options, [{hibernate_after, 1}|ClientOpts]}]), + ssl_test_lib:close(Server2), + ssl_test_lib:close(Client2). + +%%-------------------------------------------------------------------- listen_socket() -> [{doc,"Check error handling and inet compliance when calling API functions with listen sockets."}]. diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index f25f6f9425..9a76d603b1 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -1192,13 +1192,13 @@ wait_for_openssl_server(Port, N) -> end. version_flag(tlsv1) -> - " -tls1 "; + "-tls1"; version_flag('tlsv1.1') -> - " -tls1_1 "; + "-tls1_1"; version_flag('tlsv1.2') -> - " -tls1_2 "; + "-tls1_2"; version_flag(sslv3) -> - " -ssl3 ". + "-ssl3". filter_suites(Ciphers0) -> Version = tls_record:highest_protocol_version([]), @@ -1243,3 +1243,9 @@ close_loop(Port, Time, SentClose) -> ct:log("Timeout~n",[]) end end. + +portable_open_port(Exe, Args) -> + AbsPath = os:find_executable(Exe), + ct:pal("open_port({spawn_executable, ~p}, [{args, ~p}, stderr_to_stdout]).", [AbsPath, Args]), + open_port({spawn_executable, AbsPath}, + [{args, Args}, stderr_to_stdout]). diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 16b6cb10b9..119baf1072 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -262,12 +262,11 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile, - - ct:log("openssl cmd: ~p~n", [Cmd]), + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + "-cert", CertFile, "-key", KeyFile], - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -302,13 +301,11 @@ basic_erlang_server_openssl_client(Config) when is_list(Config) -> {mfa, {?MODULE, erlang_ssl_receive, [Data]}}, {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), - - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ - " -host localhost" ++ workaround_openssl_s_clinent(), - - ct:log("openssl cmd: ~p~n", [Cmd]), - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port) | workaround_openssl_s_clinent()], + + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, Data), ssl_test_lib:check_result(Server, ok), @@ -334,12 +331,12 @@ erlang_client_openssl_server(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile, - - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-key", KeyFile], + + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -376,12 +373,12 @@ erlang_server_openssl_client(Config) when is_list(Config) -> Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost", + Exe = "openssl", + Args = ["s_client", "-connect", "localhost: " ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version)], - ct:log("openssl cmd: ~p~n", [Cmd]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), true = port_command(OpenSslPort, Data), ssl_test_lib:check_result(Server, ok), @@ -407,14 +404,13 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-CAfile", CaCertFile, + "-key", KeyFile, "-Verify", "2", "-msg"], - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile - ++ " -key " ++ KeyFile ++ " -Verify 2 -msg", - - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -455,13 +451,14 @@ erlang_server_openssl_client_dsa_cert(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost " ++ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile - ++ " -key " ++ KeyFile ++ " -msg", - - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_client", "-connect", "localhost: " ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, + "-CAfile", CaCertFile, + "-key", KeyFile, "-msg"], + + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, Data), ssl_test_lib:check_result(Server, ok), @@ -491,12 +488,13 @@ erlang_server_openssl_client_reuse_session(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost -reconnect", - - ct:log("openssl cmd: ~p~n", [Cmd]), - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + Exe = "openssl", + Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-reconnect"], + + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, Data), @@ -527,12 +525,12 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) -> KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-key", KeyFile, "-msg"], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -576,12 +574,12 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-key", KeyFile, "-msg"], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -622,12 +620,12 @@ erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) -> {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost -msg", - - ct:log("openssl cmd: ~p~n", [Cmd]), + Exe = "openssl", + Args = ["s_client","-connect", "localhost: " ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-msg"], - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, Data), @@ -657,13 +655,13 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -msg", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-key", KeyFile, "-msg"], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), + ssl_test_lib:wait_for_openssl_server(Port), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, @@ -699,13 +697,13 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) -> CaCertFile = proplists:get_value(cacertfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile - ++ " -key " ++ KeyFile ++ " -Verify 2", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-CAfile", CaCertFile, + "-key", KeyFile, "-Verify", "2"], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -750,13 +748,14 @@ erlang_server_openssl_client_client_cert(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ClientOpts), KeyFile = proplists:get_value(keyfile, ClientOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile - ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost", - - ct:log("openssl cmd: ~p~n", [Cmd]), + Exe = "openssl", + Args = ["s_client", "-cert", CertFile, + "-CAfile", CaCertFile, + "-key", KeyFile,"-connect", "localhost:" ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version)], - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), + true = port_command(OpenSslPort, Data), ssl_test_lib:check_result(Server, ok), @@ -839,12 +838,11 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version), + "-cert", CertFile, "-key", KeyFile], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -895,12 +893,11 @@ expired_session(Config) when is_list(Config) -> CertFile = proplists:get_value(certfile, ServerOpts), KeyFile = proplists:get_value(keyfile, ServerOpts), - Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", + Exe = "openssl", + Args = ["s_server", "-accept", integer_to_list(Port), + "-cert", CertFile,"-key", KeyFile], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), ssl_test_lib:wait_for_openssl_server(Port), @@ -953,12 +950,11 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), - Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ - " -host localhost -ssl2 -msg", - - ct:log("openssl cmd: ~p~n", [Cmd]), + Exe = "openssl", + Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port), + "-ssl2", "-msg"], - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), true = port_command(OpenSslPort, Data), ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]), @@ -1033,7 +1029,7 @@ erlang_server_alpn_openssl_client(Config) when is_list(Config) -> Data = "From openssl to erlang", start_erlang_server_and_openssl_client_with_opts(Config, [{alpn_preferred_protocols, [<<"spdy/2">>]}], - "", + [], Data, fun(Server, OpensslPort) -> true = port_command(OpensslPort, Data), ssl_test_lib:check_result(Server, ok) @@ -1046,7 +1042,7 @@ erlang_server_openssl_client_alpn(Config) when is_list(Config) -> Data = "From openssl to erlang", start_erlang_server_and_openssl_client_with_opts(Config, [], - "-alpn spdy/2", + ["-alpn", "spdy/2"], Data, fun(Server, OpensslPort) -> true = port_command(OpensslPort, Data), ssl_test_lib:check_result(Server, ok) @@ -1179,7 +1175,7 @@ erlang_client_openssl_server_npn_only_client(Config) when is_list(Config) -> %%-------------------------------------------------------------------------- erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) -> Data = "From openssl to erlang", - start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], "", + start_erlang_server_and_openssl_client_with_opts(Config, [{next_protocols_advertised, [<<"spdy/2">>]}], [], Data, fun(Server, OpensslPort) -> true = port_command(OpensslPort, Data), ssl_test_lib:check_result(Server, ok) @@ -1188,7 +1184,7 @@ erlang_server_openssl_client_npn_only_server(Config) when is_list(Config) -> erlang_server_openssl_client_npn_only_client(Config) when is_list(Config) -> Data = "From openssl to erlang", - start_erlang_server_and_openssl_client_with_opts(Config, [], "-nextprotoneg spdy/2", + start_erlang_server_and_openssl_client_with_opts(Config, [], ["-nextprotoneg", "spdy/2"], Data, fun(Server, OpensslPort) -> true = port_command(OpensslPort, Data), ssl_test_lib:check_result(Server, ok) @@ -1261,7 +1257,7 @@ client_check_result(Port, DataExpected, DataReceived) -> client_check_result(Port, DataExpected, NewData) end after 3000 -> - ct:fail({"Time out on opensssl Client", {expected, DataExpected}, + ct:fail({"Time out on openSSL Client", {expected, DataExpected}, {got, DataReceived}}) end. client_check_result(Port, DataExpected) -> @@ -1613,12 +1609,12 @@ start_erlang_server_and_openssl_client_for_npn_negotiation(Config, Data, Callbac {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client -nextprotoneg http/1.0,spdy/2 -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost", - ct:log("openssl cmd: ~p~n", [Cmd]), + Exe = "openssl", + Args = ["s_client", "-nextprotoneg", "http/1.0,spdy/2", "-msg", "-connect", "localhost:" + ++ integer_to_list(Port), ssl_test_lib:version_flag(Version)], - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), Callback(Server, OpenSslPort), @@ -1642,12 +1638,12 @@ start_erlang_server_and_openssl_client_with_opts(Config, ErlangServerOpts, OpenS {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), Version = tls_record:protocol_version(tls_record:highest_protocol_version([])), - Cmd = "openssl s_client " ++ OpenSSLClientOpts ++ " -msg -port " ++ integer_to_list(Port) ++ ssl_test_lib:version_flag(Version) ++ - " -host localhost", + + Exe = "openssl", + Args = ["s_client"] ++ OpenSSLClientOpts ++ ["-msg", "-connect", "localhost:" ++ integer_to_list(Port), + ssl_test_lib:version_flag(Version)], - ct:log("openssl cmd: ~p~n", [Cmd]), - - OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args), Callback(Server, OpenSslPort), @@ -1679,8 +1675,6 @@ erlang_ssl_receive(Socket, Data) -> erlang_ssl_receive(Socket,Data); Other -> ct:fail({unexpected_message, Other}) - after 4000 -> - ct:fail({did_not_get, Data}) end. connection_info(Socket, Version) -> @@ -1753,7 +1747,9 @@ check_sane_openssl_renegotaite(Config, _) -> check_sane_openssl_renegotaite(Config). check_sane_openssl_renegotaite(Config) -> - case os:cmd("openssl version") of + case os:cmd("openssl version") of + "OpenSSL 1.0.0" ++ _ -> + {skip, "Known renegotiation bug in OpenSSL"}; "OpenSSL 0.9.8" ++ _ -> {skip, "Known renegotiation bug in OpenSSL"}; "OpenSSL 0.9.7" ++ _ -> @@ -1793,13 +1789,13 @@ workaround_openssl_s_clinent() -> %% explicitly specified case os:cmd("openssl version") of "OpenSSL 1.0.1c" ++ _ -> - " -no_tls1_2 "; + ["-no_tls1_2"]; "OpenSSL 1.0.1d" ++ _ -> - " -no_tls1_2 "; + ["-no_tls1_2"]; "OpenSSL 1.0.1e" ++ _ -> - " -no_tls1_2 "; + ["-no_tls1_2"]; "OpenSSL 1.0.1f" ++ _ -> - " -no_tls1_2 "; + ["-no_tls1_2"]; _ -> - "" + [] end. diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index c5bad41573..f81d0bbbd9 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -225,9 +225,9 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process) if(driver_monitor_process(port, process, &monitor) == 0) { // Should we be able to handle commands when recursing? probably // fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr); - app->recurse_level += 2; + app->recurse_level++; app->dispatch_cb(wxe_queue, process); - app->recurse_level -= 2; + app->recurse_level--; // fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); driver_demonitor_process(port, &monitor); } |