Created
February 15, 2022 19:06
-
-
Save 221V/17046ff1cd942d4a1dee207764ff8b9d to your computer and use it in GitHub Desktop.
O_o erl 19.3.6.5 diff O_o
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ diff -r otp-OTP-19.3.6.5 erlang-otp-6356f67 | |
diff -r otp-OTP-19.3.6.5/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem erlang-otp-6356f67/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem | |
1c1,31 | |
< ../../test/httpc_SUITE_data/ssl_client_cert.pem | |
\ Наприкінці файла немає нового рядка | |
--- | |
> -----BEGIN RSA PRIVATE KEY----- | |
> MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n | |
> 0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr | |
> 3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB | |
> AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB | |
> I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna | |
> QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f | |
> eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws | |
> /LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI | |
> ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV | |
> LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj | |
> 40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6 | |
> UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80 | |
> t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J | |
> -----END RSA PRIVATE KEY----- | |
> -----BEGIN CERTIFICATE----- | |
> MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT | |
> BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE | |
> BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD | |
> VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw | |
> MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl | |
> cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD | |
> VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB | |
> AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV | |
> wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53 | |
> h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID | |
> AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A | |
> PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD | |
> 4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ | |
> S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5 | |
> -----END CERTIFICATE----- | |
diff -r otp-OTP-19.3.6.5/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem erlang-otp-6356f67/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem | |
1c1,31 | |
< ../../test/httpc_SUITE_data/ssl_client_cert.pem | |
\ Наприкінці файла немає нового рядка | |
--- | |
> -----BEGIN RSA PRIVATE KEY----- | |
> MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n | |
> 0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr | |
> 3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB | |
> AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB | |
> I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna | |
> QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f | |
> eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws | |
> /LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI | |
> ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV | |
> LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj | |
> 40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6 | |
> UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80 | |
> t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J | |
> -----END RSA PRIVATE KEY----- | |
> -----BEGIN CERTIFICATE----- | |
> MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT | |
> BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE | |
> BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD | |
> VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw | |
> MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl | |
> cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD | |
> VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB | |
> AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV | |
> wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53 | |
> h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID | |
> AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A | |
> PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD | |
> 4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ | |
> S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5 | |
> -----END CERTIFICATE----- | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/ftp_internal.hrl erlang-otp-6356f67/lib/inets/test/ftp_internal.hrl | |
1c1,33 | |
< ../src/ftp/ftp_internal.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2005-2016. 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. | |
> %% 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(ftp_internal_hrl). | |
> -define(ftp_internal_hrl, true). | |
> | |
> -include_lib("inets/src/inets_app/inets_internal.hrl"). | |
> | |
> -define(SERVICE, ftpc). | |
> -define(fcri(Label, Content), ?report_important(Label, ?SERVICE, Content)). | |
> -define(fcrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)). | |
> -define(fcrd(Label, Content), ?report_debug(Label, ?SERVICE, Content)). | |
> -define(fcrt(Label, Content), ?report_trace(Label, ?SERVICE, Content)). | |
> | |
> -endif. % -ifdef(ftp_internal_hrl). | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/httpc_internal.hrl erlang-otp-6356f67/lib/inets/test/httpc_internal.hrl | |
1c1,177 | |
< ../src/http_client/httpc_internal.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2005-2016. 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. | |
> %% 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(httpc_internal_hrl). | |
> -define(httpc_internal_hrl, true). | |
> | |
> -include_lib("inets/src/inets_app/inets_internal.hrl"). | |
> | |
> -define(SERVICE, httpc). | |
> -define(hcri(Label, Data), ?report_important(Label, ?SERVICE, Data)). | |
> -define(hcrv(Label, Data), ?report_verbose(Label, ?SERVICE, Data)). | |
> -define(hcrd(Label, Data), ?report_debug(Label, ?SERVICE, Data)). | |
> -define(hcrt(Label, Data), ?report_trace(Label, ?SERVICE, Data)). | |
> | |
> -define(HTTP_REQUEST_TIMEOUT, infinity). | |
> -define(HTTP_REQUEST_CTIMEOUT, ?HTTP_REQUEST_TIMEOUT). | |
> -define(HTTP_PIPELINE_TIMEOUT, 0). | |
> -define(HTTP_PIPELINE_LENGTH, 2). | |
> -define(HTTP_MAX_TCP_SESSIONS, 2). | |
> -define(HTTP_MAX_REDIRECTS, 4). | |
> -define(HTTP_KEEP_ALIVE_TIMEOUT, 120000). | |
> -define(HTTP_KEEP_ALIVE_LENGTH, 5). | |
> -define(TLS_UPGRADE_TOKEN, "TLS/1.0"). | |
> | |
> %%% HTTP Client per request settings | |
> -record(http_options, | |
> { | |
> %% "HTTP/1.1" | "HTTP/1.0" | "HTTP/0.9" | |
> version :: 'undefined' | string(), | |
> | |
> %% ms before a request times out | |
> timeout = ?HTTP_REQUEST_TIMEOUT :: timeout(), | |
> | |
> %% true if auto redirect on 30x response | |
> autoredirect = true :: boolean(), | |
> | |
> %% ssl socket options | |
> ssl = [], | |
> | |
> %% {User, Password} = {string(), string()} | |
> proxy_auth, | |
> | |
> %% true if not strictly std compliant | |
> relaxed = false :: boolean(), | |
> | |
> %% integer() - ms before a connect times out | |
> connect_timeout = ?HTTP_REQUEST_CTIMEOUT :: timeout(), | |
> | |
> %% Use %-encoding rfc 2396 | |
> url_encode :: 'undefined' | boolean() | |
> } | |
> ). | |
> -type http_options() :: #http_options{}. | |
> | |
> %%% HTTP Client per profile setting. | |
> -record(options, | |
> { | |
> proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]}, | |
> https_proxy = {undefined, []}, % {{ProxyHost, ProxyPort}, [NoProxy]} | |
> %% 0 means persistent connections are used without pipelining | |
> pipeline_timeout = ?HTTP_PIPELINE_TIMEOUT, | |
> max_pipeline_length = ?HTTP_PIPELINE_LENGTH, | |
> max_keep_alive_length = ?HTTP_KEEP_ALIVE_LENGTH, | |
> keep_alive_timeout = ?HTTP_KEEP_ALIVE_TIMEOUT, % Used when pipeline_timeout = 0 | |
> max_sessions = ?HTTP_MAX_TCP_SESSIONS, | |
> cookies = disabled, % enabled | disabled | verify | |
> verbose = false, % boolean(), | |
> ipfamily = inet, % inet | inet6 | inet6fb4 | |
> ip = default, % specify local interface | |
> port = default, % specify local port | |
> socket_opts = [] % other socket options | |
> } | |
> ). | |
> -type options() :: #options{}. | |
> | |
> %%% All data associated to a specific HTTP request | |
> -record(request, | |
> { | |
> id :: 'undefined' | reference(), % Request Id | |
> from, % pid() - Caller | |
> redircount = 0,% Number of redirects made for this request | |
> scheme, % http | https | |
> address, % ({Host,Port}) Destination Host and Port | |
> path, % string() - Path of parsed URL | |
> pquery, % string() - Rest of parsed URL | |
> method, % atom() - HTTP request Method | |
> headers, % #http_request_h{} | |
> content, % {ContentType, Body} - Current HTTP request | |
> settings :: http_options(), % User defined settings | |
> abs_uri, % string() ex: "http://www.erlang.org" | |
> userinfo, % string() - optinal "<userinfo>@<host>:<port>" | |
> stream, % boolean() - stream async reply? | |
> headers_as_is, % boolean() - workaround for servers that does | |
> % not honor the http standard, can also be used | |
> % for testing purposes. | |
> started, % integer() > 0 - When we started processing the | |
> % request | |
> timer :: undefined | reference(), | |
> socket_opts, % undefined | [socket_option()] | |
> ipv6_host_with_brackets % boolean() | |
> } | |
> ). | |
> -type request() :: #request{}. | |
> | |
> -record(session, | |
> { | |
> %% {{Host, Port}, HandlerPid} | |
> id, | |
> | |
> client_close :: 'undefined' | boolean(), | |
> | |
> %% http (HTTP/TCP) | https (HTTP/SSL/TCP) | |
> scheme, | |
> | |
> %% Open socket, used by connection | |
> socket, | |
> | |
> %% socket-type, used by connection | |
> socket_type, | |
> | |
> %% Current length of pipeline or keep-alive queue | |
> queue_length = 1, | |
> | |
> %% pipeline | keep_alive (wait for response before sending new request) | |
> type :: 'undefined' | 'pipeline' | 'keep_alive', | |
> | |
> %% This will be true, when a response has been received for | |
> %% the first request. See type above. | |
> available = false :: boolean() | |
> }). | |
> -type session() :: #session{}. | |
> | |
> -record(http_cookie, | |
> { | |
> domain, | |
> domain_default = false, | |
> name, | |
> value, | |
> comment, | |
> max_age = session, | |
> path, | |
> path_default = false, | |
> secure = false, | |
> version = "0" | |
> }). | |
> -type http_cookie() :: #http_cookie{}. | |
> | |
> %% -record(parsed_uri, | |
> %% { | |
> %% scheme, % http | https | |
> %% uinfo, % string() | |
> %% host, % string() | |
> %% port, % integer() | |
> %% path, % string() | |
> %% q % query: string() | |
> %% }). | |
> | |
> | |
> -endif. % -ifdef(httpc_internal_hrl). | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/httpc_SUITE_data/cgi_echo.c erlang-otp-6356f67/lib/inets/test/httpc_SUITE_data/cgi_echo.c | |
1c1,97 | |
< ../httpd_SUITE_data/cgi_echo.c | |
\ Наприкінці файла немає нового рядка | |
--- | |
> #include <stdlib.h> | |
> #include <stdio.h> | |
> | |
> #if defined __WIN32__ | |
> #include <windows.h> | |
> #include <fcntl.h> | |
> #endif | |
> | |
> static int read_exact(char *buffer, int len); | |
> static int write_exact(char *buffer, int len); | |
> | |
> int main(void) | |
> { | |
> char msg[100]; | |
> int msg_len; | |
> #ifdef __WIN32__ | |
> _setmode(_fileno( stdin), _O_BINARY); | |
> _setmode(_fileno( stdout), _O_BINARY); | |
> #endif | |
> msg_len = read_exact(msg, 100); | |
> | |
> write_exact("Content-type: text/plain\r\n\r\n", 28); | |
> write_exact(msg, msg_len); | |
> exit(EXIT_SUCCESS); | |
> } | |
> | |
> | |
> /* read from stdin */ | |
> #ifdef __WIN32__ | |
> static int read_exact(char *buffer, int len) | |
> { | |
> HANDLE standard_input = GetStdHandle(STD_INPUT_HANDLE); | |
> | |
> unsigned read_result; | |
> unsigned sofar = 0; | |
> | |
> if (!len) { /* Happens for "empty packages */ | |
> return 0; | |
> } | |
> for (;;) { | |
> if (!ReadFile(standard_input, buffer + sofar, | |
> len - sofar, &read_result, NULL)) { | |
> return -1; /* EOF */ | |
> } | |
> if (!read_result) { | |
> return -2; /* Interrupted while reading? */ | |
> } | |
> sofar += read_result; | |
> if (sofar == len) { | |
> return len; | |
> } | |
> } | |
> } | |
> #else | |
> static int read_exact(char *buffer, int len) { | |
> int i, got = 0; | |
> | |
> do { | |
> if ((i = read(0, buffer + got, len - got)) <= 0) | |
> return(i); | |
> got += i; | |
> } while (got < len); | |
> return len; | |
> | |
> } | |
> #endif | |
> | |
> /* write to stdout */ | |
> #ifdef __WIN32__ | |
> static int write_exact(char *buffer, int len) | |
> { | |
> HANDLE standard_output = GetStdHandle(STD_OUTPUT_HANDLE); | |
> unsigned written; | |
> | |
> if (!WriteFile(standard_output, buffer, len, &written, NULL)) { | |
> return -1; /* Broken Pipe */ | |
> } | |
> if (written < ((unsigned) len)) { | |
> /* This should not happen, standard output is not blocking? */ | |
> return -2; | |
> } | |
> | |
> return (int) written; | |
> } | |
> | |
> #else | |
> static int write_exact(char *buffer, int len) { | |
> int i, wrote = 0; | |
> | |
> do { | |
> if ((i = write(1, buffer + wrote, len - wrote)) <= 0) | |
> return i; | |
> wrote += i; | |
> } while (wrote < len); | |
> return len; | |
> } | |
> #endif | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/httpc_SUITE_data/Makefile.src erlang-otp-6356f67/lib/inets/test/httpc_SUITE_data/Makefile.src | |
1c1,19 | |
< ../httpd_SUITE_data/Makefile.src | |
\ Наприкінці файла немає нового рядка | |
--- | |
> CC = @CC@ | |
> LD = @LD@ | |
> CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@ | |
> CROSSLDFLAGS = @CROSSLDFLAGS@ | |
> | |
> PROGS = cgi_echo@exe@ | |
> | |
> all: $(PROGS) | |
> | |
> cgi_echo@exe@: cgi_echo@obj@ | |
> $(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@ | |
> | |
> @IFEQ@ (@CC@, cl -nologo) | |
> cgi_echo@obj@: cgi_echo.c | |
> $(CC) /c /Focgi_echo@obj@ $(CFLAGS) cgi_echo.c | |
> @ELSE@ | |
> cgi_echo@obj@: cgi_echo.c | |
> $(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c | |
> @ENDIF@ | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/httpd_basic_SUITE_data/printenv.bat erlang-otp-6356f67/lib/inets/test/httpd_basic_SUITE_data/printenv.bat | |
1c1,9 | |
< ../httpd_SUITE_data/server_root/cgi-bin/printenv.bat | |
\ Наприкінці файла немає нового рядка | |
--- | |
> @echo off | |
> echo tomrad > c:\cygwin\tmp\hej | |
> echo Content-type: text/html | |
> echo. | |
> echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^> | |
> set | |
> echo ^</PRE^>^</BODY^>^</HTML^> | |
> | |
> | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/httpd_basic_SUITE_data/printenv.sh erlang-otp-6356f67/lib/inets/test/httpd_basic_SUITE_data/printenv.sh | |
1c1,6 | |
< ../httpd_SUITE_data/server_root/cgi-bin/printenv.sh | |
\ Наприкінці файла немає нового рядка | |
--- | |
> #!/bin/sh | |
> echo "Content-type: text/html" | |
> echo "" | |
> echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>" | |
> env | |
> echo "</PRE></BODY></HTML>" | |
\ Наприкінці файла немає нового рядка | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/http_internal.hrl erlang-otp-6356f67/lib/inets/test/http_internal.hrl | |
1c1,123 | |
< ../src/http_lib/http_internal.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2002-2016. 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. | |
> %% 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(http_internal_hrl). | |
> -define(http_internal_hrl, true). | |
> | |
> -include_lib("inets/src/inets_app/inets_internal.hrl"). | |
> | |
> -define(HTTP_MAX_BODY_SIZE, nolimit). | |
> -define(HTTP_MAX_HEADER_SIZE, 10240). | |
> -define(HTTP_MAX_URI_SIZE, nolimit). | |
> -define(HTTP_MAX_VERSION_STRING, 8). | |
> -define(HTTP_MAX_METHOD_STRING, 20). | |
> -define(HTTP_MAX_CONTENT_LENGTH, 100000000). | |
> | |
> -ifndef(HTTP_DEFAULT_SSL_KIND). | |
> -define(HTTP_DEFAULT_SSL_KIND, essl). | |
> -endif. % -ifdef(HTTP_DEFAULT_SSL_KIND). | |
> | |
> | |
> %%% Response headers | |
> -record(http_response_h,{ | |
> %%% --- Standard "General" headers | |
> 'cache-control', | |
> connection, | |
> date, | |
> pragma, | |
> trailer, | |
> 'transfer-encoding', | |
> upgrade, | |
> via, | |
> warning, | |
> %%% --- Standard "Response" headers | |
> 'accept-ranges', | |
> age, | |
> etag, | |
> location, | |
> 'proxy-authenticate', | |
> 'retry-after', | |
> server, | |
> vary, | |
> 'www-authenticate', | |
> %%% --- Standard "Entity" headers | |
> allow, | |
> 'content-encoding', | |
> 'content-language', | |
> 'content-length' = "-1", | |
> 'content-location', | |
> 'content-md5', | |
> 'content-range', | |
> 'content-type', | |
> expires, | |
> 'last-modified', | |
> other=[] % list() - Key/Value list with other headers | |
> }). | |
> -type http_response_h() :: #http_response_h{}. | |
> | |
> %%% Request headers | |
> -record(http_request_h,{ | |
> %%% --- Standard "General" headers | |
> 'cache-control', | |
> connection = "keep-alive", | |
> date, | |
> pragma, | |
> trailer, | |
> 'transfer-encoding', | |
> upgrade, | |
> via, | |
> warning, | |
> %%% --- Standard "Request" headers | |
> accept, | |
> 'accept-charset', | |
> 'accept-encoding', | |
> 'accept-language', | |
> authorization, | |
> expect, | |
> from, | |
> host, | |
> 'if-match', | |
> 'if-modified-since', | |
> 'if-none-match', | |
> 'if-range', | |
> 'if-unmodified-since', | |
> 'max-forwards', | |
> 'proxy-authorization', | |
> range, | |
> referer, | |
> te, | |
> 'user-agent', | |
> %%% --- Standard "Entity" headers | |
> allow, | |
> 'content-encoding', | |
> 'content-language', | |
> 'content-length' = "0", | |
> 'content-location', | |
> 'content-md5', | |
> 'content-range', | |
> 'content-type', | |
> expires, | |
> 'last-modified', | |
> other=[] % list() - Key/Value list with other headers | |
> }). | |
> -type http_request_h() :: #http_request_h{}. | |
> | |
> -endif. % -ifdef(http_internal_hrl). | |
diff -r otp-OTP-19.3.6.5/lib/inets/test/inets_internal.hrl erlang-otp-6356f67/lib/inets/test/inets_internal.hrl | |
1c1,52 | |
< ../src/inets_app/inets_internal.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2005-2016. 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. | |
> %% 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(inets_internal_hrl). | |
> -define(inets_internal_hrl, true). | |
> | |
> -define(STACK(), erlang:get_stacktrace()). | |
> | |
> %% Various trace macros | |
> | |
> -define(report(Severity, Label, Service, Content), | |
> inets_trace:report_event(Severity, Label, Service, | |
> [{module, ?MODULE}, {line, ?LINE} | Content])). | |
> -define(report_important(Label, Service, Content), | |
> ?report(20, Label, Service, Content)). | |
> -define(report_verbose(Label, Service, Content), | |
> ?report(40, Label, Service, Content)). | |
> -define(report_debug(Label, Service, Content), | |
> ?report(60, Label, Service, Content)). | |
> -define(report_trace(Label, Service, Content), | |
> ?report(80, Label, Service, Content)). | |
> | |
> | |
> -define(CR, $\r). | |
> -define(LF, $\n). | |
> -define(CRLF, [$\r,$\n]). | |
> -define(SP, $\s). | |
> -define(TAB, $\t). | |
> -define(LEFT_PAREN, $(). | |
> -define(RIGHT_PAREN, $)). | |
> -define(WHITE_SPACE, $ ). | |
> -define(DOUBLE_QUOTE, $"). | |
> | |
> -endif. % -ifdef(inets_internal_hrl). | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/bup.erl erlang-otp-6356f67/lib/mnesia/examples/bup.erl | |
1c1,240 | |
< ../doc/src/bup.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% ``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. | |
> %% | |
> %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. | |
> %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings | |
> %% AB. All Rights Reserved.'' | |
> %% | |
> %% $Id$ | |
> %% | |
> -module(bup). | |
> -export([ | |
> change_node_name/5, | |
> view/2, | |
> test/0, | |
> test/1 | |
> ]). | |
> | |
> -export([ | |
> count/1, | |
> display/1 | |
> ]). | |
> | |
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
> %% Management of backups, a few demos | |
> | |
> %0 | |
> change_node_name(Mod, From, To, Source, Target) -> | |
> Switch = | |
> fun(Node) when Node == From -> To; | |
> (Node) when Node == To -> throw({error, already_exists}); | |
> (Node) -> Node | |
> end, | |
> Convert = | |
> fun({schema, db_nodes, Nodes}, Acc) -> | |
> {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc}; | |
> ({schema, version, Version}, Acc) -> | |
> {[{schema, version, Version}], Acc}; | |
> ({schema, cookie, Cookie}, Acc) -> | |
> {[{schema, cookie, Cookie}], Acc}; | |
> ({schema, Tab, CreateList}, Acc) -> | |
> Keys = [ram_copies, disc_copies, disc_only_copies], | |
> OptSwitch = | |
> fun({Key, Val}) -> | |
> case lists:member(Key, Keys) of | |
> true -> {Key, lists:map(Switch, Val)}; | |
> false-> {Key, Val} | |
> end | |
> end, | |
> {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc}; | |
> (Other, Acc) -> | |
> {[Other], Acc} | |
> end, | |
> mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched). | |
> | |
> view(Source, Mod) -> | |
> View = fun(Item, Acc) -> | |
> io:format("~p.~n",[Item]), | |
> {[Item], Acc + 1} | |
> end, | |
> mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0). | |
> %0 | |
> | |
> -record(bup_rec, {key, val}). | |
> | |
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
> %% Test change of node name | |
> %% | |
> %% Assume db_nodes to be current node and on all other nodes but one | |
> %% Create new schema, start Mnesia on all db_nodes | |
> %% Create a table of disc_copies type which is replicated to all db_nodes | |
> %% Perform a backup and change current node to unused node in backup | |
> %% Start Mnesia on all nodes according to the new set of db_nodes | |
> test() -> | |
> test(nodes()). | |
> | |
> test(Nodes)-> | |
> AllNodes = (Nodes -- [node()]) ++ [node()], | |
> case length(AllNodes) of | |
> Length when Length > 1 -> | |
> OldBup = "old.BUP", | |
> NewBup = "new.BUP", | |
> Res = (catch test2(AllNodes, OldBup, NewBup)), | |
> case Res of | |
> {'EXIT', Reason} -> | |
> file:delete(OldBup), | |
> file:delete(NewBup), | |
> {error, Reason}; | |
> ok -> | |
> ok = count(NewBup), | |
> file:delete(OldBup), | |
> file:delete(NewBup), | |
> ok | |
> end; | |
> _ -> | |
> {error,{"Must run on at least one other node",AllNodes}} | |
> end. | |
> | |
> test2(AllNodes, OldBup, NewBup) -> | |
> ThisNode = node(), | |
> OtherNode = hd(AllNodes -- [ThisNode]), | |
> OldNodes = AllNodes -- [OtherNode], | |
> NewNodes = AllNodes -- [ThisNode], | |
> Mod = mnesia_backup, % Assume local files | |
> file:delete(OldBup), | |
> file:delete(NewBup), | |
> | |
> %% Create old backup | |
> rpc:multicall(AllNodes, mnesia, lkill, []), | |
> ok = mnesia:delete_schema(AllNodes), | |
> ok = mnesia:create_schema(OldNodes), | |
> rpc:multicall(OldNodes, mnesia, start, []), | |
> rpc:multicall(OldNodes, mnesia, wait_for_tables, [[schema], infinity]), | |
> | |
> CreateList = [{disc_copies, OldNodes}, | |
> {attributes, record_info(fields, bup_rec)}], | |
> {atomic, ok} = mnesia:create_table(bup_rec, CreateList), | |
> rpc:multicall(OldNodes, mnesia, wait_for_tables, [[bup_rec], infinity]), | |
> OldRecs = [#bup_rec{key = I, val = I * I} || I <- lists:seq(1, 10)], | |
> lists:foreach(fun(R) -> ok = mnesia:dirty_write(R) end,OldRecs), | |
> ok = mnesia:backup(OldBup, Mod), | |
> ok = mnesia:dirty_write(#bup_rec{key = 4711, val = 4711}), | |
> rpc:multicall(OldNodes, mnesia, stop, []), | |
> {ok,_} = view(OldBup, Mod), | |
> | |
> %% Change node name | |
> {ok,_} = change_node_name(Mod, ThisNode, OtherNode, OldBup, NewBup), | |
> ok = rpc:call(OtherNode, mnesia, install_fallback, [NewBup, Mod]), | |
> {_NewStartRes,[]} = rpc:multicall(NewNodes, mnesia, start, []), | |
> rpc:call(OtherNode, mnesia, wait_for_tables, [[bup_rec], infinity]), | |
> Wild = rpc:call(OtherNode, mnesia, table_info, [bup_rec, wild_pattern]), | |
> NewRecs = rpc:call(OtherNode, mnesia, dirty_match_object, [Wild]), | |
> rpc:multicall(NewNodes, mnesia, stop, []), | |
> {ok,_} = view(NewBup, Mod), | |
> | |
> %% Sanity test | |
> case {lists:sort(OldRecs), lists:sort(NewRecs)} of | |
> {Same, Same} -> ok | |
> end. | |
> | |
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
> | |
> -record(state, {counter_tab, size_tab, acc_size = 0, n_records = 0}). | |
> | |
> | |
> %% Iterates over a backup file and shows some statistics | |
> %% The identity of ets table containing the counters is not removed | |
> count(BupFile) -> | |
> CounterTab = ets:new(?MODULE, [set, public]), | |
> SizeTab = ets:new(?MODULE, [set, public]), | |
> Mod = mnesia:system_info(backup_module), | |
> State = #state{counter_tab = CounterTab, size_tab = SizeTab}, | |
> case mnesia:traverse_backup(BupFile, Mod, dummy, read_only, fun incr/2, State) of | |
> {ok, State2} -> | |
> Res = display(State2), | |
> ets:delete(CounterTab), | |
> ets:delete(SizeTab), | |
> Res; | |
> {error, Reason} -> | |
> ets:delete(CounterTab), | |
> ets:delete(SizeTab), | |
> {error, Reason} | |
> end. | |
> | |
> incr(Rec, State) -> | |
> Tab = element(1, Rec), | |
> Key = element(2, Rec), | |
> Oid = {Tab, Key}, | |
> incr_counter(State#state.counter_tab, Oid), | |
> Size = size(term_to_binary(Rec)), | |
> max_size(State#state.size_tab, Tab, Key, Size), | |
> AccSize = State#state.acc_size, | |
> N = State#state.n_records, | |
> State2 = State#state{acc_size = AccSize + Size, n_records = N + 1}, | |
> {[Rec], State2}. | |
> | |
> incr_counter(T, Counter) -> | |
> case catch ets:update_counter(T, Counter, 1) of | |
> {'EXIT', _} -> | |
> ets:insert(T, {Counter, 1}); | |
> _ -> | |
> ignore | |
> end. | |
> | |
> max_size(T, Tab, Key, Size) -> | |
> case catch ets:lookup_element(T, Tab, 2) of | |
> {'EXIT', _} -> | |
> ets:insert(T, {Tab, Size, Key}); | |
> OldSize when OldSize < Size -> | |
> ets:insert(T, {Tab, Size, Key}); | |
> _ -> | |
> ignore | |
> end. | |
> | |
> %% Displays the statistics found in the ets table | |
> display(State) -> | |
> CounterTab = State#state.counter_tab, | |
> Tabs = [T || {{_, T}, _} <- match_tab(CounterTab, schema)], | |
> io:format("~w tables with totally: ~w records, ~w keys, ~w bytes~n", | |
> [length(Tabs), | |
> State#state.n_records, | |
> ets:info(CounterTab, size), | |
> State#state.acc_size]), | |
> display(State, lists:sort(Tabs)). | |
> | |
> display(State, [Tab | Tabs]) -> | |
> Counters = match_tab(State#state.counter_tab, Tab), | |
> io:format("~-10w records in table ~w~n", [length(Counters), Tab]), | |
> Fun = fun({_Oid, Val}) when Val < 5 -> | |
> ignore; | |
> ({Oid, Val}) -> | |
> io:format("~-10w *** records with key ~w~n", [Val, Oid]) | |
> end, | |
> lists:foreach(Fun, Counters), | |
> display_size(State#state.size_tab, Tab), | |
> display(State, Tabs); | |
> display(_CounterTab, []) -> | |
> ok. | |
> | |
> match_tab(T, Tab) -> | |
> ets:match_object(T, {{Tab, '_'}, '_'}). | |
> | |
> display_size(T, Tab) -> | |
> case catch ets:lookup(T, Tab) of | |
> [] -> | |
> ignore; | |
> [{_, Size, Key}] when Size > 1000 -> | |
> io:format("~-10w --- bytes occupied by largest record ~w~n", | |
> [Size, {Tab, Key}]); | |
> [{_, _, _}] -> | |
> ignore | |
> end. | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/company.erl erlang-otp-6356f67/lib/mnesia/examples/company.erl | |
1c1,383 | |
< ../doc/src/company.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 1999-2016. 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. | |
> %% 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% | |
> %% | |
> -module(company). | |
> | |
> -compile(export_all). | |
> | |
> %0 | |
> | |
> -include_lib("stdlib/include/qlc.hrl"). | |
> -include("company.hrl"). | |
> | |
> init() -> | |
> mnesia:create_table(employee, | |
> [{attributes, record_info(fields, employee)}]), | |
> mnesia:create_table(dept, | |
> [{attributes, record_info(fields, dept)}]), | |
> mnesia:create_table(project, | |
> [{attributes, record_info(fields, project)}]), | |
> mnesia:create_table(manager, [{type, bag}, | |
> {attributes, record_info(fields, manager)}]), | |
> mnesia:create_table(at_dep, | |
> [{attributes, record_info(fields, at_dep)}]), | |
> mnesia:create_table(in_proj, [{type, bag}, | |
> {attributes, record_info(fields, in_proj)}]). | |
> | |
> %0 | |
> | |
> %1 | |
> | |
> insert_emp(Emp, DeptId, ProjNames) -> | |
> Ename = Emp#employee.name, | |
> Fun = fun() -> | |
> mnesia:write(Emp), | |
> AtDep = #at_dep{emp = Ename, dept_id = DeptId}, | |
> mnesia:write(AtDep), | |
> mk_projs(Ename, ProjNames) | |
> end, | |
> mnesia:transaction(Fun). | |
> | |
> | |
> mk_projs(Ename, [ProjName|Tail]) -> | |
> mnesia:write(#in_proj{emp = Ename, proj_name = ProjName}), | |
> mk_projs(Ename, Tail); | |
> mk_projs(_, []) -> ok. | |
> | |
> | |
> %1 | |
> | |
> %2 | |
> females() -> | |
> F = fun() -> | |
> Q = qlc:q([E#employee.name || E <- mnesia:table(employee), | |
> E#employee.sex == female]), | |
> qlc:e(Q) | |
> end, | |
> mnesia:transaction(F). | |
> %2 | |
> %20 | |
> all_females() -> | |
> F = fun() -> | |
> Female = #employee{sex = female, name = '$1', _ = '_'}, | |
> mnesia:select(employee, [{Female, [], ['$1']}]) | |
> end, | |
> mnesia:transaction(F). | |
> %20 | |
> | |
> g() -> l. | |
> | |
> %3 | |
> female_bosses() -> | |
> H1 = qlc:q( [{Atdep#at_dep.dept_id,E} || | |
> E <- mnesia:table(employee), | |
> E#employee.sex == female, | |
> Atdep <- mnesia:table(at_dep), | |
> Atdep#at_dep.emp == E#employee.emp_no] | |
> ), | |
> | |
> H2 = qlc:q( [{Mgr#manager.emp,E} || | |
> {AtdepDeptId, E} <- H1, | |
> Mgr <- mnesia:table(manager), | |
> AtdepDeptId == Mgr#manager.dept] | |
> ), | |
> | |
> Q = qlc:q( [{E#employee.name, Boss#employee.name} || | |
> {MgrEmp,E} <- H2, | |
> Boss <- mnesia:table(employee), | |
> MgrEmp == Boss#employee.emp_no] | |
> ), | |
> mnesia:transaction(fun() -> qlc:e(Q) end). | |
> %3 | |
> | |
> %4 | |
> raise_females(Amount) -> | |
> F = fun() -> | |
> Q = qlc:q([E || E <- mnesia:table(employee), | |
> E#employee.sex == female]), | |
> Fs = qlc:e(Q), | |
> over_write(Fs, Amount) | |
> end, | |
> mnesia:transaction(F). | |
> | |
> over_write([E|Tail], Amount) -> | |
> Salary = E#employee.salary + Amount, | |
> New = E#employee{salary = Salary}, | |
> mnesia:write(New), | |
> 1 + over_write(Tail, Amount); | |
> over_write([], _) -> | |
> 0. | |
> %4 | |
> | |
> %5 | |
> raise(Eno, Raise) -> | |
> F = fun() -> | |
> [E] = mnesia:read(employee, Eno, write), | |
> Salary = E#employee.salary + Raise, | |
> New = E#employee{salary = Salary}, | |
> mnesia:write(New) | |
> end, | |
> mnesia:transaction(F). | |
> %5 | |
> | |
> | |
> %6 | |
> bad_raise(Eno, Raise) -> | |
> F = fun() -> | |
> [E] = mnesia:read({employee, Eno}), | |
> Salary = E#employee.salary + Raise, | |
> New = E#employee{salary = Salary}, | |
> io:format("Trying to write ... ~n", []), | |
> mnesia:write(New) | |
> end, | |
> mnesia:transaction(F). | |
> %6 | |
> | |
> %9 | |
> get_emps(Salary, Dep) -> | |
> Q = qlc:q( | |
> [E || E <- mnesia:table(employee), | |
> At <- mnesia:table(at_dep), | |
> E#employee.salary > Salary, | |
> E#employee.emp_no == At#at_dep.emp, | |
> At#at_dep.dept_id == Dep] | |
> ), | |
> F = fun() -> qlc:e(Q) end, | |
> mnesia:transaction(F). | |
> %9 | |
> %10 | |
> get_emps2(Salary, Dep) -> | |
> Epat = mnesia:table_info(employee, wild_pattern), | |
> Apat = mnesia:table_info(at_dep, wild_pattern), | |
> F = fun() -> | |
> All = mnesia:match_object(Epat), | |
> High = filter(All, Salary), | |
> Alldeps = mnesia:match_object(Apat), | |
> filter_deps(High, Alldeps, Dep) | |
> end, | |
> mnesia:transaction(F). | |
> | |
> | |
> filter([E|Tail], Salary) -> | |
> if | |
> E#employee.salary > Salary -> | |
> [E | filter(Tail, Salary)]; | |
> true -> | |
> filter(Tail, Salary) | |
> end; | |
> filter([], _) -> | |
> []. | |
> | |
> filter_deps([E|Tail], Deps, Dep) -> | |
> case search_deps(E#employee.name, Deps, Dep) of | |
> true -> | |
> [E | filter_deps(Tail, Deps, Dep)]; | |
> false -> | |
> filter_deps(Tail, Deps, Dep) | |
> end; | |
> filter_deps([], _,_) -> | |
> []. | |
> | |
> | |
> search_deps(Name, [D|Tail], Dep) -> | |
> if | |
> D#at_dep.emp == Name, | |
> D#at_dep.dept_id == Dep -> true; | |
> true -> search_deps(Name, Tail, Dep) | |
> end; | |
> search_deps(_Name, _Tail, _Dep) -> | |
> false. | |
> | |
> %10 | |
> | |
> | |
> | |
> %11 | |
> bench1() -> | |
> Me = #employee{emp_no= 104732, | |
> name = klacke, | |
> salary = 7, | |
> sex = male, | |
> phone = 99586, | |
> room_no = {221, 015}}, | |
> | |
> F = fun() -> insert_emp(Me, 'B/DUR', [erlang, mnesia, otp]) end, | |
> T1 = timer:tc(company, dotimes, [1000, F]), | |
> mnesia:add_table_copy(employee, b@skeppet, ram_copies), | |
> mnesia:add_table_copy(at_dep, b@skeppet, ram_copies), | |
> mnesia:add_table_copy(in_proj, b@skeppet, ram_copies), | |
> T2 = timer:tc(company, dotimes, [1000, F]), | |
> {T1, T2}. | |
> | |
> dotimes(0, _) -> | |
> ok; | |
> dotimes(I, F) -> | |
> F(), dotimes(I-1, F). | |
> | |
> %11 | |
> | |
> | |
> | |
> | |
> | |
> %12 | |
> | |
> dist_init() -> | |
> mnesia:create_table(employee, | |
> [{ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, | |
> employee)}]), | |
> mnesia:create_table(dept, | |
> [{ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, dept)}]), | |
> mnesia:create_table(project, | |
> [{ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, project)}]), | |
> mnesia:create_table(manager, [{type, bag}, | |
> {ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, | |
> manager)}]), | |
> mnesia:create_table(at_dep, | |
> [{ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, at_dep)}]), | |
> mnesia:create_table(in_proj, | |
> [{type, bag}, | |
> {ram_copies, [a@gin, b@skeppet]}, | |
> {attributes, record_info(fields, in_proj)}]). | |
> %12 | |
> | |
> %13 | |
> remove_proj(ProjName) -> | |
> F = fun() -> | |
> Ip = qlc:e(qlc:q([X || X <- mnesia:table(in_proj), | |
> X#in_proj.proj_name == ProjName] | |
> )), | |
> mnesia:delete({project, ProjName}), | |
> del_in_projs(Ip) | |
> end, | |
> mnesia:transaction(F). | |
> | |
> del_in_projs([Ip|Tail]) -> | |
> mnesia:delete_object(Ip), | |
> del_in_projs(Tail); | |
> del_in_projs([]) -> | |
> done. | |
> %13 | |
> | |
> %14 | |
> sync() -> | |
> case mnesia:wait_for_tables(tabs(), 10000) of | |
> {timeout, RemainingTabs} -> | |
> panic(RemainingTabs); | |
> ok -> | |
> synced | |
> end. | |
> | |
> tabs() -> [employee, dept, project, at_dep, in_proj, manager]. | |
> | |
> %14 | |
> | |
> | |
> find_male_on_second_floor() -> | |
> Select = fun() -> | |
> %21 | |
> MatchHead = #employee{name='$1', sex=male, room_no={'$2', '_'}, _='_'}, | |
> Guard = [{'>=', '$2', 220},{'<', '$2', 230}], | |
> Result = '$1', | |
> mnesia:select(employee,[{MatchHead, Guard, [Result]}]) | |
> %21 | |
> end, | |
> mnesia:transaction(Select). | |
> | |
> panic(X) -> exit({panic, X}). | |
> | |
> | |
> fill_tables() -> | |
> Emps = | |
> [ | |
> {employee, 104465, "Johnson Torbjorn", 1, male, 99184, {242,038}}, | |
> {employee, 107912, "Carlsson Tuula", 2, female,94556, {242,056}}, | |
> {employee, 114872, "Dacker Bjarne", 3, male, 99415, {221,035}}, | |
> {employee, 104531, "Nilsson Hans", 3, male, 99495, {222,026}}, | |
> {employee, 104659, "Tornkvist Torbjorn", 2, male, 99514, {222,022}}, | |
> {employee, 104732, "Wikstrom Claes", 2, male, 99586, {221,015}}, | |
> {employee, 117716, "Fedoriw Anna", 1, female,99143, {221,031}}, | |
> {employee, 115018, "Mattsson Hakan", 3, male, 99251, {203,348}} | |
> ], | |
> | |
> Dept = [ | |
> {dept, 'B/SF', "Open Telecom Platform"}, | |
> {dept, 'B/SFP', "OTP - Product Development"}, | |
> {dept, 'B/SFR', "Computer Science Laboratory"} | |
> ], | |
> | |
> Projects = [ | |
> {project, erlang, 1}, | |
> {project, otp, 2}, | |
> {project, beam, 3}, | |
> {project, mnesia, 5}, | |
> {project, wolf, 6}, | |
> {project, documentation, 7}, | |
> {project, www, 8} | |
> ], | |
> | |
> Manager = [ | |
> {manager, 104465, 'B/SF'}, | |
> {manager, 104465, 'B/SFP'}, | |
> {manager, 114872, 'B/SFR'} | |
> ], | |
> | |
> At_dep = [ | |
> {at_dep, 104465, 'B/SF'}, | |
> {at_dep, 107912, 'B/SF'}, | |
> {at_dep, 114872, 'B/SFR'}, | |
> {at_dep, 104531, 'B/SFR'}, | |
> {at_dep, 104659, 'B/SFR'}, | |
> {at_dep, 104732, 'B/SFR'}, | |
> {at_dep, 117716, 'B/SFP'}, | |
> {at_dep, 115018, 'B/SFP'} | |
> ], | |
> | |
> In_proj = [ | |
> {in_proj, 104465, otp}, | |
> {in_proj, 107912, otp}, | |
> {in_proj, 114872, otp}, | |
> {in_proj, 104531, otp}, | |
> {in_proj, 104531, mnesia}, | |
> {in_proj, 104545, wolf}, | |
> {in_proj, 104659, otp}, | |
> {in_proj, 104659, wolf}, | |
> {in_proj, 104732, otp}, | |
> {in_proj, 104732, mnesia}, | |
> {in_proj, 104732, erlang}, | |
> {in_proj, 117716, otp}, | |
> {in_proj, 117716, documentation}, | |
> {in_proj, 115018, otp}, | |
> {in_proj, 115018, mnesia} | |
> ], | |
> | |
> [mnesia:dirty_write(W) || W <- Emps], | |
> [mnesia:dirty_write(W) || W <- Dept], | |
> [mnesia:dirty_write(W) || W <- Projects], | |
> %% Relations | |
> [mnesia:dirty_write(W) || W <- Manager], | |
> [mnesia:dirty_write(W) || W <- At_dep], | |
> [mnesia:dirty_write(W) || W <- In_proj], | |
> | |
> ok. | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/company.hrl erlang-otp-6356f67/lib/mnesia/examples/company.hrl | |
1c1,51 | |
< ../doc/src/company.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% ``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. | |
> %% | |
> %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. | |
> %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings | |
> %% AB. All Rights Reserved.'' | |
> %% | |
> %% $Id$ | |
> %% | |
> | |
> | |
> %0 | |
> -record(employee, {emp_no, | |
> name, | |
> salary, | |
> sex, | |
> phone, | |
> room_no}). | |
> | |
> -record(dept, {id, | |
> name}). | |
> | |
> -record(project, {name, | |
> number}). | |
> | |
> | |
> -record(manager, {emp, | |
> dept}). | |
> | |
> -record(at_dep, {emp, | |
> dept_id}). | |
> | |
> -record(in_proj, {emp, | |
> proj_name}). | |
> | |
> %0 | |
> | |
> | |
> | |
> | |
> | |
> | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/company_o.erl erlang-otp-6356f67/lib/mnesia/examples/company_o.erl | |
1c1,147 | |
< ../doc/src/company_o.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 1999-2016. 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. | |
> %% 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% | |
> %% | |
> | |
> -module(company_o). | |
> -compile(export_all). | |
> | |
> -import(mnesia, [transaction/1]). | |
> | |
> %0 | |
> -include_lib("stdlib/include/qlc.hrl"). | |
> -include("company_o.hrl"). | |
> | |
> | |
> sinit() -> | |
> mnesia:create_schema([node()]). | |
> | |
> init() -> | |
> mnesia:create_table(employee, | |
> [{attributes, record_info(fields, employee)}]), | |
> mnesia:create_table(dept, | |
> [{attributes, record_info(fields, dept)}]), | |
> mnesia:create_table(project, | |
> [{attributes, record_info(fields, project)}]). | |
> | |
> %0 | |
> | |
> | |
> | |
> %1 | |
> | |
> insert_emp(Emp, DeptId, ProjNames) -> | |
> Fun = fun() -> | |
> mnesia:write(Emp#employee{dept = DeptId, | |
> projects = ProjNames}) | |
> end, | |
> mnesia:transaction(Fun). | |
> | |
> | |
> %1 | |
> | |
> %2 | |
> females() -> | |
> F = fun() -> | |
> Q = qlc:q([E#employee.name || E <- mnesia:table(employee), | |
> E#employee.sex == female]), | |
> qlc:e(Q) | |
> end, | |
> mnesia:transaction(F). | |
> %2 | |
> | |
> %3 | |
> female_bosses() -> | |
> F = fun() -> qlc:e(qlc:q( | |
> [{E#employee.name, Boss#employee.name} || | |
> E <- mnesia:table(employee), | |
> Boss <- mnesia:table(employee), | |
> Boss#employee.emp_no == E#employee.manager, | |
> E#employee.sex == female] | |
> )) | |
> end, | |
> mnesia:transaction(F). | |
> | |
> | |
> %4 | |
> raise_females(Amount) -> | |
> F = fun() -> | |
> Q = qlc:q([E || E <- mnesia:table(employee), | |
> E#employee.sex == female]), | |
> Fs = qlc:e(Q), | |
> over_write(Fs, Amount) | |
> end, | |
> mnesia:transaction(F). | |
> | |
> over_write([E|Tail], Amount) -> | |
> Salary = E#employee.salary + Amount, | |
> New = E#employee{salary = Salary}, | |
> mnesia:write(New), | |
> 1 + over_write(Tail, Amount); | |
> over_write([], _) -> | |
> 0. | |
> %4 | |
> | |
> %5 | |
> raise(Eno, Raise) -> | |
> F = fun() -> | |
> [E] = mnesia:read({employee, Eno}), | |
> Salary = E#employee.salary + Raise, | |
> New = E#employee{salary = Salary}, | |
> mnesia:write(New) | |
> end, | |
> mnesia:transaction(F). | |
> %5 | |
> | |
> | |
> %6 | |
> bad_raise(Eno, Raise) -> | |
> F = fun() -> | |
> [E] = mnesia:read({employee, Eno}), | |
> Salary = E#employee.salary + Raise, | |
> New = E#employee{salary = Salary}, | |
> io:format("Trying to write ... ~n", []), | |
> mnesia:write(New) | |
> end, | |
> mnesia:transaction(F). | |
> %6 | |
> | |
> %9 | |
> get_emps(Salary, Dep) -> | |
> Q = qlc:q( | |
> [E || E <- mnesia:table(employee), | |
> E#employee.salary > Salary, | |
> E#employee.dept == Dep] | |
> ), | |
> F = fun() -> qlc:e(Q) end, | |
> transaction(F). | |
> %9 | |
> | |
> %10 | |
> get_emps2(Salary, Dep) -> | |
> Epat0 = mnesia:table_info(employee, wild_pattern), | |
> Epat = Epat0#employee{dept = Dep}, | |
> F = fun() -> | |
> All = mnesia:match_object(Epat), | |
> [E || E <-All, E#employee.salary > Salary ] | |
> end, | |
> mnesia:transaction(F). | |
> | |
> | |
> %10 | |
> | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/company_o.hrl erlang-otp-6356f67/lib/mnesia/examples/company_o.hrl | |
1c1,39 | |
< ../doc/src/company_o.hrl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% ``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. | |
> %% | |
> %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. | |
> %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings | |
> %% AB. All Rights Reserved.'' | |
> %% | |
> %% $Id$ | |
> %% | |
> | |
> %0 | |
> -record(employee, {emp_no, | |
> name, | |
> salary, | |
> sex, | |
> phone, | |
> room_no, | |
> dept, | |
> projects, | |
> manager}). | |
> | |
> | |
> -record(dept, {id, | |
> name}). | |
> | |
> -record(project, {name, | |
> number, | |
> location}). | |
> | |
> %0 | |
diff -r otp-OTP-19.3.6.5/lib/mnesia/examples/DATA erlang-otp-6356f67/lib/mnesia/examples/DATA | |
1c1,100 | |
< ../doc/src/DATA | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %S0 | |
> {tables, | |
> [{employee, [{attributes, [emp_no,name,salary,sex, phone,room_no]}]}, | |
> {dept, [{attributes, [id, name]}]}, | |
> {project, [{attributes, [name, number]}]}, | |
> {manager, [{attributes, [emp, dept]}, | |
> {type, bag}]}, | |
> {at_dep, [{attributes, [emp, dept_id]}]}, | |
> {in_proj, [{attributes, [emp, proj_name]}, | |
> {type, bag}]} | |
> ] | |
> }. | |
> | |
> %E0 | |
> | |
> | |
> %S1 | |
> {employee, 104465, "Johnson Torbjorn", 1, male, 99184, {242,038}}. | |
> {employee, 107912, "Carlsson Tuula", 2, female, 94556, {242,056}}. | |
> {employee, 114872, "Dacker Bjarne", 3, male, 99415, {221,035}}. | |
> {employee, 114849, "Armstrong Josef", 3, male, 99452, {221,023}}. | |
> {employee, 114952, "Froberg Magnus", 5, male, 99469, {222,018}}. | |
> {employee, 104531, "Nilsson Hans", 3, male, 99495, {222,026}}. | |
> {employee, 104659, "Tornkvist Torbjorn", 2, male, 99514, {222,022}}. | |
> {employee, 104732, "Wikstrom Claes", 2, male, 99586, {221,015}}. | |
> {employee, 117716, "Fedoriw Anna", 1, female, 99143, {221,031}}. | |
> {employee, 115020, "Hansson Catrin", 6, female, 99129, {222,072}}. | |
> {employee, 115018, "Mattsson Hakan", 3, male, 99251, {203,348}}. | |
> {employee, 113069, "Eriksson Morgan", 6, male, 99186, {241,543}}. | |
> %E1 | |
> | |
> %S2 | |
> %% departments | |
> {dept, 'B/SF', "Open Telecom Platform"}. | |
> {dept, 'B/SFP', "OTP - Product Development"}. | |
> {dept, 'B/SFR', "Computer Science Laboratory"}. | |
> %E2 | |
> | |
> | |
> %% projects | |
> %S3 | |
> {project, erlang, 1}. | |
> {project, otp, 2}. | |
> {project, beam, 3}. | |
> {project, mnesia, 5}. | |
> {project, wolf, 6}. | |
> {project, documentation, 7}. | |
> {project, www, 8}. | |
> | |
> %E3 | |
> | |
> | |
> | |
> %% manager | |
> %S4 | |
> {manager, 104465, 'B/SF'}. | |
> {manager, 104465, 'B/SFP'}. | |
> {manager, 114872, 'B/SFR'}. | |
> | |
> %E4 | |
> %S5 | |
> {at_dep, 104465, 'B/SF'}. | |
> {at_dep, 107912, 'B/SF'}. | |
> {at_dep, 114872, 'B/SFR'}. | |
> {at_dep, 114849, 'B/SFR'}. | |
> {at_dep, 114952, 'B/SFR'}. | |
> {at_dep, 104531, 'B/SFR'}. | |
> {at_dep, 104659, 'B/SFR'}. | |
> {at_dep, 104732, 'B/SFR'}. | |
> {at_dep, 117716, 'B/SFP'}. | |
> {at_dep, 115020, 'B/SFP'}. | |
> {at_dep, 115018, 'B/SFP'}. | |
> {at_dep, 113069, 'B/SFP'}. | |
> | |
> | |
> %E5 | |
> %S6 | |
> {in_proj, 104465, otp}. | |
> {in_proj, 107912, otp}. | |
> {in_proj, 114872, otp}. | |
> {in_proj, 114849, otp}. | |
> {in_proj, 114849, erlang}. | |
> {in_proj, 114952, otp}. | |
> {in_proj, 104531, otp}. | |
> {in_proj, 104531, mnesia}. | |
> {in_proj, 104545, wolf}. | |
> {in_proj, 104659, otp}. | |
> {in_proj, 104659, wolf}. | |
> {in_proj, 104732, otp}. | |
> {in_proj, 104732, mnesia}. | |
> {in_proj, 104732, erlang}. | |
> {in_proj, 117716, otp}. | |
> {in_proj, 117716, documentation}. | |
> {in_proj, 115020, otp}. | |
> {in_proj, 115018, otp}. | |
> {in_proj, 115018, mnesia}. | |
> {in_proj, 113069, otp}. | |
> | |
> %E6 | |
> | |
diff -r otp-OTP-19.3.6.5/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/src/installer.erl erlang-otp-6356f67/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/src/installer.erl | |
1c1,1124 | |
< ../../../../installer.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2011-2016. 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. | |
> %% 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% | |
> %% | |
> | |
> -module(installer). | |
> | |
> -include("test_lib.hrl"). | |
> | |
> %%-compile(export_all). | |
> -export([install_1/2]). | |
> -export([install_2/1]). | |
> -export([install_3/2]). | |
> -export([install_6a/1]). | |
> -export([install_4/1]). | |
> -export([install_5/1]). | |
> -export([install_5a/1]). | |
> -export([install_6/1]). | |
> -export([install_7/1]). | |
> -export([install_7a/1]). | |
> -export([install_8/1]). | |
> -export([install_8a/1]). | |
> -export([install_9/1]). | |
> -export([install_10/1]). | |
> -export([install_11/1]). | |
> -export([install_12/1]). | |
> -export([install_13/1]). | |
> -export([install_14/1]). | |
> -export([upgrade_restart_1/2]). | |
> -export([upgrade_restart_1a/1]). | |
> -export([upgrade_restart_2/1]). | |
> -export([upgrade_restart_2a/1]). | |
> -export([upgrade_restart_2b/1]). | |
> -export([upgrade_restart_3/1]). | |
> -export([client1_1/4]). | |
> -export([client2/3]). | |
> -export([stop/1]). | |
> -export([unpack_p1h/2]). | |
> -export([permanent_p1h/1]). | |
> -export([reg_proc/1]). | |
> -export([registered_loop/1]). | |
> | |
> -define(print(List), | |
> io:format(user,"(~w:~w) ~tp~n",[?MODULE,?LINE,List]), | |
> {rh_print, TestNode} ! {print, {?MODULE, ?LINE}, List}). | |
> -define(print_line(Line,List), | |
> io:format(user,"(~w:~w) ~tp~n",[?MODULE,Line,List]), | |
> {rh_print, TestNode} ! {print, {?MODULE, Line}, List}). | |
> -define(fail(Term), exit({?MODULE, ?LINE, Term})). | |
> -define(fail_line(Line,Term), exit({?MODULE, Line, Term})). | |
> | |
> -define(check_release_states(States), | |
> check_release_states(TestNode,node(),States,?LINE)). | |
> -define(check_release_states_client(Node,States), | |
> check_release_states(TestNode,Node,States,?LINE)). | |
> | |
> -define(check_release_lib(Vsn,Apps), | |
> check_release_lib(TestNode,node(),Vsn,Apps,?LINE)). | |
> -define(check_release_lib_client(Node,Vsn,Apps), | |
> check_release_lib(TestNode,Node,Vsn,Apps,?LINE)). | |
> | |
> -define(check_running_app(App,Vsn), | |
> check_running_app(TestNode,node(),App,Vsn,?LINE)). | |
> -define(check_running_app_client(Node,App,Vsn), | |
> check_running_app(TestNode,Node,App,Vsn,?LINE)). | |
> | |
> -define(check_disallowed_calls,check_disallowed_calls(TestNode,?LINE)). | |
> | |
> | |
> install_1(TestNode,PrivDir) -> | |
> ?print([TestNode]), | |
> ?print(["install_1 start"]), | |
> ?check_release_states([permanent]), | |
> | |
> % Unpack and install P1H | |
> {ok, "P1H"} = unpack_release(PrivDir,"rel1"), | |
> ?check_release_states([permanent,unpacked]), | |
> ?check_release_lib("P1H",["a-1.0"]), | |
> {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), | |
> ?check_release_states([permanent,current]), | |
> ?check_running_app(a,"1.0"), | |
> X = a:a(), | |
> ?print(["X", X]), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> ?print(["install_1 end OK"]), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> install_2(TestNode) -> | |
> ?print(["install_2 start"]), | |
> | |
> % Check that P1H is still unpacked, install it and make_permanent | |
> ?check_release_states([permanent,unpacked]), | |
> {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), | |
> ?print(["install_2 install_release ok"]), | |
> ?check_release_states([permanent,current]), | |
> ?check_running_app(a,"1.0"), | |
> ok = release_handler:make_permanent("P1H"), | |
> ?print(["install_2 make permanent P1H ok"]), | |
> ?check_release_states([old,permanent]), | |
> ?check_running_app(a,"1.0"), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> install_3(TestNode,PrivDir) -> | |
> ?print(["install_3 start"]), | |
> | |
> % Check that P1H is permanent | |
> ?check_release_states([old,permanent]), | |
> ?check_running_app(a,"1.0"), | |
> X = a:a(), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> | |
> % Unpack and install P1I | |
> {ok, "P1I"} = unpack_release(PrivDir,"rel2"), | |
> ?check_release_states([old,permanent,unpacked]), | |
> ?check_release_lib("P1I",["a-1.1"]), | |
> {ok,"P1H",[{extra, gott}]} = release_handler:check_install_release("P1I"), | |
> ?print(["install_3 check_install_release P1I ok"]), | |
> {error,_} = release_handler:check_install_release("P1J"), | |
> ?print(["install_3 check_install_release P1J fails - ok"]), | |
> {ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"), | |
> ?check_release_states([old,permanent,current]), | |
> ?check_running_app(a,"1.1"), | |
> X2 = a:a(), | |
> {key2, newval2} = lists:keyfind(key2, 1, X2), | |
> {key1, val1} = lists:keyfind(key1, 1, X2), | |
> {ok, bval} = a:b(), | |
> ?print(["install_3 env ok"]), | |
> | |
> % Unpack P2A | |
> {ok, "P2A"} = unpack_release(PrivDir,"rel3"), | |
> ?check_release_states([old,permanent,current,unpacked]), | |
> ?check_release_lib("P2A",["a-1.1"]), | |
> {ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"), | |
> ?print(["install_3 check_install_release P2A ok"]), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> install_4(TestNode) -> | |
> ?print(["install_4 start"]), | |
> | |
> %% Check that P1H is the one that is used | |
> ?check_release_states([old,permanent,unpacked,unpacked]), | |
> ?check_running_app(a,"1.0"), | |
> | |
> %% Install P2A | |
> {continue_after_restart, "P1H", [new_emu,new_appl]} = | |
> release_handler:install_release("P2A"), | |
> %% Node is rebooted by the release_handler:install_release | |
> %% (init:reboot) because P2A includes a new erts vsn and the relup | |
> %% file contains a 'restart_new_emulator' instruction. | |
> ?print(["install_4 P2A installed"]), | |
> ok. | |
> | |
> | |
> install_5(TestNode) -> | |
> ?print(["install_5 start"]), | |
> | |
> %% Check that the upgrade was done via a temporary release due to | |
> %% new emulator version. | |
> {"SASL-test","__new_emulator__P1H"} = init:script_id(), | |
> | |
> %% Check that P2A is in use. | |
> ?check_release_states([old,permanent,unpacked,current]), | |
> ?check_running_app(a,"1.1"), | |
> X = a:a(), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = a:b(), | |
> ?print(["install_5 check env ok"]), | |
> ok. | |
> | |
> install_5a(TestNode) -> | |
> ?print(["install_5a start"]), | |
> | |
> %% Install P1I (this will be a downgrade) | |
> {ok, "P1I", [old_emu]} = release_handler:install_release("P1I"), | |
> %% Node is rebooted by the release_handler:install_release | |
> %% (init:reboot) because P2A includes a new erts vsn and the relup | |
> %% file contains a 'restart_new_emulator' instruction. | |
> ?print(["install_5a P1I installed"]), | |
> ok. | |
> | |
> install_6(TestNode) -> | |
> ?print(["install_6 start"]), | |
> | |
> %% Check that P1I is used | |
> ?check_release_states([old,permanent,current,old]), | |
> ?check_running_app(a,"1.1"), | |
> | |
> %% Make P1I permanent | |
> ok = release_handler:make_permanent("P1I"), | |
> ?check_release_states([old,old,permanent,old]), | |
> ?check_running_app(a,"1.1"), | |
> ok. | |
> | |
> install_6a(TestNode) -> | |
> %% Install P2A | |
> {continue_after_restart, "P1I", [new_emu]} = | |
> release_handler:install_release("P2A"), | |
> %% Node is rebooted by the release_handler:install_release | |
> %% (init:reboot) because P2A includes a new erts vsn and the relup | |
> %% file contains a 'restart_new_emulator' instruction. | |
> ?print(["install_6a P2A installed"]), | |
> ok. | |
> | |
> install_7(TestNode) -> | |
> ?print(["install_7 start"]), | |
> | |
> %% Check that the upgrade was done via a temporary release due to | |
> %% new emulator version. | |
> {"SASL-test","__new_emulator__P1I"} = init:script_id(), | |
> | |
> % Check that P2A is in use. | |
> ?check_release_states([old,old,permanent,current]), | |
> ?check_running_app(a,"1.1"), | |
> X = a:a(), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = a:b(), | |
> ?print(["install_7 check env ok"]), | |
> ok. | |
> | |
> install_7a(TestNode) -> | |
> %% Install P1H (this will be a downgrade) | |
> {ok, "P1H", [old_emu,old_appl]} = release_handler:install_release("P1H"), | |
> %% Node is rebooted by the release_handler:install_release | |
> %% (init:reboot) because P2A includes a new erts vsn and the relup | |
> %% file contains a 'restart_new_emulator' instruction. | |
> ?print(["install_7a P1H installed"]), | |
> ok. | |
> | |
> install_8(TestNode) -> | |
> ?print(["install_8 start"]), | |
> | |
> %% Check that P1H is used | |
> ?check_release_states([old,current,permanent,old]), | |
> ?check_running_app(a,"1.0"), | |
> {ok,"P1H",[new_emu,new_appl]} = release_handler:check_install_release("P2A"), | |
> ?print(["install_8 check_install_release P2A ok"]), | |
> | |
> %% Install P1I and check that it is permanent | |
> {ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"), | |
> ?check_release_states([old,old,permanent,old]), | |
> ?check_running_app(a,"1.1"), | |
> ok. | |
> | |
> install_8a(TestNode) -> | |
> % Install P2A again | |
> {continue_after_restart, "P1I", [new_emu]} = | |
> release_handler:install_release("P2A"), | |
> %% Node is rebooted by the release_handler:install_release | |
> %% (init:reboot) because P2A includes a new erts vsn and the relup | |
> %% file contains a 'restart_new_emulator' instruction. | |
> ?print(["install_8a P2A installed"]), | |
> ok. | |
> | |
> install_9(TestNode) -> | |
> ?print(["install_9 start"]), | |
> | |
> %% Check that the upgrade was done via a temporary release due to | |
> %% new emulator version. | |
> {"SASL-test","__new_emulator__P1I"} = init:script_id(), | |
> | |
> % Check that P2A is used | |
> ?check_release_states([old,old,permanent,current]), | |
> ?check_running_app(a,"1.1"), | |
> X = a:a(), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = a:b(), | |
> ?print(["install_9 check env ok"]), | |
> ok = release_handler:make_permanent("P2A"), | |
> ?check_release_states([old,old,old,permanent]), | |
> ?check_running_app(a,"1.1"), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> | |
> install_10(TestNode) -> | |
> ?print(["install_10 start"]), | |
> | |
> % Check that P2A is used | |
> ?check_release_states([old,old,old,permanent]), | |
> ?check_running_app(a,"1.1"), | |
> | |
> % Install old P1H | |
> ok = release_handler:reboot_old_release("P1H"), | |
> ?print(["install_10 reboot_old ok"]), | |
> ok. | |
> | |
> | |
> install_11(TestNode) -> | |
> ?print(["install_11 start"]), | |
> | |
> % Check that P1H is permanent | |
> ?check_release_states([old,permanent,old,old]), | |
> ?check_running_app(a,"1.0"), | |
> X = a:a(), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> ?print(["install_11 check env ok"]), | |
> | |
> %% Remove P1I and P2A and check that a-1.1 and erts-<latest> are removed | |
> ok = release_handler:remove_release("P2A"), | |
> ?check_release_states([old,permanent,old]), | |
> ok = release_handler:remove_release("P1I"), | |
> ?check_release_states([old,permanent]), | |
> {ok, Libs} = file:list_dir(code:lib_dir()), | |
> {_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()), | |
> true = lists:member("stdlib-"++StdlibVsn, Libs), | |
> true = lists:member("a-1.0", Libs), | |
> false = lists:member("a-1.1", Libs), | |
> {ok, Dirs} = file:list_dir(code:root_dir()), | |
> ErtsDir = "erts-"++?ertsvsn, | |
> [ErtsDir] = lists:filter(fun(Dir) -> lists:prefix("erts-",Dir) end, Dirs), | |
> ?print(["install_11 file checks ok"]), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> install_12(TestNode) -> | |
> ?print(["install_12 start"]), | |
> | |
> % Check that P1H is permanent | |
> ?check_release_states([old,permanent]), | |
> ?check_running_app(a,"1.0"), | |
> X = a:a(), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> ?print(["install_12 check env ok"]), | |
> | |
> % Install old P1G | |
> ok = release_handler:reboot_old_release("P1G"), | |
> ?print(["install_12 reboot_old ok"]), | |
> ok. | |
> | |
> install_13(TestNode) -> | |
> ?print(["install_13 start"]), | |
> | |
> % Check that P1G is permanent | |
> ?check_release_states([permanent,old]), | |
> false = lists:keysearch(a,1,application:loaded_applications()), | |
> ?print(["install_13 no a application found - ok"]), | |
> | |
> %% Remove P1H and check that both versions of application a is removed | |
> ok = release_handler:remove_release("P1H"), | |
> ?check_release_states([permanent]), | |
> {ok, Libs} = file:list_dir(code:lib_dir()), | |
> {_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()), | |
> true = lists:member("stdlib-"++StdlibVsn, Libs), | |
> false = lists:member("a-1.0", Libs), | |
> false = lists:member("a-1.1", Libs), | |
> ?print(["install_13 file checks ok"]), | |
> ok. | |
> % release_handler_SUITE will reboot this node now! | |
> | |
> install_14(TestNode) -> | |
> ?print(["install_14 start"]), | |
> | |
> % Check that P1G is permanent | |
> ?check_release_states([permanent]), | |
> false = lists:keysearch(a,1,application:loaded_applications()), | |
> ?print(["install_13 no a application found - ok"]), | |
> ok. | |
> | |
> | |
> %%%----------------------------------------------------------------- | |
> %%% Ths test checks that an upgrade which both upgrades to a new | |
> %%% emulator version, and had a restart_emulator option to | |
> %%% systools:make_relup will be restarted twice on upgrade. | |
> %%% (On downgrade it will happen only once.) | |
> upgrade_restart_1(TestNode,PrivDir) -> | |
> ?print([TestNode]), | |
> ?print(["upgrade_restart_1 start"]), | |
> ?check_release_states([permanent]), | |
> | |
> {ok, "P2B"} = unpack_release(PrivDir,"rel4"), | |
> ?check_release_states([permanent,unpacked]), | |
> ?check_release_lib("P2B",["a-1.1"]), | |
> ok. | |
> | |
> upgrade_restart_1a(TestNode) -> | |
> ?print(["upgrade_restart_1a start"]), | |
> | |
> {continue_after_restart,"P1G",[new_emu,add_appl]} = | |
> release_handler:install_release("P2B"), | |
> ?print(["upgrade_restart_1a P2B installed"]), | |
> ok. | |
> | |
> upgrade_restart_2(TestNode) -> | |
> ?print(["upgrade_restart_2 start"]), | |
> | |
> %% Check that the node has been restarted once more after the tmp release | |
> case init:script_id() of | |
> {"SASL-test","P2B"} -> | |
> upgrade_restart_2a(TestNode); | |
> {"SASL-test","__new_emulator__P1G"} -> | |
> %% catched the node too early - give it another try | |
> {wait,whereis(init)} | |
> end. | |
> | |
> upgrade_restart_2a(TestNode) -> | |
> ?print(["upgrade_restart_2a start"]), | |
> | |
> %% This time we must be there, else something is definitely wrong | |
> {"SASL-test","P2B"} = init:script_id(), | |
> | |
> ?check_release_states([permanent,current]), | |
> ?check_running_app(a,"1.1"), | |
> | |
> ok = release_handler:make_permanent("P2B"), | |
> ?check_release_states([old,permanent]), | |
> | |
> ok. | |
> | |
> upgrade_restart_2b(TestNode) -> | |
> ?print(["upgrade_restart_2b start"]), | |
> | |
> {ok,"P1G",[old_emu,rm_appl]} = release_handler:install_release("P1G"), | |
> ?print(["upgrade_restart_2b P1G installed"]), | |
> ok. | |
> | |
> upgrade_restart_3(TestNode) -> | |
> ?print(["upgrade_restart_3 start"]), | |
> | |
> %% Ideally we should test that the node has only been restarted | |
> %% once... but that's not so easy. Let's just check that P1G is running. | |
> ?check_release_states([current,permanent]), | |
> false = lists:keysearch(a,1,application:loaded_applications()), | |
> ?print(["upgrade_restart_3 no a application found - ok"]), | |
> | |
> ok. | |
> | |
> | |
> | |
> | |
> %%----------------------------------------------------------------- | |
> %% This test starts a client node which uses this node as master | |
> %% for the release_handler. | |
> %% The client node runs all tests as in installer/1 test case. | |
> %% Thus, the client node will be rebooted several times. | |
> %% The to_erl /tmp/NODENAME@HOSTNAME/ command can be used to connect | |
> %% to the client node. | |
> %% run_erl logs for the client can be found in the directory: | |
> %% code:root_dir() ++ "/clients/type1/NODENAME@HOSTNAME/log | |
> %%----------------------------------------------------------------- | |
> | |
> | |
> client1_1(TestNode,PrivDir,MasterDir,ClientSname) -> | |
> TestHost = test_host(), | |
> ?print(["client1_1 start"]), | |
> | |
> {ok,IP} = inet:getaddr(TestHost,inet), | |
> erl_boot_server:start([IP]), | |
> | |
> ok = net_kernel:monitor_nodes(true), | |
> Node = start_client(TestNode,client1,ClientSname), | |
> trace_disallowed_calls(Node), | |
> | |
> ?check_release_states_client(Node,[permanent]), | |
> | |
> %% Check env var for SASL on client node | |
> SaslEnv = rpc:call(Node, application, get_all_env, [sasl]), | |
> ?print([{client1_1,sasl_env},SaslEnv]), | |
> {_,CliDir} = lists:keyfind(client_directory,1,SaslEnv), | |
> {_,[Master]} = lists:keyfind(masters,1,SaslEnv), | |
> {_,StartCli} = lists:keyfind(start_prg,1,SaslEnv), | |
> NodeStr = atom_to_list(Node), | |
> [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)), | |
> true = (Master =:= node()), | |
> case os:type() of | |
> {unix,_} -> | |
> true = (StartCli =:= filename:join([CliDir,"bin","start"])); | |
> _ -> | |
> ok | |
> end, | |
> | |
> %% Unpack P1H on master | |
> {ok, "P1H"} = unpack_release(PrivDir,"rel1"), | |
> | |
> %% Unpack and install P1H on client | |
> Root = code:root_dir(), | |
> P1HDir = filename:join([Root, "releases", "P1H"]), | |
> | |
> %% The AppDirs argument (last arg to set_unpacked) below is really | |
> %% not necessary, it could just be [] since the path is the same | |
> %% as default. But it is given here in order to force hitting the | |
> %% release_handler:check_path function so it can be checked that | |
> %% it does not use file:read_file_info on the client node, see | |
> %% trace_disallowed_calls/1 and check_disallowed_calls/2 below. | |
> %% (OTP-9142) | |
> {ok, "P1H"} = rpc:call(Node, release_handler, set_unpacked, | |
> [filename:join(P1HDir, "rel1.rel"), | |
> [{a,"1.0",filename:join(MasterDir,lib)}]]), | |
> | |
> ?check_release_states_client(Node,[permanent,unpacked]), | |
> ?check_release_lib_client(Node,"P1H",["a-1.0"]), | |
> | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1H", filename:join(P1HDir, "start.boot")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1H", filename:join(P1HDir, "sys.config")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1H", filename:join(P1HDir, "relup")]), | |
> ?print([{release_handler_state, Node}, | |
> rpc:call(Node, sys, get_status, [release_handler])]), | |
> | |
> {ok,"P1G",[new_appl]} = | |
> rpc:call(Node, release_handler, check_install_release, ["P1H"]), | |
> | |
> {ok,"P1G",[new_appl]} = | |
> rpc:call(Node, release_handler, install_release, ["P1H"]), | |
> | |
> ?check_release_states_client(Node,[permanent,current]), | |
> ?check_running_app_client(Node,a,"1.0"), | |
> | |
> Apps = rpc:call(Node, application, which_applications, []), | |
> {a,"A CXC 138 11","1.0"} = lists:keyfind(a, 1, Apps), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_2(TestNode,PrivDir,Node). | |
> | |
> client1_2(TestNode,PrivDir,Node) -> | |
> ?print(["client1_2 start"]), | |
> | |
> %% Check that P1H is still unpacked, install it and make_permanent | |
> ?check_release_states_client(Node,[permanent,unpacked]), | |
> | |
> {ok,"P1G",[new_appl]} = | |
> rpc:call(Node, release_handler, install_release, ["P1H"]), | |
> ?check_release_states_client(Node,[permanent,current]), | |
> ?check_running_app_client(Node,a,"1.0"), | |
> | |
> ok = rpc:call(Node, release_handler, make_permanent, ["P1H"]), | |
> ?check_release_states_client(Node,[old,permanent]), | |
> | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_3(TestNode,PrivDir,Node). | |
> | |
> client1_3(TestNode,PrivDir,Node) -> | |
> ?print(["client1_3 start"]), | |
> | |
> %% Check that P1H is permanent | |
> ?check_release_states_client(Node,[old,permanent]), | |
> ?check_running_app_client(Node,a,"1.0"), | |
> | |
> %% Unpack P1I on master | |
> {ok, "P1I"} = unpack_release(PrivDir,"rel2"), | |
> | |
> MasterRoot = code:root_dir(), | |
> | |
> %% Unpack and install P1I on client | |
> P1IDir = filename:join([MasterRoot, "releases", "P1I"]), | |
> {ok, "P1I"} = rpc:call(Node, release_handler, set_unpacked, | |
> [filename:join(P1IDir, "rel2.rel"),[]]), | |
> | |
> ?check_release_states_client(Node,[old,permanent,unpacked]), | |
> ?check_release_lib_client(Node,"P1I",["a-1.1"]), | |
> | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1I", filename:join(P1IDir, "start.boot")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1I", filename:join(P1IDir, "sys.config")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P1I", filename:join(P1IDir, "relup")]), | |
> | |
> {ok,"P1H",[{extra, gott}]} = | |
> rpc:call(Node, release_handler, check_install_release, ["P1I"]), | |
> {error,_} = rpc:call(Node, release_handler, check_install_release, ["P1J"]), | |
> {ok,"P1H",[{extra, gott}]} = | |
> rpc:call(Node, release_handler, install_release, ["P1I"]), | |
> | |
> ?check_release_states_client(Node,[old,permanent,current]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> X2 = rpc:call(Node, a, a, []), | |
> {key2, newval2} = lists:keyfind(key2, 1, X2), | |
> {key1, val1} = lists:keyfind(key1, 1, X2), | |
> {ok, bval} = rpc:call(Node, a, b, []), | |
> | |
> %% Unpack P2A on master | |
> {ok, "P2A"} = unpack_release(PrivDir,"rel3"), | |
> | |
> %% Unpack and install P2A on client | |
> P2ADir = filename:join([MasterRoot, "releases", "P2A"]), | |
> {ok, "P2A"} = | |
> rpc:call(Node, release_handler, set_unpacked, | |
> [filename:join(P2ADir, "rel3.rel"),[]]), | |
> | |
> ?check_release_states_client(Node,[old,permanent,current,unpacked]), | |
> ?check_release_lib_client(Node,"P2A",["a-1.1"]), | |
> | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P2A", filename:join(P2ADir, "start.boot")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P2A", filename:join(P2ADir, "sys.config")]), | |
> ok = rpc:call(Node, release_handler, install_file, | |
> ["P2A", filename:join(P2ADir, "relup")]), | |
> | |
> {ok, "P1I", [new_emu]} = | |
> rpc:call(Node, release_handler, check_install_release, ["P2A"]), | |
> | |
> %% Reboot from P1H | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_4(TestNode,Node). | |
> | |
> client1_4(TestNode,Node) -> | |
> ?print(["client1_4 start"]), | |
> | |
> %% check that P1H is used | |
> ?check_release_states_client(Node,[old,permanent,unpacked,unpacked]), | |
> | |
> %% since the install_release below reboot the node... | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> {continue_after_restart, "P1H", [new_emu,new_appl]} = | |
> rpc:call(Node, release_handler, install_release, ["P2A"]), | |
> %% Reboots the client ! | |
> | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_5(TestNode,Node). | |
> | |
> client1_5(TestNode,Node) -> | |
> ?print(["client1_5 start"]), | |
> | |
> %% Check that P2A is in use. | |
> ?check_release_states_client(Node,[old,permanent,unpacked,current]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = rpc:call(Node, a, b, []), | |
> | |
> %% since the install_release below reboot the node... | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> {ok,"P1I",[old_emu]} = | |
> rpc:call(Node, release_handler, install_release, ["P1I"]), | |
> | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_6(TestNode,Node). | |
> | |
> client1_6(TestNode,Node) -> | |
> ?print(["client1_6 start"]), | |
> | |
> ?check_release_states_client(Node,[old,permanent,current,old]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> | |
> ok = rpc:call(Node, release_handler, make_permanent, ["P1I"]), | |
> ?check_release_states_client(Node,[old,old,permanent,old]), | |
> | |
> %% since the install_release below reboot the node... | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> {continue_after_restart, "P1I", [new_emu]} = | |
> rpc:call(Node, release_handler, install_release, ["P2A"]), | |
> %% Reboots the client ! | |
> | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_7(TestNode,Node). | |
> | |
> client1_7(TestNode,Node) -> | |
> ?print(["client1_7 start"]), | |
> | |
> %% Check that P2A is in use. | |
> ?check_release_states_client(Node,[old,old,permanent,current]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = rpc:call(Node, a, b, []), | |
> | |
> %% since the install_release below reboot the node... | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> {ok,"P1H",[old_emu,old_appl]} = | |
> rpc:call(Node, release_handler, install_release, ["P1H"]), | |
> | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_8(TestNode,Node). | |
> | |
> client1_8(TestNode,Node) -> | |
> ?print(["client1_8 start"]), | |
> | |
> %% Check that P1H is used | |
> ?check_release_states_client(Node,[old,current,permanent,old]), | |
> ?check_running_app_client(Node,a,"1.0"), | |
> {ok, "P1H", [new_emu,new_appl]} = | |
> rpc:call(Node, release_handler, check_install_release, ["P2A"]), | |
> | |
> | |
> {ok,"P1H",[{extra, gott}]} = | |
> rpc:call(Node, release_handler, install_release, ["P1I"]), | |
> ?check_release_states_client(Node,[old,old,permanent,old]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> | |
> | |
> %% since the install_release below will reboot the node... | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> %% Install P2A again | |
> {continue_after_restart, "P1I", [new_emu]} = | |
> rpc:call(Node, release_handler, install_release, ["P2A"]), | |
> | |
> %% We are rebooted again. | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_9(TestNode,Node). | |
> | |
> client1_9(TestNode,Node) -> | |
> ?print(["client1_9 start"]), | |
> | |
> %% Check that P2A is used | |
> ?check_release_states_client(Node,[old,old,permanent,current]), | |
> ?check_running_app_client(Node,a,"1.1"), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, newval2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> {ok, bval} = rpc:call(Node, a, b, []), | |
> | |
> %% Make P2A permanent | |
> ok = rpc:call(Node, release_handler, make_permanent, ["P2A"]), | |
> ?check_release_states_client(Node,[old,old,old,permanent]), | |
> | |
> %% Reboot from P2A | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_10(TestNode,Node). | |
> | |
> client1_10(TestNode,Node) -> | |
> ?print(["client1_10 start"]), | |
> | |
> %% Check that P2A is used | |
> ?check_release_states_client(Node,[old,old,old,permanent]), | |
> | |
> %% since the reboot_old_release below will reboot the node | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> %% Install old P1H | |
> rpc:call(Node, release_handler, reboot_old_release, ["P1H"]), | |
> %% We are rebooted. | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_11(TestNode,Node). | |
> | |
> client1_11(TestNode,Node) -> | |
> ?print(["client1_11 start"]), | |
> | |
> %% Check that P1H is permanent | |
> ?check_release_states_client(Node,[old,permanent,old,old]), | |
> ?check_running_app_client(Node,a,"1.0"), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> | |
> %% Remove P1I and P2A from client | |
> ok = rpc:call(Node, release_handler, set_removed, ["P2A"]), | |
> ?check_release_states_client(Node,[old,permanent,old]), | |
> ok = rpc:call(Node, release_handler, set_removed, ["P1I"]), | |
> ?check_release_states_client(Node,[old,permanent]), | |
> | |
> %% Check that P2A and P1I does not exists | |
> Rels = rpc:call(Node, release_handler, which_releases, []), | |
> false = lists:keysearch("P2A", 2, Rels), | |
> false = lists:keysearch("P1I", 2, Rels), | |
> X = rpc:call(Node, a, a, []), | |
> {key2, val2} = lists:keyfind(key2, 1, X), | |
> {key1, val1} = lists:keyfind(key1, 1, X), | |
> | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_12(TestNode,Node). | |
> | |
> client1_12(TestNode,Node) -> | |
> ?print(["client1_12 start"]), | |
> | |
> ?check_release_states_client(Node,[old,permanent]), | |
> | |
> %% since the reboot_old_release below will reboot the node | |
> ?check_disallowed_calls, | |
> cover_client(TestNode,Node,stop_cover), | |
> | |
> %% Install old P1G | |
> rpc:call(Node, release_handler, reboot_old_release, ["P1G"]), | |
> %% We are rebooted. | |
> check_reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_13(TestNode,Node). | |
> | |
> client1_13(TestNode,Node) -> | |
> ?print(["client1_13 start"]), | |
> | |
> %% Check that P1G is permanent | |
> ?check_release_states_client(Node,[permanent,old]), | |
> {error,client_node} = rpc:call(Node,release_handler,remove_release,["P1H"]), | |
> ok = rpc:call(Node, release_handler, set_removed, ["P1H"]), | |
> ?check_release_states_client(Node,[permanent]), | |
> | |
> ?check_disallowed_calls, | |
> reboot(TestNode,Node), | |
> trace_disallowed_calls(Node), | |
> | |
> client1_14(TestNode,Node). | |
> | |
> client1_14(TestNode,Node) -> | |
> ?print(["client1_14 start"]), | |
> | |
> %% Check that P1G is permanent | |
> ?check_release_states_client(Node,[permanent]), | |
> | |
> ?check_disallowed_calls, | |
> stop_client(TestNode,Node), %% TEST IS OK !! | |
> net_kernel:monitor_nodes(false), | |
> | |
> %% Remove releases from master | |
> ok = release_handler:remove_release("P2A"), | |
> ok = release_handler:remove_release("P1I"), | |
> ok = release_handler:remove_release("P1H"), | |
> ok. | |
> | |
> %% Start tracing of the file module on the client node. This module | |
> %% shall never be called, since | |
> %% 1) the node is a client from the release_handler's point of view, | |
> %% so all file access should be done via rpc calls to the master | |
> %% 2) it is started with erl_prim_loader loader set to 'inet' so all | |
> %% code loading should be done via the inet to the master | |
> %% (OTP-9142) | |
> %% This function is called each time the client node is started and to | |
> %% check if a call has been made, call check_disallowed_node/0 | |
> trace_disallowed_calls(Node) -> | |
> MasterProc = self(), | |
> rpc:call(Node,dbg,tracer,[process,{fun(T,_) -> MasterProc ! T end,[]}]), | |
> rpc:call(Node,dbg,p,[all,call]), | |
> rpc:call(Node,dbg,tp,[file,[{'_',[],[{message,{caller}}]}]]), | |
> %% File:native_name_encoding/0 is a BIF and OK to use | |
> rpc:call(Node,dbg,ctp,[file,native_name_encoding,0]). | |
> | |
> check_disallowed_calls(TestNode,Line) -> | |
> receive | |
> Trace when element(1,Trace)==trace -> | |
> ?print_line(Line,["Disallowed function called",Trace]), | |
> exit({disallowed_function_call,Trace}) | |
> after 0 -> | |
> ok | |
> end. | |
> | |
> start_client(TestNode,Client,Sname) -> | |
> Node = list_to_atom(lists:concat([Sname,"@",test_host()])), | |
> case os:type() of | |
> {unix,_} -> start_client_unix(TestNode,Sname,Node); | |
> {win32,_} -> start_client_win32(TestNode,Client,Sname) | |
> end, | |
> receive | |
> {nodeup, Node} -> | |
> wait_started(TestNode,Node) | |
> after 30000 -> | |
> ?print([{start_client,failed,Node},net_adm:ping(Node)]), | |
> ?fail({"can not start", Node}) | |
> end. | |
> | |
> start_client_unix(TestNode,Sname,Node) -> | |
> Start = filename:join(["clients", "type1", Node, "bin", "start"]), | |
> Cmd = filename:join(code:root_dir(), Start), | |
> ?print([{start_client,Sname},Cmd]), | |
> Res = rh_test_lib:cmd(Cmd,[],[{"NODENAME",atom_to_list(Sname)}]), | |
> ?print([{start_client,result},Res]). | |
> | |
> start_client_win32(TestNode,Client,ClientSname) -> | |
> Name = atom_to_list(ClientSname) ++ "_P1G", | |
> RootDir = code:root_dir(), | |
> ErtsBinDir = filename:join([RootDir,"erts-"++?ertsvsn,"bin"]), | |
> | |
> {ClientArgs,RelClientDir} = rh_test_lib:get_client_args(Client,ClientSname, | |
> RootDir), | |
> StartErlArgs = rh_test_lib:get_start_erl_args(RootDir,RelClientDir, | |
> ClientArgs), | |
> ServiceArgs = rh_test_lib:get_service_args(RootDir, RelClientDir, | |
> ClientSname, StartErlArgs), | |
> | |
> ?print([{start_client,ClientSname},ServiceArgs]), | |
> Erlsrv = filename:nativename(filename:join(ErtsBinDir,"erlsrv")), | |
> rh_test_lib:erlsrv(Erlsrv,stop,Name), | |
> rh_test_lib:erlsrv(Erlsrv,remove,Name), | |
> ok = rh_test_lib:erlsrv(Erlsrv,add,Name,ServiceArgs), | |
> ok = rh_test_lib:erlsrv(Erlsrv,start,Name), | |
> ?print([{start_client,result},ok]), | |
> ok. | |
> | |
> reboot(TestNode,Node) -> | |
> cover_client(TestNode,Node,stop_cover), | |
> rpc:call(Node, init, reboot, []), | |
> check_reboot(TestNode,Node). | |
> | |
> %% This way of checking that the node is rebooted will only work if | |
> %% the nodes are automatically re-connected after the reboot. This | |
> %% happens for master/client (when sasl is started on the client). | |
> check_reboot(TestNode,Node) -> | |
> receive | |
> {nodedown, Node} -> | |
> receive | |
> {nodeup, Node} -> wait_started(TestNode,Node) | |
> after 30000 -> | |
> ?fail({Node, "not rebooted",net_adm:ping(Node)}) | |
> end | |
> after 30000 -> | |
> ?fail({Node, "not closing down",net_adm:ping(Node)}) | |
> end. | |
> | |
> stop_client(TestNode,Node) -> | |
> cover_client(TestNode,Node,stop_cover), | |
> rpc:call(Node, init, stop, []), | |
> receive | |
> {nodedown, Node} -> ok | |
> after 30000 -> | |
> ?fail({Node, "not stopping"}) | |
> end. | |
> | |
> wait_started(TestNode,Node) -> | |
> case rpc:call(Node, init, get_status, []) of | |
> {started, _} -> | |
> cover_client(TestNode,Node,start_cover), | |
> Node; | |
> _ -> | |
> timer:sleep(1000), | |
> wait_started(TestNode,Node) | |
> end. | |
> | |
> cover_client(TestNode,Node,Func) -> | |
> R = rpc:call(TestNode,release_handler_SUITE,Func,[Node]), | |
> ?print([{Func,Node,R}]). | |
> | |
> | |
> %%----------------------------------------------------------------- | |
> %% This test starts a client node which uses this node as master | |
> %% for the release_handler. | |
> %% The client node has the name cli2@HOSTNAME. | |
> %% The client node is not allowed to do ANY release updates | |
> %% as it also have another (non-existing) master node. | |
> %% | |
> %% The to_erl /tmp/cli2@HOSTNAME/ command can be used to connect | |
> %% to the client node. | |
> %% run_erl logs for the client can be found in the directory: | |
> %% code:root_dir() ++ "/clients/type1/cli2@HOSTNAME/log | |
> %%----------------------------------------------------------------- | |
> client2(TestNode,PrivDir,ClientSname) -> | |
> TestHost = test_host(), | |
> ?print(["client2 start"]), | |
> | |
> %% Clean up if previous test case failed | |
> release_handler:remove_release("P1H"), | |
> | |
> ok = net_kernel:monitor_nodes(true), | |
> Node = start_client(TestNode,client2,ClientSname), | |
> | |
> %% Check env var for SASL on client node | |
> SaslEnv = rpc:call(Node, application, get_all_env, [sasl]), | |
> ?print([{client1_1,sasl_env},SaslEnv]), | |
> {_,CliDir} = lists:keyfind(client_directory,1,SaslEnv), | |
> {_,[Master,Master2]} = lists:keyfind(masters,1,SaslEnv), | |
> {_,StartCli} = lists:keyfind(start_prg,1,SaslEnv), | |
> NodeStr = atom_to_list(Node), | |
> [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)), | |
> true = (Master =:= node()), | |
> true = (Master2 =:= list_to_atom("master2@"++TestHost)), | |
> case os:type() of | |
> {unix,_} -> | |
> true = (StartCli =:= filename:join([CliDir,"bin","start"])); | |
> _ -> | |
> ok | |
> end, | |
> | |
> %% Unpack P1H on master | |
> {ok, "P1H"} = unpack_release(PrivDir,"rel1"), | |
> | |
> %% Try to set P1H unpacked on client | |
> Root = code:root_dir(), | |
> {error,{bad_masters,[Master2]}} = | |
> rpc:call(Node, release_handler, set_unpacked, | |
> [filename:join([Root, "releases", "P1H", "rel1.rel"]),[]]), | |
> | |
> {error,{no_such_release,"P1H"}} = | |
> rpc:call(Node, release_handler, check_install_release, ["P1H"]), | |
> | |
> stop_client(TestNode,Node), %% TEST IS OK !! | |
> net_kernel:monitor_nodes(false), | |
> | |
> release_handler:remove_release("P1H"), | |
> ok. | |
> | |
> | |
> stop(Now) -> | |
> %% The timestamp is only used for debugging. It is printed by | |
> %% release_handler_SUITE also. | |
> R = init:stop(), | |
> erlang:display({init_stop,Now,R}), | |
> R. | |
> | |
> unpack_p1h(TestNode,PrivDir) -> | |
> {ok, "P1H"} = unpack_release(PrivDir,"rel1"), | |
> ?check_release_states([permanent,unpacked]), | |
> ?check_release_lib("P1H",["a-1.0"]), | |
> ok. | |
> | |
> permanent_p1h(TestNode) -> | |
> ?check_release_states([permanent,unpacked]), | |
> ?check_release_lib("P1H",["a-1.0"]), | |
> {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), | |
> ?check_release_states([permanent,current]), | |
> ok = release_handler:make_permanent("P1H"), | |
> ?check_release_states([old,permanent]), | |
> ok. | |
> | |
> | |
> reg_proc(Name) -> | |
> catch unregister(Name), | |
> Pid = spawn_link(?MODULE, registered_loop, [Name]), | |
> global:register_name(Name, Pid), | |
> ok. | |
> | |
> registered_loop(_Name) -> | |
> receive | |
> kill -> | |
> exit(killed) | |
> end. | |
> | |
> %% Checks that the list of states for all releases (sorted on vsn) | |
> %% equals the input States | |
> check_release_states(TestNode,Node,States,Line) -> | |
> case rpc:call(Node,release_handler,which_releases,[]) of | |
> {badrpc,_}=Error -> | |
> ?fail_line(Line,{check_release_states,Node,States,Error}); | |
> Rels -> | |
> ?print_line(Line,["check_release_states:", Rels]), | |
> States = [Status || {_,_,_,Status} <- lists:keysort(2,Rels)], | |
> ok | |
> end. | |
> | |
> %% Check that the given release (Vsn) sees the correct vsn of App. | |
> check_release_lib(TestNode,Node,Vsn,Apps,Line) -> | |
> case rpc:call(Node,release_handler,which_releases,[]) of | |
> {badrpc,_}=Error -> | |
> ?fail_line(Line,{check_release_lib,Node,Vsn,Apps,Error}); | |
> Rels -> | |
> ?print_line(Line,["check_release_lib:", Rels]), | |
> {"SASL-test", Vsn, Libs, _Status} = lists:keyfind(Vsn, 2, Rels), | |
> true = lists:all(fun(App) -> lists:member(App,Libs) end,Apps), | |
> ok | |
> end. | |
> | |
> %% Check that the given Vsn of App is executed | |
> check_running_app(TestNode,Node,App,Vsn,Line) -> | |
> case rpc:call(Node,application,which_applications,[]) of | |
> {badrpc,_}=Error -> | |
> ?fail_line(Line,{check_running_app,Node,App,Vsn,Error}); | |
> Apps -> | |
> ?print_line(Line,["check_running_app:", Apps]), | |
> {App, _, Vsn} = lists:keyfind(App, 1, Apps), | |
> ok | |
> end. | |
> | |
> test_host() -> | |
> {ok,Host} = inet:gethostname(), | |
> Host. | |
> | |
> unpack_release(PrivDir,Rel) -> | |
> copy(filename:join([PrivDir,Rel,Rel++".tar.gz"]), | |
> filename:join(code:root_dir(),releases)), | |
> release_handler:unpack_release(Rel). | |
> | |
> copy(Src, DestDir) -> | |
> Dest = filename:join(DestDir, filename:basename(Src)), | |
> {ok,_} = file:copy(Src, Dest), | |
> ok. | |
> | |
diff -r otp-OTP-19.3.6.5/lib/sasl/test/release_handler_SUITE_data/target_system.erl erlang-otp-6356f67/lib/sasl/test/release_handler_SUITE_data/target_system.erl | |
1c1,275 | |
< ../../examples/src/target_system.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 2011-2016. 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. | |
> %% 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% | |
> %% | |
> %module | |
> -module(target_system). | |
> -export([create/1, create/2, install/2]). | |
> | |
> %% Note: RelFileName below is the *stem* without trailing .rel, | |
> %% .script etc. | |
> %% | |
> | |
> %% create(RelFileName) | |
> %% | |
> create(RelFileName) -> | |
> create(RelFileName,[]). | |
> | |
> create(RelFileName,SystoolsOpts) -> | |
> RelFile = RelFileName ++ ".rel", | |
> Dir = filename:dirname(RelFileName), | |
> PlainRelFileName = filename:join(Dir,"plain"), | |
> PlainRelFile = PlainRelFileName ++ ".rel", | |
> io:fwrite("Reading file: ~tp ...~n", [RelFile]), | |
> {ok, [RelSpec]} = file:consult(RelFile), | |
> io:fwrite("Creating file: ~tp from ~tp ...~n", | |
> [PlainRelFile, RelFile]), | |
> {release, | |
> {RelName, RelVsn}, | |
> {erts, ErtsVsn}, | |
> AppVsns} = RelSpec, | |
> PlainRelSpec = {release, | |
> {RelName, RelVsn}, | |
> {erts, ErtsVsn}, | |
> lists:filter(fun({kernel, _}) -> | |
> true; | |
> ({stdlib, _}) -> | |
> true; | |
> (_) -> | |
> false | |
> end, AppVsns) | |
> }, | |
> {ok, Fd} = file:open(PlainRelFile, [write]), | |
> io:fwrite(Fd, "~p.~n", [PlainRelSpec]), | |
> file:close(Fd), | |
> | |
> io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", | |
> [PlainRelFileName,PlainRelFileName]), | |
> make_script(PlainRelFileName,SystoolsOpts), | |
> | |
> io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", | |
> [RelFileName, RelFileName]), | |
> make_script(RelFileName,SystoolsOpts), | |
> | |
> TarFileName = RelFileName ++ ".tar.gz", | |
> io:fwrite("Creating tar file ~tp ...~n", [TarFileName]), | |
> make_tar(RelFileName,SystoolsOpts), | |
> | |
> TmpDir = filename:join(Dir,"tmp"), | |
> io:fwrite("Creating directory ~tp ...~n",[TmpDir]), | |
> file:make_dir(TmpDir), | |
> | |
> io:fwrite("Extracting ~tp into directory ~tp ...~n", [TarFileName,TmpDir]), | |
> extract_tar(TarFileName, TmpDir), | |
> | |
> TmpBinDir = filename:join([TmpDir, "bin"]), | |
> ErtsBinDir = filename:join([TmpDir, "erts-" ++ ErtsVsn, "bin"]), | |
> io:fwrite("Deleting \"erl\" and \"start\" in directory ~tp ...~n", | |
> [ErtsBinDir]), | |
> file:delete(filename:join([ErtsBinDir, "erl"])), | |
> file:delete(filename:join([ErtsBinDir, "start"])), | |
> | |
> io:fwrite("Creating temporary directory ~tp ...~n", [TmpBinDir]), | |
> file:make_dir(TmpBinDir), | |
> | |
> io:fwrite("Copying file \"~ts.boot\" to ~tp ...~n", | |
> [PlainRelFileName, filename:join([TmpBinDir, "start.boot"])]), | |
> copy_file(PlainRelFileName++".boot",filename:join([TmpBinDir, "start.boot"])), | |
> | |
> io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" | |
> "~tp to ~tp ...~n", | |
> [ErtsBinDir, TmpBinDir]), | |
> copy_file(filename:join([ErtsBinDir, "epmd"]), | |
> filename:join([TmpBinDir, "epmd"]), [preserve]), | |
> copy_file(filename:join([ErtsBinDir, "run_erl"]), | |
> filename:join([TmpBinDir, "run_erl"]), [preserve]), | |
> copy_file(filename:join([ErtsBinDir, "to_erl"]), | |
> filename:join([TmpBinDir, "to_erl"]), [preserve]), | |
> | |
> %% This is needed if 'start' script created from 'start.src' shall | |
> %% be used as it points out this directory as log dir for 'run_erl' | |
> TmpLogDir = filename:join([TmpDir, "log"]), | |
> io:fwrite("Creating temporary directory ~tp ...~n", [TmpLogDir]), | |
> ok = file:make_dir(TmpLogDir), | |
> | |
> StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]), | |
> io:fwrite("Creating ~tp ...~n", [StartErlDataFile]), | |
> StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), | |
> write_file(StartErlDataFile, StartErlData), | |
> | |
> io:fwrite("Recreating tar file ~tp from contents in directory ~tp ...~n", | |
> [TarFileName,TmpDir]), | |
> {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), | |
> %% {ok, Cwd} = file:get_cwd(), | |
> %% file:set_cwd("tmp"), | |
> ErtsDir = "erts-"++ErtsVsn, | |
> erl_tar:add(Tar, filename:join(TmpDir,"bin"), "bin", []), | |
> erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []), | |
> erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []), | |
> erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []), | |
> erl_tar:add(Tar, filename:join(TmpDir,"log"), "log", []), | |
> erl_tar:close(Tar), | |
> %% file:set_cwd(Cwd), | |
> io:fwrite("Removing directory ~tp ...~n",[TmpDir]), | |
> remove_dir_tree(TmpDir), | |
> ok. | |
> | |
> | |
> install(RelFileName, RootDir) -> | |
> TarFile = RelFileName ++ ".tar.gz", | |
> io:fwrite("Extracting ~tp ...~n", [TarFile]), | |
> extract_tar(TarFile, RootDir), | |
> StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]), | |
> {ok, StartErlData} = read_txt_file(StartErlDataFile), | |
> [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"), | |
> ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]), | |
> BinDir = filename:join([RootDir, "bin"]), | |
> io:fwrite("Substituting in erl.src, start.src and start_erl.src to " | |
> "form erl, start and start_erl ...\n"), | |
> subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, | |
> [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], | |
> [preserve]), | |
> %%! Workaround for pre OTP 17.0: start.src and start_erl.src did | |
> %%! not have correct permissions, so the above 'preserve' option did not help | |
> ok = file:change_mode(filename:join(BinDir,"start"),8#0755), | |
> ok = file:change_mode(filename:join(BinDir,"start_erl"),8#0755), | |
> | |
> io:fwrite("Creating the RELEASES file ...\n"), | |
> create_RELEASES(RootDir, filename:join([RootDir, "releases", | |
> filename:basename(RelFileName)])). | |
> | |
> %% LOCALS | |
> | |
> %% make_script(RelFileName,Opts) | |
> %% | |
> make_script(RelFileName,Opts) -> | |
> systools:make_script(RelFileName, [no_module_tests, | |
> {outdir,filename:dirname(RelFileName)} | |
> |Opts]). | |
> | |
> %% make_tar(RelFileName,Opts) | |
> %% | |
> make_tar(RelFileName,Opts) -> | |
> RootDir = code:root_dir(), | |
> systools:make_tar(RelFileName, [{erts, RootDir}, | |
> {outdir,filename:dirname(RelFileName)} | |
> |Opts]). | |
> | |
> %% extract_tar(TarFile, DestDir) | |
> %% | |
> extract_tar(TarFile, DestDir) -> | |
> erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]). | |
> | |
> create_RELEASES(DestDir, RelFileName) -> | |
> release_handler:create_RELEASES(DestDir, RelFileName ++ ".rel"). | |
> | |
> subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> | |
> lists:foreach(fun(Script) -> | |
> subst_src_script(Script, SrcDir, DestDir, | |
> Vars, Opts) | |
> end, Scripts). | |
> | |
> subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> | |
> subst_file(filename:join([SrcDir, Script ++ ".src"]), | |
> filename:join([DestDir, Script]), | |
> Vars, Opts). | |
> | |
> subst_file(Src, Dest, Vars, Opts) -> | |
> {ok, Conts} = read_txt_file(Src), | |
> NConts = subst(Conts, Vars), | |
> write_file(Dest, NConts), | |
> case lists:member(preserve, Opts) of | |
> true -> | |
> {ok, FileInfo} = file:read_file_info(Src), | |
> file:write_file_info(Dest, FileInfo); | |
> false -> | |
> ok | |
> end. | |
> | |
> %% subst(Str, Vars) | |
> %% Vars = [{Var, Val}] | |
> %% Var = Val = string() | |
> %% Substitute all occurrences of %Var% for Val in Str, using the list | |
> %% of variables in Vars. | |
> %% | |
> subst(Str, Vars) -> | |
> subst(Str, Vars, []). | |
> | |
> subst([$%, C| Rest], Vars, Result) when $A =< C, C =< $Z -> | |
> subst_var([C| Rest], Vars, Result, []); | |
> subst([$%, C| Rest], Vars, Result) when $a =< C, C =< $z -> | |
> subst_var([C| Rest], Vars, Result, []); | |
> subst([$%, C| Rest], Vars, Result) when C == $_ -> | |
> subst_var([C| Rest], Vars, Result, []); | |
> subst([C| Rest], Vars, Result) -> | |
> subst(Rest, Vars, [C| Result]); | |
> subst([], _Vars, Result) -> | |
> lists:reverse(Result). | |
> | |
> subst_var([$%| Rest], Vars, Result, VarAcc) -> | |
> Key = lists:reverse(VarAcc), | |
> case lists:keysearch(Key, 1, Vars) of | |
> {value, {Key, Value}} -> | |
> subst(Rest, Vars, lists:reverse(Value, Result)); | |
> false -> | |
> subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]]) | |
> end; | |
> subst_var([C| Rest], Vars, Result, VarAcc) -> | |
> subst_var(Rest, Vars, Result, [C| VarAcc]); | |
> subst_var([], Vars, Result, VarAcc) -> | |
> subst([], Vars, [VarAcc ++ [$%| Result]]). | |
> | |
> copy_file(Src, Dest) -> | |
> copy_file(Src, Dest, []). | |
> | |
> copy_file(Src, Dest, Opts) -> | |
> {ok,_} = file:copy(Src, Dest), | |
> case lists:member(preserve, Opts) of | |
> true -> | |
> {ok, FileInfo} = file:read_file_info(Src), | |
> file:write_file_info(Dest, FileInfo); | |
> false -> | |
> ok | |
> end. | |
> | |
> write_file(FName, Conts) -> | |
> Enc = file:native_name_encoding(), | |
> {ok, Fd} = file:open(FName, [write]), | |
> file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)), | |
> file:close(Fd). | |
> | |
> read_txt_file(File) -> | |
> {ok, Bin} = file:read_file(File), | |
> {ok, binary_to_list(Bin)}. | |
> | |
> remove_dir_tree(Dir) -> | |
> remove_all_files(".", [Dir]). | |
> | |
> remove_all_files(Dir, Files) -> | |
> lists:foreach(fun(File) -> | |
> FilePath = filename:join([Dir, File]), | |
> case filelib:is_dir(FilePath) of | |
> true -> | |
> {ok, DirFiles} = file:list_dir(FilePath), | |
> remove_all_files(FilePath, DirFiles), | |
> file:del_dir(FilePath); | |
> _ -> | |
> file:delete(FilePath) | |
> end | |
> end, Files). | |
> %module | |
diff -r otp-OTP-19.3.6.5/lib/tools/emacs/tags.erl erlang-otp-6356f67/lib/tools/emacs/tags.erl | |
1c1,346 | |
< ../src/tags.erl | |
\ Наприкінці файла немає нового рядка | |
--- | |
> %% | |
> %% %CopyrightBegin% | |
> %% | |
> %% Copyright Ericsson AB 1996-2016. 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. | |
> %% 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% | |
> %% | |
> %%%---------------------------------------------------------------------- | |
> %%% File : tags.erl | |
> %%% Author : Anders Lindgren | |
> %%% Purpose : Generate an Emacs TAGS file from programs written in Erlang. | |
> %%% Date : 1998-03-16 | |
> %%% Version : 1.1 | |
> %%%---------------------------------------------------------------------- | |
> | |
> -module(tags). | |
> | |
> -export([file/1, file/2, files/1, files/2, dir/1, dir/2, | |
> dirs/1, dirs/2, subdir/1, subdir/2, subdirs/1, subdirs/2, | |
> root/0, root/1]). | |
> | |
> | |
> %% `Tags' is a part of the editor Emacs. It is used for warp-speed | |
> %% jumps between different source files in a project. When Using | |
> %% `Tags', a function in any source file can be found by few a simple | |
> %% keystrokes, just press M-. (in normal terms: Press Escape and dot). | |
> %% | |
> %% In order to work, the `Tags' system needs a list of all functions | |
> %% in all source files in the project. This list is denoted the "TAGS | |
> %% file". This purpose of this module is to create the TAGS file for | |
> %% programs written in Erlang. | |
> %% | |
> %% In addition to functions, both records and macros (`define's) are | |
> %% added to the TAGS file. | |
> | |
> | |
> %% Usage: | |
> %% root([Options]) -- Create a TAGS file covering all files in | |
> %% the Erlang distribution. | |
> %% | |
> %% file(File [, Options]) -- Create a TAGS file for the file `File'. | |
> %% files(FileList [, Options]) | |
> %% -- Dito for all files in `FileList'. | |
> %% | |
> %% dir(Dir [, Options]) -- Create a TAGS file for all files in `Dir'. | |
> %% dirs(DirList [, Options]) -- Dito for all files in all | |
> %% directories in `DirList'. | |
> %% | |
> %% subdir(Dir [, Options]) -- Descend recursively down `Dir' and create | |
> %% a TAGS file convering all files found. | |
> %% subdirs(DirList [, Options]) | |
> %% -- Dito, for all directories in `DirList'. | |
> %% | |
> %% The default is to create a file named "TAGS" in the current directory. | |
> %% | |
> %% Options is a list of tuples, where the following tuples are | |
> %% recognised: | |
> %% {outfile, NameOfTAGSFile} | |
> %% {outdir, NameOfDirectory} | |
> %% | |
> %% Note, should both `outfile' and `outdir' options be given, `outfile' | |
> %% take precedence. | |
> | |
> | |
> %%% External interface | |
> | |
> root() -> root([]). | |
> root(Options) -> subdir(code:root_dir(), Options). | |
> | |
> dir(Dir) -> dir(Dir, []). | |
> dir(Dir, Options) -> dirs([Dir], Options). | |
> | |
> dirs(Dirs) -> dirs(Dirs, []). | |
> dirs(Dirs, Options) -> | |
> files(collect_dirs(Dirs, false), Options). | |
> | |
> subdir(Dir) -> subdir(Dir, []). | |
> subdir(Dir, Options) -> subdirs([Dir], Options). | |
> | |
> subdirs(Dirs) -> subdirs(Dirs, []). | |
> subdirs(Dirs, Options) -> | |
> files(collect_dirs(Dirs, true), Options). | |
> | |
> file(Name) -> file(Name, []). | |
> file(Name, Options) -> files([Name], Options). | |
> | |
> files(Files) -> files(Files, []). | |
> files(Files, Options) -> | |
> case open_out(Options) of | |
> {ok, Os} -> | |
> files_loop(Files, Os), | |
> ok = close_out(Os), | |
> ok; | |
> _ -> | |
> error | |
> end. | |
> | |
> | |
> | |
> %%% Internal functions. | |
> | |
> %% Find all files in a directory list. Should the second argument be | |
> %% the atom `true' the functions will descend into subdirectories. | |
> collect_dirs(Dirs, Recursive) -> | |
> collect_dirs(Dirs, Recursive, []). | |
> | |
> collect_dirs([], _Recursive, Acc) -> Acc; | |
> collect_dirs([Dir | Dirs], Recursive, Acc) -> | |
> NewAcc = case file:list_dir(Dir) of | |
> {ok, Entries} -> | |
> collect_files(Dir, Entries, Recursive, Acc); | |
> _ -> | |
> Acc | |
> end, | |
> collect_dirs(Dirs, Recursive, NewAcc). | |
> | |
> collect_files(_Dir,[],_Recursive, Acc) -> Acc; | |
> collect_files(Dir, [File | Files], Recursive, Acc) -> | |
> FullFile = filename:join(Dir, File), | |
> NewAcc = case filelib:is_dir(FullFile) of | |
> true when Recursive -> | |
> collect_dirs([FullFile], Recursive, Acc); | |
> true -> | |
> Acc; | |
> false -> | |
> case filelib:is_regular(FullFile) of | |
> true -> | |
> case filename:extension(File) of | |
> ".erl" -> | |
> [FullFile | Acc]; | |
> ".hrl" -> | |
> [FullFile | Acc]; | |
> _ -> | |
> Acc | |
> end; | |
> false -> | |
> Acc | |
> end | |
> end, | |
> collect_files(Dir, Files, Recursive, NewAcc). | |
> | |
> | |
> files_loop([],_Os) -> true; | |
> files_loop([F | Fs], Os) -> | |
> case filename(F, Os) of | |
> ok -> | |
> ok; | |
> error -> | |
> %% io:format("Could not open ~ts~n", [F]), | |
> error | |
> end, | |
> files_loop(Fs, Os). | |
> | |
> | |
> %% Generate tags for one file. | |
> filename(Name, Os) -> | |
> case file:open(Name, [read]) of | |
> {ok, Desc} -> | |
> Acc = module(Desc, [], [], {1, 0}), | |
> ok = file:close(Desc), | |
> genout(Os, Name, Acc), | |
> ok; | |
> _ -> | |
> error | |
> end. | |
> | |
> | |
> module(In, Last, Acc, {LineNo, CharNo}) -> | |
> case io:get_line(In, []) of | |
> eof -> | |
> Acc; | |
> Line -> | |
> {NewLast, NewAcc} = line(Line, Last, Acc, {LineNo, CharNo}), | |
> module(In, NewLast, NewAcc, {LineNo+1, CharNo+length(Line)}) | |
> end. | |
> | |
> | |
> %% Handle one line. Return the last added function name. | |
> line([], Last, Acc, _) -> {Last, Acc}; | |
> line(Line, _, Acc, Nos) when hd(Line) =:= $- -> | |
> case attribute(Line, Nos) of | |
> false -> {[], Acc}; | |
> New -> {[], [New | Acc]} | |
> end; | |
> line(Line, Last, Acc, Nos) -> | |
> %% to be OR not to be? | |
> case case {hd(Line), word_char(hd(Line))} of | |
> {$', _} -> true; | |
> {_, true} -> true; | |
> _ -> false | |
> end of | |
> true -> | |
> case func(Line, Last, Nos) of | |
> false -> | |
> {Last, Acc}; | |
> {NewLast, NewEntry} -> | |
> {NewLast, [NewEntry | Acc]} | |
> end; | |
> false -> | |
> {Last, Acc} | |
> end. | |
> | |
> %% Handle one function. Will only add the first clause. (i.e. | |
> %% if the function name doesn't match `Last'). | |
> %% Return `false' or {NewLast, GeneratedLine}. | |
> func(Line, Last, Nos) -> | |
> {Name, Line1} = word(Line), | |
> case Name of | |
> [] -> false; | |
> Last -> false; | |
> _ -> | |
> {Space, Line2} = white(Line1), | |
> case Line2 of | |
> [$( | _] -> | |
> {Name, pfnote([$(, Space, Name], Nos)}; | |
> _ -> | |
> false | |
> end | |
> end. | |
> | |
> | |
> %% Return `false' or generated line. | |
> attribute([$- | Line], Nos) -> | |
> {Attr, Line1} = word(Line), | |
> case case Attr of | |
> "drocer" -> true; | |
> "enifed" -> true; | |
> _ -> false | |
> end of | |
> false -> | |
> false; | |
> true -> | |
> {Space2, Line2} = white(Line1), | |
> case Line2 of | |
> [$( | Line3] -> | |
> {Space4, Line4} = white(Line3), | |
> {Name,_Line5} = word(Line4), | |
> case Name of | |
> [] -> false; | |
> _ -> | |
> pfnote([Name, Space4, $(, Space2, Attr, $-], Nos) | |
> end; | |
> _ -> | |
> false | |
> end | |
> end. | |
> | |
> | |
> %% Removes whitespace from the head of the line. | |
> %% Returns {ReveredSpace, Rest} | |
> white(Line) -> white(Line, []). | |
> | |
> white([], Acc) -> {Acc, []}; | |
> white([32 | Rest], Acc) -> white(Rest, [32 | Acc]); | |
> white([9 | Rest], Acc) -> white(Rest, [9 | Acc]); | |
> white(Line, Acc) -> {Acc, Line}. | |
> | |
> | |
> %% Returns {ReversedWord, Rest} | |
> word([$' | Rest]) -> | |
> quoted(Rest, [$']); | |
> word(Line) -> | |
> unquoted(Line, []). | |
> | |
> quoted([$' | Rest], Acc) -> {[$' | Acc], Rest}; | |
> quoted([$\\ , C | Rest], Acc) -> | |
> quoted(Rest, [C, $\\ | Acc]); | |
> quoted([C | Rest], Acc) -> | |
> quoted(Rest, [C | Acc]). | |
> | |
> unquoted([], Word) -> {Word, []}; | |
> unquoted([C | Cs], Acc) -> | |
> case word_char(C) of | |
> true -> unquoted(Cs, [C | Acc]); | |
> false -> {Acc, [C | Cs]} | |
> end. | |
> | |
> word_char(C) when C >= $a, C =< $z -> true; | |
> word_char(C) when C >= $A, C =< $Z -> true; | |
> word_char(C) when C >= $0, C =< $9 -> true; | |
> word_char($_) -> true; | |
> word_char(_) -> false. | |
> | |
> | |
> %%% Output routines | |
> | |
> %% Check the options `outfile' and `outdir'. | |
> open_out(Options) -> | |
> Opts = [write, {encoding, unicode}], | |
> case lists:keysearch(outfile, 1, Options) of | |
> {value, {outfile, File}} -> | |
> file:open(File, Opts); | |
> _ -> | |
> case lists:keysearch(outdir, 1, Options) of | |
> {value, {outdir, Dir}} -> | |
> file:open(filename:join(Dir, "TAGS"), Opts); | |
> _ -> | |
> file:open("TAGS", Opts) | |
> end | |
> end. | |
> | |
> | |
> close_out(Os) -> | |
> file:close(Os). | |
> | |
> | |
> pfnote(Str, {LineNo, CharNo}) -> | |
> io_lib:format("~ts\177~w,~w~n", [flatrev(Str), LineNo, CharNo]). | |
> | |
> | |
> genout(Os, Name, Entries) -> | |
> io:format(Os, "\^l~n~ts,~w~n", [Name, reclength(Entries)]), | |
> io:put_chars(Os, lists:reverse(Entries)). | |
> | |
> | |
> | |
> %%% help routines | |
> | |
> %% Flatten and reverse a nested list. | |
> flatrev(Ls) -> flatrev(Ls, []). | |
> | |
> flatrev([C | Ls], Acc) when is_integer(C) -> flatrev(Ls, [C | Acc]); | |
> flatrev([L | Ls], Acc) -> flatrev(Ls, flatrev(L, Acc)); | |
> flatrev([], Acc) -> Acc. | |
> | |
> | |
> %% Count the number of elements in a nested list. | |
> reclength([L | Ls]) when is_list(L) -> | |
> reclength(L) + reclength(Ls); | |
> reclength([_ | Ls]) -> | |
> reclength(Ls) + 1; | |
> reclength([]) -> 0. | |
> | |
> %%% tags.erl ends here. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
otp-OTP-19.3.6.5 = from otp-OTP-19.3.6.5.zip | |
page https://github.com/erlang/otp/releases/tag/OTP-19.3.6.5 | |
link https://github.com/erlang/otp/archive/refs/tags/OTP-19.3.6.5.zip ("Source code (zip)" - bottom) | |
erlang-otp-6356f67 = from erlang-otp-OTP-19.3.6.5-0-g2e7160f.tar.gz | |
page https://www.erlang.org/patches/otp-19.3.6.5 | |
link https://api.github.com/repos/erlang/otp/tarball/refs/tags/OTP-19.3.6.5 (red button "Download source" - right top) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment