Codebase list swi-prolog / b9a3b2a
New upstream version 8.1.28+dfsg Lev Lamberov 4 years ago
250 changed file(s) with 4666 addition(s) and 3975 deletion(s). Raw diff Collapse all Expand all
105105 | `-DMULTI_THREADED=OFF` | Drop support for Prolog threads |
106106 | `-DUSE_SIGNALS=OFF` | Drop signal support |
107107 | `-DUSE_GMP=OFF` | Drop bignum and rational numbers |
108 | `-DUSE_TCMALLOC=OFF` | Do not link against `-ltcmalloc` |
108109 | `-DSWIPL_SHARED_LIB=OFF` | Build Prolog kernel as static lib |
109110 | `-DSWIPL_INSTALL_IN_LIB=ON` | Install libswipl.so in <prefix>/lib |
111 | `-DSWIPL_INSTALL_IN_SHARE=ON` | Install docs in <prefix>/share |
110112 | `-DSWIPL_M32=ON` | Make 32-bit version on 64-bit Linux |
111113 | `-DSWIPL_PACKAGES=OFF` | Only build the core system |
112114 | `-DSWIPL_PACKAGES_BASIC=OFF` | Drop all basic packages |
334336 % ninja
335337
336338 See also `cmake/BuildType.cmake` and `PL_halt()` in `src/pl-fli.c`.
339
340 You can run the tests normally using `ctest`. Note that the `swipl:GC`
341 test requires more stack than the default when using AddressSanitizer.
342 To fix this run (bash) `ulimit -s 20000` before running `ctest`. The
343 test `jpl:prolog_in_java` because Java is not loaded with
344 AddressSanitizer preloaded. All other tests should pass (about 4 times
345 slower than normal).
337346
338347
339348 ## Packaging
1414 option(USE_GMP
1515 "Use GNU MP Bignum library (GPL)"
1616 ON)
17 option(USE_TCMALLOC
18 "Use Google tcmalloc instead of default malloc"
19 ON)
1720 option(SWIPL_SHARED_LIB
1821 "Put kernel in a shared library"
1922 ON)
2225 OFF)
2326 option(SWIPL_INSTALL_IN_LIB
2427 "Install library in ${CMAKE_INSTALL_PREFIX}/lib"
28 OFF)
29 option(SWIPL_INSTALL_IN_SHARE
30 "Install docs in ${CMAKE_INSTALL_PREFIX}/share/swipl"
2531 OFF)
2632 option(SWIPL_M32
2733 "Build 32-bit version on 64-bit Linux using multilib and gcc -m32"
109115 set(SWIPL_INSTALL_RESOURCES SWI-Prolog.app/Contents/Resources)
110116 else()
111117 set(SWIPL_INSTALL_PREFIX lib/${SWIPL_INSTALL_DIR})
118 if(SWIPL_INSTALL_IN_SHARE)
119 set(SWIPL_INSTALL_SHARE_PREFIX share/${SWIPL_INSTALL_DIR})
120 endif()
112121 set(SWIPL_INSTALL_ARCH_EXE ${SWIPL_INSTALL_PREFIX}/bin/${SWIPL_ARCH})
113122 set(SWIPL_INSTALL_ARCH_LIB ${SWIPL_INSTALL_PREFIX}/lib/${SWIPL_ARCH})
114123 set(SWIPL_INSTALL_MANPAGES share/man/man1
121130
122131 endif(WIN32)
123132
133 if(NOT SWIPL_INSTALL_SHARE_PREFIX)
134 set(SWIPL_INSTALL_SHARE_PREFIX "${SWIPL_INSTALL_PREFIX}")
135 endif()
136
124137 set(SWIPL_INSTALL_LIBRARY ${SWIPL_INSTALL_PREFIX}/library)
125138 set(SWIPL_INSTALL_BOOT ${SWIPL_INSTALL_PREFIX}/boot)
126139 set(SWIPL_INSTALL_INCLUDE ${SWIPL_INSTALL_PREFIX}/include)
140 set(SWIPL_INSTALL_DOC ${SWIPL_INSTALL_SHARE_PREFIX}/doc)
127141 if(INSTALL_TESTS)
128142 set(INSTALL_TESTS_DIR ${SWIPL_INSTALL_PREFIX}/test)
129143 endif()
146160 if(MULTI_THREADED)
147161 find_package(Threads)
148162 endif()
163
164 include(TestLargeFiles)
165 OPJ_TEST_LARGE_FILES(HAVE_LARGE_FILES)
149166
150167 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "Core_system")
151168
157174
158175 if(INSTALL_DOCUMENTATION)
159176 include(Documentation)
177 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Documentation)
178
160179 add_custom_target(
161180 doc ALL
162181 COMMENT "Build the documentation")
176195 man_index
177196 DEPENDS ${MAN_INDEX})
178197 add_dependencies(doc man_index)
179 install(FILES ${MAN_INDEX} DESTINATION ${SWIPL_INSTALL_PREFIX}/doc)
198 install(FILES ${MAN_INDEX} DESTINATION ${SWIPL_INSTALL_DOC})
180199
181200 if(BUILD_PDF_DOCUMENTATION)
182201 add_custom_target(
185204 add_dependencies(doc doc.pdf)
186205 endif()
187206
188 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Documentation)
189207 add_subdirectory(man)
190208 install(FILES packages/index.html
191 DESTINATION ${SWIPL_INSTALL_PREFIX}/doc/packages)
209 DESTINATION ${SWIPL_INSTALL_DOC}/packages)
192210 endif(INSTALL_DOCUMENTATION)
193211
194212 # Install a prolog script to run tests on target device
199217 set(INSTALL_TESTS_DB ${CMAKE_BINARY_DIR}/cmake_pkg_tests.db)
200218 #Move test db to installation
201219 install(FILES ${INSTALL_TESTS_DB}
202 DESTINATION ${INSTALL_TESTS_DIR}/)
220 DESTINATION ${INSTALL_TESTS_DIR}
221 COMPONENT Tests)
203222 file(REMOVE ${INSTALL_TESTS_DB})
204223 endif(INSTALL_TESTS)
205224
0 8.1.26
0 8.1.28
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2017, VU University Amsterdam
5 Copyright (c) 2017-2020, VU University Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
4041 %
4142 % Wait for signals from other threads to perform global GC operations
4243 % and do them for them.
44 %
45 % When using [tcmalloc](https://github.com/google/tcmalloc) we call
46 % MallocExtension_MarkThreadIdle() to transfer the collected memory
47 % immediately to the other threads.
4348
4449 gc_loop :-
4550 repeat,
46 '$gc_wait'(Action),
51 thread_idle('$gc_wait'(Action), short),
4752 ( Action == abort
4853 -> true
4954 ; process(Action)
928928 library_directory(Dir)).
929929 user:file_search_path(swi, Home) :-
930930 current_prolog_flag(home, Home).
931 user:file_search_path(swi, Home) :-
932 current_prolog_flag(shared_home, Home).
931933 user:file_search_path(foreign, swi(ArchLib)) :-
932934 \+ current_prolog_flag(windows, true),
933935 current_prolog_flag(arch, Arch),
39623964 user:prolog_list_goal(Goal),
39633965 !.
39643966 '$prolog_list_goal'(Goal) :-
3965 user:listing(Goal).
3967 use_module(library(listing), [listing/1]),
3968 @(listing(Goal), user).
3969
39663970
39673971 /*******************************
39683972 * MISC *
19401940 !,
19411941 actions_to_format(T, Fmt0, Args),
19421942 atom_concat('~n', Fmt0, Fmt).
1943 actions_to_format([Skip|T], Fmt, Args) :-
1944 action_skip(Skip),
1945 !,
1946 actions_to_format(T, Fmt, Args).
1947 actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
1943 actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :-
19481944 !,
19491945 actions_to_format(Tail, Fmt1, Args1),
19501946 atom_concat(Fmt0, Fmt1, Fmt),
19511947 append_args(Args0, Args1, Args).
1948 actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
1949 !,
1950 actions_to_format(Tail, Fmt1, Args1),
1951 atom_concat(Fmt0, Fmt1, Fmt),
1952 append_args(Args0, Args1, Args).
1953 actions_to_format([Skip|T], Fmt, Args) :-
1954 action_skip(Skip),
1955 !,
1956 actions_to_format(T, Fmt, Args).
19521957 actions_to_format([Term|Tail], Fmt, Args) :-
19531958 atomic(Term),
19541959 !,
19611966
19621967 action_skip(at_same_line).
19631968 action_skip(flush).
1964 action_skip(ansi(_Attrs, _Fmt, _Args)).
19651969 action_skip(begin(_Level, _Ctx)).
19661970 action_skip(end(_Ctx)).
19671971
899899 '$get_predicate_attribute'(Pred, incremental, 1).
900900 '$predicate_property'(abstract(N), Pred) :-
901901 '$get_predicate_attribute'(Pred, abstract, N).
902 '$predicate_property'(size(Bytes), Pred) :-
903 '$get_predicate_attribute'(Pred, size, Bytes).
902904
903905 system_undefined(user:prolog_trace_interception/4).
904906 system_undefined(user:prolog_exception_hook/4).
11221124 module_property(line_count(_)).
11231125 module_property(exports(_)).
11241126 module_property(exported_operators(_)).
1127 module_property(size(_)).
11251128 module_property(program_size(_)).
11261129 module_property(program_space(_)).
11271130 module_property(last_modified_generation(_)).
12151218 trie_property(reevaluated(_)).
12161219 trie_property(deadlock(_)). % Shared tabling stats
12171220 trie_property(wait(_)).
1221 trie_property(idg_affected_count(_)).
1222 trie_property(idg_dependent_count(_)).
1223 trie_property(idg_size(_)).
12181224
12191225
12201226 /********************************
5050 check_include_file(zlib.h HAVE_ZLIB_H)
5151 check_include_file(crt_externs.h HAVE_CRT_EXTERNS_H)
5252
53 check_library_exists(dl dlopen "" HAVE_LIBDL)
54 check_library_exists(m sin "" HAVE_LIBM)
55 check_library_exists(rt clock_gettime "" HAVE_LIBRT)
53 check_c_source_compiles(
54 "int val = 1;
55 int main() { __atomic_add_fetch(&val, 2, __ATOMIC_SEQ_CST); }"
56 HAVE_GCC_ATOMIC)
57 check_c_source_compiles(
58 "#include <stdint.h>
59 uint64_t val = 1;
60 int main() { __atomic_add_fetch(&val, 2, __ATOMIC_SEQ_CST); }"
61 HAVE_GCC_ATOMIC_8)
62 if(HAVE_GCC_ATOMIC AND NOT HAVE_GCC_ATOMIC_8)
63 check_library_exists(atomic __atomic_add_fetch_4 "" HAVE_LIBATOMIC)
64 else()
65 set(HAVE_LIBATOMIC OFF CACHE BOOL "No need to link with -latomic")
66 endif()
67
68 check_library_exists(dl dlopen "" HAVE_LIBDL)
69 check_library_exists(m sin "" HAVE_LIBM)
70 check_library_exists(rt clock_gettime "" HAVE_LIBRT)
5671
5772 if(HAVE_LIBDL)
5873 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dl)
44 if(UNIX AND NOT EMSCRIPTEN)
55 find_package(Curses)
66 endif()
7 if(USE_TCMALLOC)
8 find_package(LibTCMalloc)
9 endif()
0 # - Try to find Google LibTCMalloc
1 # Once done this will define
2 # LIBTCMALLOC_FOUND - System has tcmalloc (minimal)
3 # LIBTCMALLOC_LIBRARIES - The libraries needed to use tcmalloc
4 # LIBTCMALLOC_DEFINITIONS - Compiler switches required for using tcmalloc
5
6 find_package(PkgConfig)
7 pkg_check_modules(PC_LIBTCMALLOC_MINIMAL QUIET libtcmalloc_minimal)
8 set(LIBTCMALLOC_DEFINITIONS ${PC_LIBTCMALLOC_MINIMAL_CFLAGS_OTHER})
9
10 find_library(LIBTCMALLOC_LIBRARY NAMES tcmalloc_minimal
11 HINTS ${PC_LIBTCMALLOC_MINIMAL_LIBDIR}
12 ${PC_LIBTCMALLOC_MINIMAL_LIBRARY_DIRS} )
13
14 include(FindPackageHandleStandardArgs)
15 # handle the QUIETLY and REQUIRED arguments and set LIBTCMALLOC_FOUND to TRUE
16 # if all listed variables are TRUE
17 find_package_handle_standard_args(LibTCMalloc DEFAULT_MSG
18 LIBTCMALLOC_LIBRARY)
19
20 mark_as_advanced(LIBTCMALLOC_LIBRARY )
21
22 set(LIBTCMALLOC_LIBRARIES ${LIBTCMALLOC_LIBRARY} )
55 check_c_source_compiles(
66 "unsigned int x = 11; int main() { return __builtin_popcount(x); }"
77 HAVE__BUILTIN_POPCOUNT)
8 check_c_source_compiles(
9 "int main() { __sync_synchronize(); return 0;}"
10 HAVE__SYNC_SYNCHRONIZE)
11 check_c_source_compiles(
12 "long long v = 1; int main() { return __sync_add_and_fetch(&v, 1); }"
13 HAVE___SYNC_ADD_AND_FETCH_8)
148 check_c_source_compiles(
159 "int i=0; int main() { return __builtin_expect(i, 0) ? 0 : 1; }"
1610 HAVE___BUILTIN_EXPECT)
7878 endif()
7979 endfunction()
8080
81 # install_in_home(name ...)
82 #
83 # Install the targets in the local home. This replaces
84 # SWIPL_INSTALL_PREFIX or SWIPL_INSTALL_SHARE_PREFIX by `home`
85
8186 function(install_in_home name)
8287 cmake_parse_arguments(my "" "RENAME;DESTINATION" "FILES" ${ARGN})
8388 if(my_DESTINATION AND my_FILES)
8590 string(REGEX REPLACE
8691 "^${pattern}"
8792 "${SWIPL_BUILD_HOME}" buildhome ${my_DESTINATION})
93
94 if(buildhome STREQUAL my_DESTINATION AND
95 NOT SWIPL_INSTALL_PREFIX STREQUAL SWIPL_INSTALL_SHARE_PREFIX)
96 string(REPLACE "." "\\." pattern ${SWIPL_INSTALL_SHARE_PREFIX})
97 string(REGEX REPLACE
98 "^${pattern}"
99 "${SWIPL_BUILD_HOME}" buildhome ${my_DESTINATION})
100 endif()
88101
89102 set(deps)
90103
77 set(C_CXX ${CMAKE_CXX_COMPILER})
88 endif()
99 set(PLHOME ${CMAKE_INSTALL_PREFIX}/${SWIPL_INSTALL_PREFIX})
10 if(SWIPL_INSTALL_IN_SHARE)
11 set(PLSHAREDHOME ${CMAKE_INSTALL_PREFIX}/share/${SWIPL_INSTALL_DIR})
12 endif()
1013 set(PLARCH ${SWIPL_ARCH})
1114 string(REGEX REPLACE "\\." "" SO_EXT "${CMAKE_SHARED_MODULE_SUFFIX}")
1215
0 #include <sys/types.h>
1
2 /* Cause a compile-time error if off_t is smaller than 64 bits */
3 #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
4 int off_t_is_large[ (LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1 ];
5
6 int main(int argc, char **argv)
7 {
8 return 0;
9 }
10
0 #cmakedefine _LARGEFILE_SOURCE
1 #cmakedefine _LARGE_FILES
2 #cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
3
4 #include <sys/types.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 int main(int argc, char **argv)
9 {
10 /* Cause a compile-time error if off_t is smaller than 64 bits,
11 * and make sure we have ftello / fseeko.
12 */
13 #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
14 int off_t_is_large[ (LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1 ];
15 FILE *fp = fopen(argv[0],"r");
16 off_t offset = ftello( fp );
17
18 fseeko( fp, offset, SEEK_CUR );
19 fclose(fp);
20 return 0;
21 }
22
0 # - Define macro to check large file support
1 #
2 # OPJ_TEST_LARGE_FILES(VARIABLE)
3 #
4 # VARIABLE will be set to true if off_t is 64 bits, and fseeko/ftello present.
5 # This macro will also defines the necessary variable enable large file support, for instance
6 # _LARGE_FILES
7 # _LARGEFILE_SOURCE
8 # _FILE_OFFSET_BITS 64
9 # OPJ_HAVE_FSEEKO
10 #
11 # However, it is YOUR job to make sure these defines are set in a #cmakedefine so they
12 # end up in a config.h file that is included in your source if necessary!
13 #
14 # Adapted from Gromacs project (http://www.gromacs.org/)
15 # by Julien Malik
16 #
17
18 macro(OPJ_TEST_LARGE_FILES VARIABLE)
19 if(NOT DEFINED ${VARIABLE})
20
21 # On most platforms it is probably overkill to first test the flags for 64-bit off_t,
22 # and then separately fseeko. However, in the future we might have 128-bit filesystems
23 # (ZFS), so it might be dangerous to indiscriminately set e.g. _FILE_OFFSET_BITS=64.
24
25 message(STATUS "Checking for 64-bit off_t")
26
27 # First check without any special flags
28 try_compile(FILE64_OK "${PROJECT_BINARY_DIR}"
29 "${PROJECT_SOURCE_DIR}/cmake/TestFileOffsetBits.c")
30 if(FILE64_OK)
31 message(STATUS "Checking for 64-bit off_t - present")
32 endif()
33
34 if(NOT FILE64_OK)
35 # Test with _FILE_OFFSET_BITS=64
36 try_compile(FILE64_OK "${PROJECT_BINARY_DIR}"
37 "${PROJECT_SOURCE_DIR}/cmake/TestFileOffsetBits.c"
38 COMPILE_DEFINITIONS "-D_FILE_OFFSET_BITS=64" )
39 if(FILE64_OK)
40 message(STATUS "Checking for 64-bit off_t - present with _FILE_OFFSET_BITS=64")
41 set(_FILE_OFFSET_BITS 64)
42 endif()
43 endif()
44
45 if(NOT FILE64_OK)
46 # Test with _LARGE_FILES
47 try_compile(FILE64_OK "${PROJECT_BINARY_DIR}"
48 "${PROJECT_SOURCE_DIR}/cmake/TestFileOffsetBits.c"
49 COMPILE_DEFINITIONS "-D_LARGE_FILES" )
50 if(FILE64_OK)
51 message(STATUS "Checking for 64-bit off_t - present with _LARGE_FILES")
52 set(_LARGE_FILES 1)
53 endif()
54 endif()
55
56 if(NOT FILE64_OK)
57 # Test with _LARGEFILE_SOURCE
58 try_compile(FILE64_OK "${PROJECT_BINARY_DIR}"
59 "${PROJECT_SOURCE_DIR}/cmake/TestFileOffsetBits.c"
60 COMPILE_DEFINITIONS "-D_LARGEFILE_SOURCE" )
61 if(FILE64_OK)
62 message(STATUS "Checking for 64-bit off_t - present with _LARGEFILE_SOURCE")
63 set(_LARGEFILE_SOURCE 1)
64 endif()
65 endif()
66
67
68 #if(NOT FILE64_OK)
69 # # now check for Windows stuff
70 # try_compile(FILE64_OK "${PROJECT_BINARY_DIR}"
71 # "${PROJECT_SOURCE_DIR}/cmake/TestWindowsFSeek.c")
72 # if(FILE64_OK)
73 # message(STATUS "Checking for 64-bit off_t - present with _fseeki64")
74 # set(HAVE__FSEEKI64 1)
75 # endif()
76 #endif()
77
78 if(NOT FILE64_OK)
79 message(STATUS "Checking for 64-bit off_t - not present")
80 endif()
81
82 set(_FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} CACHE INTERNAL "Result of test for needed _FILE_OFFSET_BITS=64")
83 set(_LARGE_FILES ${_LARGE_FILES} CACHE INTERNAL "Result of test for needed _LARGE_FILES")
84 set(_LARGEFILE_SOURCE ${_LARGEFILE_SOURCE} CACHE INTERNAL "Result of test for needed _LARGEFILE_SOURCE")
85
86 # Set the flags we might have determined to be required above
87 configure_file("${PROJECT_SOURCE_DIR}/cmake/TestLargeFiles.c.cmake.in"
88 "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestLargeFiles.c")
89
90 message(STATUS "Checking for fseeko/ftello")
91
92 # Test if ftello/fseeko are available
93 try_compile(FSEEKO_COMPILE_OK
94 "${PROJECT_BINARY_DIR}"
95 "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestLargeFiles.c")
96
97 if(FSEEKO_COMPILE_OK)
98 message(STATUS "Checking for fseeko/ftello - present")
99 endif()
100
101 if(NOT FSEEKO_COMPILE_OK)
102 # glibc 2.2 needs _LARGEFILE_SOURCE for fseeko (but not for 64-bit off_t...)
103 try_compile(FSEEKO_COMPILE_OK
104 "${PROJECT_BINARY_DIR}"
105 "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestLargeFiles.c"
106 COMPILE_DEFINITIONS "-D_LARGEFILE_SOURCE" )
107
108 if(FSEEKO_COMPILE_OK)
109 message(STATUS "Checking for fseeko/ftello - present with _LARGEFILE_SOURCE")
110 set(_LARGEFILE_SOURCE ${_LARGEFILE_SOURCE} CACHE INTERNAL "Result of test for needed _LARGEFILE_SOURCE")
111 endif()
112 endif()
113
114 if(FSEEKO_COMPILE_OK)
115 set(OPJ_HAVE_FSEEKO ON CACHE INTERNAL "Result of test for fseeko/ftello")
116 else()
117 message(STATUS "Checking for fseeko/ftello - not found")
118 set(OPJ_HAVE_FSEEKO OFF CACHE INTERNAL "Result of test for fseeko/ftello")
119 endif()
120
121 if(FILE64_OK AND FSEEKO_COMPILE_OK)
122 message(STATUS "Large File support - found")
123 set(${VARIABLE} ON CACHE INTERNAL "Result of test for large file support")
124 else()
125 message(STATUS "Large File support - not found")
126 set(${VARIABLE} OFF CACHE INTERNAL "Result of test for large file support")
127 endif()
128
129 endif()
130 endmacro()
131
132
133
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2008-2016, University of Amsterdam
5 Copyright (c) 2008-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
6061
6162 This library provides aggregating operators over the solutions of a
6263 predicate. The operations are a generalisation of the bagof/3, setof/3
63 and findall/3 built-in predicates. The defined aggregation operations
64 are counting, computing the sum, minimum, maximum, a bag of solutions
65 and a set of solutions. We first give a simple example, computing the
66 country with the smallest area:
67
68 ==
64 and findall/3 built-in predicates. Aggregations that can be computed
65 incrementally avoid findall/3 and run in constant memory. The defined
66 aggregation operations are counting, computing the sum, minimum,
67 maximum, a bag of solutions and a set of solutions. We first give a
68 simple example, computing the country with the smallest area:
69
70 ```
6971 smallest_country(Name, Area) :-
70 aggregate(min(A, N), country(N, A), min(Area, Name)).
71 ==
72 aggregate(min(A, N), country(N, A), min(Area, Name)).
73 ```
7274
7375 There are four aggregation predicates (aggregate/3, aggregate/4, aggregate_all/3 and aggregate/4), distinguished on two properties.
7476
7577 $ aggregate vs. aggregate_all :
7678 The aggregate predicates use setof/3 (aggregate/4) or bagof/3
7779 (aggregate/3), dealing with existential qualified variables
78 (Var^Goal) and providing multiple solutions for the remaining free
79 variables in Goal. The aggregate_all/3 predicate uses findall/3,
80 (`Var^Goal`) and providing multiple solutions for the remaining free
81 variables in `Goal`. The aggregate_all/3 predicate uses findall/3,
8082 implicitly qualifying all free variables and providing exactly one
8183 solution, while aggregate_all/4 uses sort/2 over solutions that
8284 Discriminator (see below) generated using findall/3.
163165
164166 %! aggregate_all(+Template, :Goal, -Result) is semidet.
165167 %
166 % Aggregate bindings in Goal according to Template. The
167 % aggregate_all/3 version performs findall/3 on Goal. Note that
168 % this predicate fails if Template contains one or more of min(X),
169 % max(X), min(X,Witness) or max(X,Witness) and Goal has no
170 % solutions, i.e., the minumum and maximum of an empty set is
171 % undefined.
168 % Aggregate bindings in Goal according to Template. The
169 % aggregate_all/3 version performs findall/3 on Goal. Note that this
170 % predicate fails if Template contains one or more of min(X), max(X),
171 % min(X,Witness) or max(X,Witness) and Goal has no solutions, i.e.,
172 % the minimum and maximum of an empty set is undefined.
173 %
174 % The Template values `count`, sum(X), max(X), min(X), max(X,W) and
175 % min(X,W) are processed incrementally rather than using findall/3 and
176 % run in constant memory.
172177
173178 aggregate_all(Var, _, _) :-
174179 var(Var),
3939 list_undefined/1, % +Options
4040 list_autoload/0, % list predicates that need autoloading
4141 list_redefined/0, % list redefinitions
42 list_cross_module_calls/0, % List Module:Goal usage
43 list_cross_module_calls/1, % +Options
4244 list_void_declarations/0, % list declarations with no clauses
4345 list_trivial_fails/0, % list goals that trivially fail
4446 list_trivial_fails/1, % +Options
294296
295297 global_module(user).
296298 global_module(system).
299
300 %! list_cross_module_calls is det.
301 %
302 % List calls from one module to another using Module:Goal where the
303 % callee is not defined exported, public or multifile, i.e., where the
304 % callee should be considered _private_.
305
306 list_cross_module_calls :-
307 list_cross_module_calls([]).
308
309 list_cross_module_calls(Options) :-
310 call_cleanup(
311 list_cross_module_calls_guarded(Options),
312 retractall(cross_module_call(_,_,_))).
313
314 list_cross_module_calls_guarded(Options) :-
315 merge_options(Options,
316 [ module_class([user])
317 ],
318 WalkOptions),
319 prolog_walk_code([ trace_reference(_),
320 trace_condition(cross_module_call),
321 on_trace(write_call)
322 | WalkOptions
323 ]).
324
325 :- thread_local
326 cross_module_call/3.
327
328 :- public
329 cross_module_call/2,
330 write_call/3.
331
332 cross_module_call(Callee, Context) :-
333 \+ same_module_call(Callee, Context).
334
335 same_module_call(Callee, Context) :-
336 caller_module(Context, MCaller),
337 Callee = (MCallee:_),
338 ( ( MCaller = MCallee
339 ; predicate_property(Callee, exported)
340 ; predicate_property(Callee, built_in)
341 ; predicate_property(Callee, public)
342 ; clause_property(Context.get(clause), module(MCallee))
343 ; predicate_property(Callee, multifile)
344 )
345 -> true
346 ).
347
348 caller_module(Context, MCaller) :-
349 Caller = Context.caller,
350 ( Caller = (MCaller:_)
351 -> true
352 ; Caller == '<initialization>',
353 MCaller = Context.module
354 ).
355
356 write_call(Callee, Caller, Position) :-
357 cross_module_call(Callee, Caller, Position),
358 !.
359 write_call(Callee, Caller, Position) :-
360 ( cross_module_call(_,_,_)
361 -> true
362 ; print_message(warning, check(cross_module_calls))
363 ),
364 asserta(cross_module_call(Callee, Caller, Position)),
365 print_message(warning,
366 check(cross_module_call(Callee, Caller, Position))).
297367
298368 %! list_void_declarations is det.
299369 %
808878 prolog:message(check(redefined(In, From, Pred))) -->
809879 predicate(In:Pred),
810880 redefined(In, From).
881 prolog:message(check(cross_module_calls)) -->
882 [ 'Qualified calls to private predicates'-[] ].
883 prolog:message(check(cross_module_call(Callee, _Caller, Location))) -->
884 { pi_head(PI, Callee) },
885 [ ' '-[] ],
886 '$messages':swi_location(Location),
887 [ 'Cross-module call to ~p'-[PI] ].
811888 prolog:message(check(trivial_failures)) -->
812889 [ 'The following goals fail because there are no matching clauses.' ].
813890 prolog:message(check(trivial_failure(Goal, Refs))) -->
8080 % features.
8181
8282 % Feature tests
83 component(tcmalloc,
84 _{ test:test_tcmalloc,
85 url:'tcmalloc.html'
86 }).
8387 component(gmp,
8488 _{ test:current_prolog_flag(bounded, false),
8589 url:'gmp.html'
311315 * SPECIAL TESTS *
312316 *******************************/
313317
318 %! test_tcmalloc
319
320 :- if(current_predicate(malloc_property/1)).
321 test_tcmalloc :-
322 malloc_property('generic.current_allocated_bytes'(Bytes)),
323 Bytes > 1 000 000.
324 :- else.
325 test_tcmalloc :-
326 fail.
327 :- endif.
328
314329 %! archive_features
315330 %
316331 % Report features supported by library(archive).
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2006-2018, University of Amsterdam
5 Copyright (c) 2006-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
334334 % True if Term satisfies Type.
335335
336336 :- '$clausable'(has_type/2). % always allow clause/2
337 :- public % May be called through current_type/3
338 is_list_or_partial_list/1,
339 current_encoding/1,
340 element_types/2.
337341
338342 has_type(any, _).
339343 has_type(atom, X) :- atom(X).
9898 test,development]))),
9999 source(boolean),
100100 trace_reference(any),
101 trace_condition(callable),
101102 on_trace(callable),
102103 infer_meta_predicates(oneof([false,true,all])),
103104 evaluate(boolean),
114115 infer_meta_predicates:oneof([false,true,all])=true,
115116 clauses:list, % Walk only these clauses
116117 trace_reference:any=(-),
118 trace_condition:callable, % Call-back condition
117119 on_trace:callable, % Call-back on trace hits
118120 % private stuff
119121 clause, % Processed clause
174176 % Print all calls to goals that subsume Callable. Goals are
175177 % represented as Module:Callable (i.e., they are always
176178 % qualified). See also subsumes_term/2.
179 %
180 % * trace_condition(:Cond)
181 % Additional filter condition applied after `trace_reference`.
182 % Called as call(Cond, Callee, Context), where `Context` is a
183 % dict containing the following keys:
184 %
185 % - Context:caller
186 % Qualified term representing the caller or the atom
187 % '<initialization>'.
188 % - Context:module
189 % Module being processed
190 % - Context:clause
191 % If we are processing a normal clause, the clause reference
192 % to this clause.
193 % - Context:initialization
194 % If we are processing an initialization/1 directive, a term
195 % `File:Line` representing the location of the declaration.
177196 %
178197 % * on_trace(:OnTrace)
179198 % If a reference to =trace_reference= is found, call
234253 ).
235254
236255 is_meta(on_trace).
237
256 is_meta(trace_condition).
238257
239258 %! walk_clauses(+Clauses, +OTerm) is det.
240259 %
290309 ; walk_option_module_class(OTerm, Classes),
291310 source_file_property(File, module(MF))
292311 -> module_property(MF, class(Class)),
293 memberchk(Class, Classes)
312 memberchk(Class, Classes),
313 walk_option_module(OTerm, MF)
294314 ; true
295315 ).
296316
308328
309329 find_walk_from_module(M, OTerm) :-
310330 debug(autoload, 'Analysing module ~q', [M]),
331 walk_option_module(OTerm, M),
311332 forall(predicate_in_module(M, PI),
312333 walk_called_by_pred(M:PI, OTerm)).
313334
511532 ; predicate_property(Module:Goal, imported_from(M2)),
512533 subsumes_term(To, M2:Goal)
513534 ),
535 trace_condition(M2:Goal, TermPos, OTerm),
514536 print_reference(M2:Goal, TermPos, trace, OTerm),
515537 fail. % Continue search
516538 walk_called(Goal, Module, _, OTerm) :-
564586 undefined(Module:Goal, TermPos, OTerm).
565587 walk_called(Goal, _Module, TermPos, OTerm) :-
566588 not_callable(Goal, TermPos, OTerm).
589
590 %! trace_condition(:Callee, +TermPos, +OTerm) is semidet.
591 %
592 % Call call(Condition, Callee, Dict)
593
594 trace_condition(Callee, TermPos, OTerm) :-
595 walk_option_trace_condition(OTerm, Cond), nonvar(Cond),
596 !,
597 cond_location_context(OTerm, TermPos, Context0),
598 walk_option_caller(OTerm, Caller),
599 walk_option_module(OTerm, Module),
600 put_dict(#{caller:Caller, module:Module}, Context0, Context),
601 call(Cond, Callee, Context).
602 trace_condition(_, _, _).
603
604 cond_location_context(OTerm, _TermPos, Context) :-
605 walk_option_clause(OTerm, Clause), nonvar(Clause),
606 !,
607 Context = #{clause:Clause}.
608 cond_location_context(OTerm, _TermPos, Context) :-
609 walk_option_initialization(OTerm, Init), nonvar(Init),
610 !,
611 Context = #{initialization:Init}.
567612
568613 %! undecided(+Variable, +TermPos, +OTerm)
569614
891936 :- meta_predicate
892937 subterm_pos(+, +, 2, +, -),
893938 sublist_pos(+, +, +, +, 2, -).
939 :- public
940 subterm_pos/5. % used in library(check).
894941
895942 subterm_pos(_, _, _, Pos, _) :-
896943 var(Pos), !, fail.
12501250 xref_meta(thread_create(A,_,_), [A]).
12511251 xref_meta(thread_create(A,_), [A]).
12521252 xref_meta(thread_signal(_,A), [A]).
1253 xref_meta(thread_idle(A,_), [A]).
12531254 xref_meta(thread_at_exit(A), [A]).
12541255 xref_meta(thread_initialization(A), [A]).
12551256 xref_meta(engine_create(_,A,_), [A]).
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2013-2019, VU University Amsterdam
5 Copyright (c) 2013-2020, VU University Amsterdam
66 CWI, Amsterdam
77 All rights reserved.
88
3636 [ safe_goal/1, % :Goal
3737 safe_call/1 % :Goal
3838 ]).
39 :- autoload(library(apply),[maplist/2]).
40 :- autoload(library(assoc),[empty_assoc/1,get_assoc/3,put_assoc/4]).
41 :- autoload(library(debug),[debug/3,debugging/1]).
42 :- autoload(library(error),
43 [ must_be/2,
44 instantiation_error/1,
45 type_error/2,
46 permission_error/3
47 ]).
48 :- autoload(library(lists),[append/3]).
49 :- autoload(library(prolog_format),[format_types/2]).
5039 :- use_module(library(apply_macros),[expand_phrase/2]).
51
40 :- use_module(library(apply),[maplist/2]).
41 :- use_module(library(assoc),[empty_assoc/1,get_assoc/3,put_assoc/4]).
42 :- use_module(library(debug),[debug/3,debugging/1]).
43 :- use_module(library(error),
44 [ must_be/2,
45 instantiation_error/1,
46 type_error/2,
47 permission_error/3
48 ]).
49 :- use_module(library(lists),[append/3]).
50 :- use_module(library(prolog_format),[format_types/2]).
5251
5352 :- multifile
5453 safe_primitive/1, % Goal
133133 set(PLDOC_LIB ${PLDOC_LIB} PARENT_SCOPE)
134134 endfunction()
135135
136 has_package(ssl, HAVE_SSL_PACKAGE)
137 if(HAVE_SSL_PACKAGE)
138 set(doc_depends_ssl ssl)
139 endif()
140
136141 # Specify how to generate tex files from PlDoc
137142 # NOTE: all files must be included from lib/library.doc and
138143 # NOTE: lib/libsummary.doc
146151 libdoc(pure_input --subsection)
147152 libdoc(explain --subsection)
148153 pldoc(lib/prologpack.tex "library(prolog_pack)"
149 OPTIONS --section)
154 OPTIONS --section DEPENDS ${doc_depends_ssl})
150155 pldoc(lib/assoclib.tex lib/assoclib.md
151156 OPTIONS --lib=assoc --module=assoc
152157 DEPENDS lib/assoclib.md ../library/assoc.pl)
299304 endif()
300305
301306 install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Manual
302 DESTINATION ${SWIPL_INSTALL_PREFIX}/doc)
307 DESTINATION ${SWIPL_INSTALL_DOC})
303308 endif(INSTALL_DOCUMENTATION)
+0
-1
man/TODO less more
0 * Document use of plld for creating shared objects
15901590 \begin{description}
15911591 \predicate[ISO]{var}{1}{@Term}
15921592 True if \arg{Term} currently is a free variable.
1593
15931594 \predicate[ISO]{nonvar}{1}{@Term}
15941595 True if \arg{Term} currently is not a free variable.
1596
15951597 \predicate[ISO]{integer}{1}{@Term}
15961598 True if \arg{Term} is bound to an integer.
1599
15971600 \predicate[ISO]{float}{1}{@Term}
15981601 True if \arg{Term} is bound to a floating point number.
1602
15991603 \predicate{rational}{1}{@Term}
16001604 True if \arg{Term} is bound to a rational number. Rational numbers
16011605 include integers.
1606
16021607 \predicate{rational}{3}{@Term, -Numerator, -Denominator}
16031608 True if \arg{Term} is a rational number with given \arg{Numerator} and
16041609 \arg{Denominator}. The \arg{Numerator} and \arg{Denominator} are in
16051610 canonical form, which means \arg{Denominator} is a positive integer and
16061611 there are no common divisors between \arg{Numerator} and \arg{Denominator}.
1612
16071613 \predicate[ISO]{number}{1}{@Term}
1608 True if \arg{Term} is bound to an integer or floating point number.%
1609 \footnote{As rational numbers are not atomic in the current
1610 implementation and we do not want to break the rule
1611 that number/1 implies atomic/1, number/1 fails on
1612 rational numbers. This will change if rational numbers
1613 become atomic.}
1614 True if \arg{Term} is bound to a rational number (including integers) or
1615 a floating point number.
16141616
16151617 \predicate[ISO]{atom}{1}{@Term}
16161618 True if \arg{Term} is bound to an atom.
34973499 by trie_gen_compiled/2,3.
34983500 \termitem{hashed}{-Count}
34993501 Number of nodes that use a hashed index to its children.
3502 \termitem{lookup_count}{-Count}
3503 Number of trie_lookup/3 calls (only when compiled with
3504 \const{O_TRIE_STATS}).
3505 \termitem{gen_call_count}{-Count}
3506 Number of trie_gen/3 calls (only when compiled with
3507 \const{O_TRIE_STATS}).
3508 \termitem{wait}{-Count}
3509 Number of times a thread waited on this trie for another
3510 thread to complete it (shared tabling, only when compiled with
3511 \const{O_TRIE_STATS}).
3512 \termitem{deadlock}{-Count}
3513 Number of times this trie was part of a deadlock and its completion
3514 was abandonned (shared tabling, only when compiled with
3515 \const{O_TRIE_STATS}).
3516 \end{description}
3517
3518 In addition, a number of additional properties are defined on
3519 \jargon{answer tries}.
3520
3521 \begin{description}
3522 \termitem{invalidated}{-Count}
3523 Number of times the trie was invalidated (incremental tabling).
3524 \termitem{reevaluated}{-Count}
3525 Number of times the trie was re-evaluated (incremental tabling).
3526 \termitem{idg_affected_count}{-Count}
3527 Number of answer tries affected by this one (incremental tabling).
3528 \termitem{idg_dependent_count}{-Count}
3529 Number of answer tries this one depends on (incremental tabling).
3530 \termitem{idg_size}{-Bytes}
3531 Number of bytes in the IDG node representation.
35003532 \end{description}
35013533 \end{description}
35023534
40194051 \termitem{quasi_quotation_syntax}{}
40204052 The predicate (with arity~4) is declared to provide quasi quotation
40214053 syntax with quasi_quotation_syntax/1.
4054
4055 \termitem{size}{Bytes}
4056 Memory used for this predicate. This includes the memory of the
4057 predicate header, the combined memory of all clauses including erased
4058 but not yet garbage collected clauses (see garbage_collect_clauses/0 and
4059 clause_property/2) and the memory used by clause indexes (see the
4060 \term{indexed}{Indexes} property. \emph{Excluded} are \jargon{lingering}
4061 data structures. These are garbage data structures that have been
4062 detached from the predicate but cannot yet be reclaimed because
4063 they may be in use by some thread.
40224064
40234065 \termitem{static}{}
40244066 The definition can \emph{not} be modified using assertz/1 and friends.
998910031 agc_gained & Number of atoms removed \\
999010032 agc_time & Time spent in atom garbage collections \\
999110033 atoms & Total number of defined atoms \\
10034 atom_space & Bytes used to represent atoms \\
999210035 c_stack & System (C-) stack limit. 0 if not known. \\
999310036 cgc & Number of clause garbage collections performed \\
999410037 cgc_gained & Number of clauses reclaimed \\
999810041 cputime & (User) {\sc cpu} time since thread was started in seconds \\
999910042 epoch & Time stamp when thread was started \\
1000010043 functors & Total number of defined name/arity pairs \\
10044 functor_space & Bytes used to represent functors \\
1000110045 global & Allocated size of the global stack in bytes \\
1000210046 globalused & Number of bytes in use on the global stack \\
1000310047 globallimit & Size to which the global stack is allowed to grow \\
1003110075 threads_created & MT-version: number of created threads \\
1003210076 engines & MT-version: number of existing engines \\
1003310077 engines_created & MT-version: number of created engines \\
10078 threads_peak & MT-version: highest id handed out. This is a fair but
10079 possibly not 100\% accurate value for the highest
10080 number of threads since the process was created. \\
1003410081 \hline
1003510082 \end{tabular}
1003610083 \end{center}
1006010107 (Used is based on \const{ru_idrss} from getrusage().
1006110108 Free is based on \const{RLIMIT_DATA} from
1006210109 getrlimit(). Both are reported as zero if the OS
10063 lacks support.) \\
10110 lacks support. Free is -1 if getrlimit() is supported
10111 but returns infinity.) \\
1006410112 stacks & [ global use, local use ] \\
10065 program & [ heap, 0 ] \\
10113 program & [ heap use, 0 ] \\
1006610114 global_stack & [ global use, global free ] \\
1006710115 local_stack & [ local use, local free ] \\
1006810116 trail & [ trail use, trail free ] \\
1011210160
1011310161 \section{Memory Management} \label{sec:memory}
1011410162
10163 \subsection{Garbage collection} \label{sec:gc}
10164
1011510165 \begin{description}
1011610166 \predicate{garbage_collect}{0}{}
1011710167 Invoke the global and trail stack garbage collector. Normally the
1022410274
1022510275 The total space limit for all stacks is controlled using the prolog
1022610276 flag \prologflag{stack_limit}.
10277
10278 \subsection{Heap memory (malloc)} \label{sec:malloc}
10279
10280 \index{tcmalloc}%
10281 SWI-Prolog's memory management is based on the C runtime malloc()
10282 function and related functions. The characteristics of the malloc()
10283 implementation may affect performance and overall memory usage of the
10284 system. For most Prolog programs the performance impact of the allocator
10285 is small.\footnote{Multi-threaded applications may suffer from
10286 allocators that do not effectively avoid \jargon{false sharing} that
10287 affect CPU cache behaviour or operate using a single lock to provide
10288 thread safety. Such allocators should be rare in modern OSes.} The
10289 impact on total memory usage can be significant though, in particular
10290 for multi-threaded applications. This is due to two aspects of
10291 SWI-Prolog memory management:
10292
10293 \begin{itemize}
10294 \item The Prolog stacks are allocated using malloc(). The stacks can
10295 be extremely large. SWI-Prolog assumes malloc() will use a mechanism
10296 that allows returning this memory to the OS. Most todays allocators
10297 satisfy this requirement.
10298
10299 \item Atoms and clauses are allocated by the thread that requires
10300 them, but this memory is freed by the thread running the atom or
10301 clause garbage collector (see garbage_collect_atoms/0 and
10302 garbage_collect_clauses/0). Normally these run in the thread
10303 \const{gc}, which means that all deallocation happens in this
10304 thread. Notably the \href{http://www.malloc.de/en/}{ptmalloc}
10305 implementation used by the GNU C library (glibc) seems to handle
10306 this poorly.
10307 \end{itemize}
10308
10309 Starting with version 8.1.27, SWI-Prolog by default links against
10310 \href{https://github.com/google/tcmalloc}{tcmalloc} when available. Note
10311 that changing the allocator can only be done by linking the main
10312 executable (\program{swipl}) to an alternative library. When embedded
10313 (see \secref{embedded}) the main program that embeds \file{libswipl}
10314 must be linked with tcmalloc. On ELF based systems (Linux), this effect
10315 can also be achieved using the environment variable \const{LD_PRELOAD}:
10316
10317 \begin{code}
10318 % LD_PRELOAD=/path/to/libtcmalloc.so swipl ...
10319 \end{code}
10320
10321 If SWI-Prolog core detects that tcmalloc is the current allocator and
10322 provides the following additional predicates.
10323
10324 \begin{description}
10325 \predicate[nondet]{malloc_property}{1}{?Property}
10326 True when \arg{Property} is a property of the current allocator. The
10327 properties are defined by the allocator. The properties of tcmalloc
10328 are defined in
10329 \file{gperftools/malloc_extension.h}:\footnote{Documentation copied from
10330 the header.}
10331
10332 \begin{description}
10333 \termitem{'generic.current_allocated_bytes'}{-Int}
10334 Number of bytes currently allocated by application.
10335 \termitem{'generic.heap_size'}{-Int}
10336 Number of bytes in the heap (= current_allocated_bytes + fragmentation
10337 + freed memory regions).
10338 \termitem{'tcmalloc.max_total_thread_cache_bytes'}{-Int}
10339 Upper limit on total number of bytes stored across allper-thread caches.
10340 \termitem{'tcmalloc.current_total_thread_cache_bytes'}{-Int}
10341 Number of bytes used across all thread caches.
10342 \termitem{'tcmalloc.central_cache_free_bytes'}{-Int}
10343 Number of free bytes in the central cache that have been
10344 assigned to size classes. They always count towards virtual
10345 memory usage, and unless the underlying memory is swapped out
10346 by the OS, they also count towards physical memory usage.
10347 \termitem{'tcmalloc.transfer_cache_free_bytes'}{-Int}
10348 Number of free bytes that are waiting to be transfered between
10349 the central cache and a thread cache. They always count
10350 towards virtual memory usage, and unless the underlying memory
10351 is swapped out by the OS, they also count towards physical
10352 \termitem{'tcmalloc.thread_cache_free_bytes'}{-Int}
10353 Number of free bytes in thread caches. They always count
10354 towards virtual memory usage, and unless the underlying memory
10355 is swapped out by the OS, they also count towards physical
10356 memory usage.
10357 \termitem{'tcmalloc.pageheap_free_bytes'}{-Int}
10358 Number of bytes in free, mapped pages in page heap. These
10359 bytes can be used to fulfill allocation requests. They
10360 always count towards virtual memory usage, and unless the
10361 underlying memory is swapped out by the OS, they also count
10362 towards physical memory usage. This property is not writable.
10363 \termitem{'tcmalloc.pageheap_unmapped_bytes'}{-Int}
10364 Number of bytes in free, unmapped pages in page heap.
10365 These are bytes that have been released back to the OS,
10366 possibly by one of the MallocExtension "Release" calls.
10367 They can be used to fulfill allocation requests, but
10368 typically incur a page fault. They always count towards
10369 virtual memory usage, and depending on the OS, typically
10370 do not count towards physical memory usage.
10371 \end{description}
10372
10373 \predicate[det]{set_malloc}{1}{+Property}
10374 Set properties described in malloc_property/1. Currently
10375 the only writable property is
10376 \const{tcmalloc.max_total_thread_cache_bytes}. Setting an unknown
10377 property raises a \const{domain_error} and setting a read-only property
10378 raises a \const{permission_error} exception.
10379
10380 \predicate[semidet]{thread_idle}{2}{:Goal, +Duration}
10381 Indicates to the system that the calling thread will idle for some time
10382 while calling \arg{Goal} as once/1. This call releases resources to the
10383 OS to minimise the footprint of the calling thread while it waits.
10384 Despite the name this predicate is always provided, also if the system
10385 is not configured with tcmalloc or is single threaded.
10386 \arg{Duration} is one of
10387
10388 \begin{description}
10389 \termitem{short}{}
10390 Calls trim_stacks/0 and, if tcmalloc is used, calls
10391 MallocExtension_MarkThreadTemporarilyIdle() which empties the thread's
10392 malloc cache but preserves the cache itself.
10393
10394 \termitem{long}{}
10395 Calls garbage_collect/0 and trim_stacks/0 and, if tcmalloc is used,
10396 calls MallocExtension_MarkThreadIdle() which releases all
10397 thread-specific allocation datastructures.
10398 \end{description}
10399 \end{description}
1022710400
1022810401
1022910402 \section{Windows DDE interface} \label{sec:DDE}
+0
-183
man/doc2tex less more
0 #!/usr/bin/env perl
1
2 sub printTeX
3 { s/`([@\w]+)\s*<->([a-z]\w*)/\\index\{\l\1,\\both\{\2\}\}`\\classboth\{\1\}\{\2\}/g;
4 s/`([@\w]+)\s*<-([a-z]\w*)/\\index\{\l\1,\\get\{\2\}\}`\\classget\{\1\}\{\2\}/g;
5 s/`([@\w]+)\s*->([a-z]\w*)/\\index\{\l\1,\\send\{\2\}\}`\\classsend\{\1\}\{\2\}/g;
6 s/<->([a-z]\w*)/\\both\{\1\}/g;
7 s/<-([a-z]\w*)/\\get\{\1\}/g;
8 s/->([a-z]\w*)/\\send\{\1\}/g;
9 s/(^|\s|\()([a-z]\w+)\/((\d+|\[\d+(-|,)\d+\]))/\1\\index\{\2\/\3\}\\predref\{\2\}\{\3\}/g;
10 s/(\s+|^)([a-z]\w+)\/\/((\d+|\[\d+(-|,)\d+\]))/\1\\index\{\2\/\/\3\}\\dcgref\{\2\}\{\3\}/g;
11 s/(\w\.\w)\.(\s+[a-z])/\1.\\\2/g;
12 s/(^|[^'"\$])<(\w[-~a-z]*\w)>/\1\\bnfmeta\{\2\}/g;
13 s/\\class\{([<\\=>]*)\}/\\verb!\1!/g;
14 s/==>/\$\\longrightarrow\$/g;
15 s/^((\\index\{[^\}]+\})+) *$/\1%/;
16 s/(\\index\{[^\}]*)\\index\{[^\}]*\}([^\}]*\})/\1\2/g;
17 s/(\\class(get|send|both)\{)\\index\{[^\}]*\}/\1/g;
18 s/(PL_[a-z_0-9]*)\(([^\)]*)\)/\\cfuncref\{\1\}\{\2\}/g;
19
20 # Prolog special arguments ...
21 # TBD: pick these up automatically from pl.sty
22
23 s/\\file\{([^\}]*\\bnfmeta[^\}]*)\}/\\metafile\{\1\}/g;
24 s/\\file\{([^\}]*\\arg[^\}]*)\}/\\metafile\{\1\}/g;
25 s/\\file\{([^\}]+)\}/\\file@\1@/g;
26 s/\\htmloutput\{([^\}]+)\}/\\htmloutput@\1@/g;
27
28 s/\{#!\}/\{\\Sexe\}/g;
29 s/\{#>\}/\{\\Scgt\}/g;
30 s/\{#>=\}/\{\\Scge\}/g;
31 s/\{#<\}/\{\\Sclt\}/g;
32 s/\{#=<\}/\{\\Scle\}/g;
33 s/\{#=\}/\{\\Sceq\}/g;
34 s/\{#\\=\}/\{\\Scne\}/g;
35 s/\{#\\\}/\{\\Snot\}/g;
36 s/\{#\\\/\}/\{\\Sor\}/g;
37 s/\{#\/\\\}/\{\\Sand\}/g;
38 s/\{#<=>\}/\{\\Sequiv\}/g;
39 s/\{#<=\}/\{\\Slimpl\}/g;
40 s/\{#=>\}/\{\\Srimpl\}/g;
41 s/\{#<==\}/\{\\Slimplies\}/g;
42 s/\{#==>\}/\{\\Srimplies\}/g;
43 s/\{#<==>\}/\{\\Scequal\}/g;
44 s/\{#=\\=\}/\{\\Scine\}/g;
45 s/\{#=:=\}/\{\\Scieq\}/g;
46 s/\{#\}/\{\\Shash\}/g;
47 s/\{!\}/\{\\Scut\}/g;
48 s/\{,\}/\{\\Scomma\}/g;
49 s/\{->\}/\{\\Sifthen\}/g;
50 s/\{\*->\}/\{\\Ssoftcut\}/g;
51 s/\{\.\}/\{\\Sdot\}/g;
52 s/\{;\}/\{\\Ssemicolon\}/g;
53 s/\{<\}/\{\\Slt\}/g;
54 s/\{><\}/\{\\Sxor\}/g;
55 s/\{=\}/\{\\Seq\}/g;
56 s/\{=\.\.\}/\{\\Suniv\}/g;
57 s/\{=:=\}/\{\\Saeq\}/g;
58 s/\{=<\}/\{\\Sle\}/g;
59 s/\{<=\}/\{\\Sel\}/g;
60 s/\{==\}/\{\\Sequal\}/g;
61 s/\{=@=\}/\{\\Sstructeq\}/g;
62 s/\{\\=@=\}/\{\\Sstructneq\}/g;
63 s/\{=\\=\}/\{\\Sane\}/g;
64 s/\{>\}/\{\\Sgt\}/g;
65 s/\{>=\}/\{\\Sge\}/g;
66 s/\{>=<\}/\{\\Seqbowtie\}/g;
67 s/\{>:<\}/\{\\Smappunify\}/g;
68 s/\{:<\}/\{\\Smapselect\}/g;
69 s/\{@<\}/\{\\Stlt\}/g;
70 s/\{@=<\}/\{\\Stle\}/g;
71 s/\{@>\}/\{\\Stgt\}/g;
72 s/\{@>=\}/\{\\Stge\}/g;
73 s/\{\\\+\}/\{\\Snot\}/g;
74 s/\{\\=\}/\{\\Sne\}/g;
75 s/\{\\==\}/\{\\Snequal\}/g;
76 s/\{\^\}/\{\\Shat\}/g;
77 s/\{\|\}/\{\\Sbar\}/g;
78 s/\{\*\}/\{\\Stimes\}/g;
79 s/\{\*\*\}/\{\\Spow\}/g;
80 s/\{\+\}/\{\\Splus\}/g;
81 s/\{-\}/\{\\Sminus\}/g;
82 s/\{\/\}/\{\\Sdiv\}/g;
83 s/\{\/\/\}/\{\\Sidiv\}/g;
84 s/\{\/\\\}/\{\\Sand\}/g;
85 s/\{<<\}/\{\\Slshift\}/g;
86 s/\{>>\}/\{\\Srshift\}/g;
87 s/\{\\\}/\{\\Sneg\}/g;
88 s/\{\\\/\}/\{\\Sor\}/g;
89 s/\{\$\}/\{\\Sdollar\}/g;
90 s/\{\?\}/\{\\Squest\}/g;
91 s/\{:\}/\{\\Smodule\}/g;
92 s/\{:-\}/\{\\Sneck\}/g;
93 s/\{\?-\}/\{\\Sdirective\}/g;
94 s/\{-->\}/\{\\Sdcg\}/g;
95 s/\{~\}/\{\\Stilde\}/g;
96 s/\{%\}/\{\\Spercent\}/g;
97 s/\{\{\}\}/\{\\Scurl\}/g;
98 s/\{\[\|\]\}/\{\\Scons\}/g;
99 s/\{xXX..\\\}/\{\\SxXX\}/g;
100
101 s/\\file@([^@]+)@/\\file\{\1\}/g;
102 s/\\htmloutput@([^@]+)@/\\htmloutput\{\1\}/g;
103
104 print;
105 }
106
107
108 sub expandTabs
109 { while ( ($i = index($_, "\t")) != $[-1 )
110 { $nspaces = 8 - $i % 8;
111 for( $spaces="", $i=0; $i<$nspaces; $i++ )
112 { $spaces .= " ";
113 }
114 s/\t/$spaces/;
115 }
116 }
117
118
119 sub
120 expandSpecials
121 { s/\^/\\verb!^!/g;
122 s/\|/\\verb!|!/g;
123 }
124
125
126 sub printCode
127 { print;
128 while (<ARGV> )
129 { &expandTabs;
130 print;
131 if ( /\\end\{(code|verbatim)\}/ )
132 { return;
133 }
134 }
135 }
136
137
138 sub printPceCode
139 { $line = 0;
140 print;
141 while (<ARGV> )
142 { $line++;
143 &expandTabs;
144 if ( /\\end\{pcecode\}/ )
145 { print;
146 return;
147 }
148 chomp;
149 print "\\lineno{$line}\\verb`$_`\n";
150 }
151 }
152
153
154 sub skiptonext
155 { while (<ARGV>)
156 { if ( ! /^\s*$/ )
157 { return;
158 }
159 last;
160 }
161 while (<ARGV>)
162 { if ( ! /^\s*$/ )
163 { return;
164 }
165 }
166 }
167
168 # MAIN PROGRAM
169
170 while (<>)
171 { while ( /\\begin\{pcecode\}/ )
172 { &printPceCode;
173 print "\n\\noindent\n";
174 &skiptonext;
175 }
176 while ( /\\begin\{(code|verbatim)\}/ )
177 { &printCode;
178 print "\n\\noindent\n";
179 &skiptonext;
180 }
181 &printTeX;
182 }
33973397 \cfunction{int}{PL_initialise}{int argc, char **argv}
33983398 Initialises the SWI-Prolog heap and stacks, restores the Prolog
33993399 state, loads the system and personal initialisation files,
3400 runs the initialization/1 hooks and finally runs the
3401 \argoption{-g}{goal} hook.
3400 runs the initialization/1 hooks and finally runs the initialization
3401 goals registered using \argoption{-g}{goal}.
34023402
34033403 Special consideration is required for \verb$argv[0]$. On {\bf Unix},
34043404 this argument passes the part of the command line that is used
34053405 to locate the executable. Prolog uses this to find the file holding
34063406 the running executable. The {\bf Windows} version uses this to find
34073407 a \jargon{module} of the running executable. If the specified module
3408 cannot be found, it tries the module \const{libpl.dll}, containing
3408 cannot be found, it tries the module \const{libswipl.dll}, containing
34093409 the Prolog runtime kernel. In all these cases, the resulting file is
34103410 used for two purposes:
34113411
34513451
34523452 A good setup in Windows is to add SWI-Prolog's \file{bin} directory
34533453 to your \env{PATH} and either pass a module holding a saved state, or
3454 \verb$"libpl.dll"$ as \verb$argv[0]$. If the Prolog state is attached
3455 to a DLL (see the \cmdlineoption{-dll} option of \program{swipl-ld}), pass
3456 the name of this DLL.
3454 \verb$"libswipl.dll"$ as \verb$argv[0]$. If the Prolog state is attached
3455 to a DLL (see the \cmdlineoption{-dll} option of \program{swipl-ld}),
3456 pass the name of this DLL.
34573457
34583458 \cfunction{int}{PL_is_initialised}{int *argc, char ***argv}
34593459 Test whether the Prolog engine is already initialised. Returns
5858
5959 \newcommand{\vmajor}{8}
6060 \newcommand{\vminor}{1}
61 \newcommand{\vpatch}{26}
61 \newcommand{\vpatch}{28}
6262 \newcommand{\vtag}{}
63 \newcommand{\vmonth}{March}
63 \newcommand{\vmonth}{April}
6464 \newcommand{\vyear}{2020}
6565
6666 #ifdef BOOK
829829 True if \arg{Module} exports the given operators. Each exported
830830 operator is represented as a term \term{op}{Pri,Assoc,Name}.
831831 Succeeds with an empty list if the module exports no operators.
832 \termitem{size}{-Bytes}
833 Total size in bytes used to represent the module. This includes
834 the module itself, its (hash) tables and the summed size of
835 all predicates defined in this module. See also
836 the \term{size}{Bytes} property in predicate_property/2.
832837 \termitem{program_size}{-Bytes}
833838 Memory (in bytes) used for storing the predicates of this
834839 module. This figure includes the predicate header and clauses.
835 Future versions might give a more precise number, including
836 e.g., the clause index tables.
837840 \termitem{program_space}{-Bytes}
838841 If present, this number limits the \const{program_size}. See
839842 set_module/1.
16041604 \prologflag{readline}) and 15 otherwise.
16051605
16061606 \prologflagitem{home}{atom}{r}
1607 SWI-Prolog's notion of the home directory. SWI-Prolog uses its home
1608 directory to find its startup file as
1609 \file{<home>/boot32.prc} (32-bit machines) or
1610 \file{<home>/boot64.prc} (64-bit machines) and to find its library as
1611 \file{<home>/library}.
1607 SWI-Prolog's notion of the home directory. SWI-Prolog uses its home
1608 directory to find its startup file as \file{<home>/boot.prc} and to find
1609 its library as \file{<home>/library}. Some installations may put
1610 architecture independent files in a \jargon{shared home} and also
1611 define \prologflag{shared_home}. System files can be found using
1612 absolute_file_name/3 as \term{swi}{file}. See file_search_path/2.
16121613
16131614 \prologflagitem{hwnd}{integer}{r}
16141615 In \program{swipl-win.exe}, this refers to the MS-Windows window handle of
19461947 \prologflagitem{saved_program}{bool}{r}
19471948 If present and \const{true}, Prolog has been started from a state saved
19481949 with qsave_program/[1,2].
1950
1951 \prologflagitem{shared_home}{atom}{r}
1952 Indicates that part of the SWI-Prolog system files are installed in
1953 \file{<prefix>/share/swipl} instead of in the home at the
1954 \file{<prefix>/lib/swipl}. This flag indicates the location of this
1955 \emph{shared home} and the directory is added to the file seach path
1956 \const{swi}. See file_search_path/2 and the flag \prologflag{home}.
19491957
19501958 \prologflagitem{shared_object_extension}{atom}{r}
19511959 Extension used by the operating system for shared objects. \fileext{so}
25532561 \end{description}
25542562
25552563
2556
2557 \section{Garbage Collection} \label{sec:gc}
2558
2559 SWI-Prolog provides garbage collection, last-call optimization and atom
2560 garbage collection. These features are controlled using Prolog flags
2561 (see current_prolog_flag/2).
2562
2563
2564 \section{The SWI-Prolog syntax} \label{sec:syntax}
2564 \section{The SWI-Prolog syntax} \label{sec:syntax}
25652565
25662566 SWI-Prolog syntax is close to ISO-Prolog standard syntax, which is based
25672567 on the Edinburgh Prolog syntax. A formal description can be found in the
4848 :- initialization(clean_pldoc, prepare_state).
4949
5050 pltotex(File, Options) :-
51 set_prolog_flag(pldoc_to_tex, true),
5152 markdown_file(File),
5253 !,
5354 preload(Options),
5758 summaries(Out, LatexOptions, LatexOptions0),
5859 doc_latex(MarkDown, Out, LatexOptions).
5960 pltotex(Lib, Options) :-
61 set_prolog_flag(pldoc_to_tex, true),
6062 ( file_name_extension(_, pl, Lib)
6163 -> Spec = Lib
6264 ; atom_to_term(Lib, Spec, _)
+0
-19
man/replaceall less more
0 #!/bin/bash -f
1
2 from="$1"
3 to="$2"
4
5 if [ -z "$from" ]; then
6 echo "Usage: $0 from to"
7 fi
8
9 files=`find . -name '*.[ch]' | xargs grep -l "$1"`
10 for f in $files; do
11 cp -p $f $f.bak
12 sed "s|$1|$2|g" $f.bak > $f
13 if cmp -s $f.bak $f; then
14 mv $f.bak $f # no change
15 else
16 echo " modified $f"
17 fi
18 done
410410 atoms} \predicatesummary{make}{0}{Reconsult all changed source files}
411411 \predicatesummary{make_directory}{1}{Create a folder on the file system}
412412 \predicatesummary{make_library_index}{1}{Create autoload file INDEX.pl}
413 \predicatesummary{make_library_index}{2}{Create selective autoload file
414 INDEX.pl} \predicatesummary{map_assoc}{2}{Map association tree}
413 \predicatesummary{malloc_property}{1}{Property of the allocator}
414 \predicatesummary{make_library_index}{2}{Create selective autoload file INDEX.pl} \predicatesummary{map_assoc}{2}{Map association tree}
415415 \predicatesummary{map_assoc}{3}{Map association tree}
416416 \predicatesummary{dict_create}{3}{Create a dict from data}
417417 \predicatesummary{dict_pairs}{3}{Convert between dict and list of pairs}
629629 open file} \predicatesummary{set_flag}{2}{Set value of a flag}
630630 \predicatesummary{set_input}{1}{Set current input stream from a stream}
631631 \predicatesummary{set_locale}{1}{Set the default local}
632 \predicatesummary{set_malloc}{1}{Set memory allocator property}
632633 \predicatesummary{set_module}{1}{Set properties of a module}
633634 \predicatesummary{set_output}{1}{Set current output stream from a
634635 stream} \predicatesummary{set_prolog_IO}{3}{Prepare streams for
713714 \predicatesummary{thread_get_message}{1}{Wait for message}
714715 \predicatesummary{thread_get_message}{2}{Wait for message in a queue}
715716 \predicatesummary{thread_get_message}{3}{Wait for message in a queue}
717 \predicatesummary{thread_idle}{2}{Reduce footprint while waiting}
716718 \predicatesummary{thread_initialization}{1}{Run action at start of thread}
717719 \predicatesummary{thread_join}{1}{Wait for Prolog task-completion}
718720 \predicatesummary{thread_join}{2}{Wait for Prolog task-completion}
359359 If the thread is an engine that is currently attached to a thread,
360360 \arg{ThreadId} is the thread that executes the engine.
361361
362 \termitem{size}{Bytes}
363 The amount of memory associated with this thread. This includes the
364 thread structure, its stacks, its default message queue, its clauses
365 in its thread local dynamic predicates (see thread_local/1) and memory
366 used for representing thread-local answer tries (see \secref{tabling}).
367
362368 \termitem{system_thread_id}{Integer}
363369 Thread identifier used by the operating system for the calling thread.
364370 Not available on all OSes. This is the same as the Prolog flag
6464 install_dll(${LibArchive_LIBRARIES})
6565
6666 pkg_doc(archive
67 SOURCE archive.pl archive4pl.tex)
67 SOURCE archive.pl archive4pl.tex
68 DEPENDS archive)
6869
6970 endif(LibArchive_FOUND)
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2015, University of Amsterdam
6 VU University Amsterdam
5 Copyright (c) 2015-2020, University of Amsterdam
6 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
158159 }
159160
160161 static int bdb_close_env(dbenvh *env, int silent);
161
162 static int bdb_close(dbh *db);
162163
163164 /*******************************
164165 * DB_ENV SYMBOL WRAPPER *
743744 dbh->env = env;
744745 NOSIG(rval=db_create(&dbh->db, env->env, 0));
745746 if ( rval )
747 { dbh->db = NULL;
748 dbh->symbol = 0;
746749 return db_status(rval, file);
750 }
747751
748752 DEBUG(Sdprintf("New DB at %p\n", dbh->db));
749753
750754 if ( !db_options(options, dbh, &subdb) )
751 { dbh->db->close(dbh->db, 0);
755 { bdb_close(dbh);
752756 return FALSE;
753757 }
754758
761765 #endif
762766
763767 if ( rval )
764 { dbh->db->close(dbh->db, 0);
768 { bdb_close(dbh);
765769 return db_status_db(rval, dbh);
766770 }
767771
768772 return unify_db(handle, dbh);
773 }
774
775
776 static int
777 bdb_close(dbh *db)
778 { int rval;
779
780 DEBUG(Sdprintf("Close DB at %p\n", db->db));
781 NOSIG(rval = db->db->close(db->db, 0);
782 db->db = NULL;
783 db->symbol = 0);
784
785 return rval;
769786 }
770787
771788
774791 { dbh *db;
775792
776793 if ( get_db(handle, &db) )
777 { int rval;
778
779 DEBUG(Sdprintf("Close DB at %p\n", db->db));
780 NOSIG(rval = db->db->close(db->db, 0);
781 db->db = NULL;
782 db->symbol = 0);
783
784 return db_status(rval, handle);
794 { if ( !db->db || !db->symbol )
795 return PL_existence_error("db", handle);
796 return db_status(bdb_close(db), handle);
785797 }
786798
787799 return FALSE;
795807 if ( PL_get_blob(t, &data, NULL, &type) && type == &db_blob)
796808 { dbh *p = data;
797809
798 if ( p->symbol )
810 if ( p->db && p->symbol )
799811 return TRUE;
800812
801813 return FALSE;
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2015, VU University Amsterdam
5 Copyright (c) 2015-2020, VU University Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
7071
7172 :- begin_tests(bdb).
7273
73 test(loop, PairsOut =@= PairsIn) :-
74 DBFile = 'test.db',
74 :- multifile user:file_search_path/1.
75 user:file_search_path(test_tmp_dir, '.').
76
77 tmp_output(Base, File) :-
78 absolute_file_name(test_tmp_dir(Base),
79 File,
80 [ access(write)
81 ]).
82
83 test(loop,
84 [ setup(tmp_output('test.db', DBFile)),
85 cleanup(delete_existing_file(DBFile)),
86 PairsOut =@= PairsIn
87 ]) :-
7588 delete_existing_file(DBFile),
7689 setof(Type-Data, data(Type, Data), PairsIn),
7790 bdb_open(DBFile, update, DB, []),
7891 forall(member(Type-Data, PairsIn),
7992 bdb_put(DB, Type, Data)),
8093 setof(Type-Data, bdb_enum(DB, Type, Data), PairsOut),
81 bdb_close(DB),
82 delete_existing_file(DBFile).
83 test(no_duplicates, Mies == mies) :-
84 DBFile = 'test.db',
94 bdb_close(DB).
95 test(no_duplicates,
96 [ setup(tmp_output('test.db', DBFile)),
97 cleanup(delete_existing_file(DBFile)),
98 Mies == mies
99 ]) :-
85100 delete_existing_file(DBFile),
86101 bdb_open(DBFile, update, DB, [duplicates(false)]),
87102 bdb_put(DB, aap, noot),
88103 bdb_put(DB, aap, mies),
89104 bdb_get(DB, aap, Mies),
90 bdb_close(DB),
91 delete_existing_file(DBFile).
92 test(duplicates, Out == [1,2,3,4,5,6,7,8,9,10]) :-
93 DBFile = 'test.db',
105 bdb_close(DB).
106 test(duplicates,
107 [ setup(tmp_output('test.db', DBFile)),
108 cleanup(delete_existing_file(DBFile)),
109 Out == [1,2,3,4,5,6,7,8,9,10]
110 ]) :-
94111 delete_existing_file(DBFile),
95112 bdb_open(DBFile, update, DB, [duplicates(true)]),
96113 forall(between(1, 10, X),
97114 forall(between(1, 10, Y),
98115 bdb_put(DB, X, Y))),
99116 bdb_getall(DB, 5, Out),
100 bdb_close(DB),
101 delete_existing_file(DBFile).
117 bdb_close(DB).
102118
103119 :- end_tests(bdb).
9696 ################
9797 # Tests
9898
99 test_libs(cgi crypt memfile process readutil socket stream time uri)
99 test_libs(cgi crypt memfile process readutil socket af_unix stream time uri)
100100
101101 ################
102102 # Documentation
6666 \InputIfFileExists{uid.tex}{}{}
6767 \InputIfFileExists{syslog.tex}{}{}
6868 \input{socket.tex}
69
70 \subsection{Unix domain sockets}
71 \label{sec:af-unix-sockets}
72
73 Unix domain sockets (sockets with address family AF_UNIX) are
74 represented as a (socket) file in the file system. They can only be used
75 to connect processes on the same host. The main advantage of AF_UNIX
76 sockets is that name conflicts are much easier to manage than port
77 conflicts and that access is determined by the file system permission
78 rules.
79
80 \begin{description}
81 \predicate{unix_domain_socket}{1}{-Socket}
82 Creates an AF_UNIX-domain stream-socket and unifies an identifier to
83 it with \arg{Socket}. This predicate does not exist if the OS does
84 not support the AF_UNIX address family (e.g. MS-Windows).
85
86 Unix domain socket affect tcp_connect/2 (for clients) and tcp_bind/2 and
87 tcp_accept/3 (for servers). The address is an atom or string that is
88 handled as a file name. On most systems the length of this file name is
89 limited to 128 bytes (including null terminator), but according to the
90 Linux documentation (unix(7)), portable applications must keep the
91 address below 92 bytes. Note that these lengths are in \emph{bytes}.
92 Non-ascii characters may be represented as multiple bytes. If the length
93 limit is exceeded a \term{representation_error}{af_unix_name} exception
94 is raised.
95 \end{description}
6996
7097 \subsection{UDP protocol support}
7198 \label{sec:udp-sockets}
5151 #cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@
5252 #cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
5353 #cmakedefine HAVE_SYS_WAIT_H @HAVE_SYS_WAIT_H@
54 #cmakedefine HAVE_SYS_UN_H @HAVE_SYS_UN_H@
5455 #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@
5556 #cmakedefine HAVE_UTIME @HAVE_UTIME@
5657 #cmakedefine HAVE_UTIME_H @HAVE_UTIME_H@
11 Author: Jan Wielemaker
22 E-mail: J.Wielemaker@vu.nl
33 WWW: http://www.swi-prolog.org
4 Copyright (c) 2004-2018, University of Amsterdam
4 Copyright (c) 2004-2020, University of Amsterdam
55 VU University Amsterdam
66 CWI, Amsterdam
77 All rights reserved.
178178 { int magic; /* PLSOCK_MAGIC */
179179 SOCKET socket; /* The OS socket */
180180 int flags; /* Misc flags */
181 int domain; /* AF_* */
181182 atom_t symbol; /* <socket>(%p) */
182183 IOSTREAM * input; /* input stream */
183184 IOSTREAM * output; /* output stream */
516517 int
517518 is_nbio_socket(nbio_sock_t socket)
518519 { return socket && socket->magic == PLSOCK_MAGIC;
520 }
521
522 int
523 nbio_domain(nbio_sock_t socket)
524 { return socket->domain;
519525 }
520526
521527 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
856862 { closesocket(sock);
857863 return NULL;
858864 }
865 s->domain = domain;
859866 #ifdef __WINDOWS__
860867 /* On older versions of Windows (win7 and before) the default send
861868 buffer size is only 8k. On a high latency link this can seriously
168168
169169 extern int nbio_wait(nbio_sock_t socket, nbio_request);
170170 extern SOCKET nbio_fd(nbio_sock_t socket);
171 extern int nbio_domain(nbio_sock_t socket);
171172
172173 extern int nbio_unify_ip4(term_t ip4, unsigned long hip);
173174 extern int nbio_get_ip(term_t ip4, struct in_addr *ip);
17751775 if ( info->envp )
17761776 { execve(info->exe, info->argv, info->envp);
17771777 } else
1778 { extern char **environ;
1779
1778 {
1779 #ifdef HAVE__NSGETENVIRON
1780 char **environ = *_NSGetEnviron();
1781 #else
1782 extern char **environ;
1783 #endif
17801784 execve(info->exe, info->argv, environ);
17811785 }
17821786
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2000-2018, University of Amsterdam
5 Copyright (c) 2000-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
7272 #else
7373 #define GET_ERRNO errno
7474 #define GET_H_ERRNO h_errno
75 #endif
76
77 #ifdef HAVE_SYS_UN_H
78 #include <sys/un.h>
79 #else
80 /* Windows does not have the header, but does have AF_UNIX? */
81 #undef AF_UNIX
7582 #endif
7683
7784 #if !defined(HAVE_IP_MREQN) && defined(__APPLE__)
95102 static atom_t ATOM_ip_add_membership; /* "ip_add_membership" */
96103 static atom_t ATOM_ip_drop_membership; /* "ip_drop_membership" */
97104 static atom_t ATOM_sndbuf; /* "sndbuf" */
105 static atom_t ATOM_af_unix; /* "af_unix" */
98106 static functor_t FUNCTOR_socket1; /* $socket(Id) */
99107
100108 static int get_socket_from_stream(term_t t, IOSTREAM **s, nbio_sock_t *sp);
544552
545553
546554 static foreign_t
547 create_socket(term_t socket, int type)
555 create_socket(int domain, term_t socket, int type)
548556 { nbio_sock_t sock;
549557
550 if ( !(sock = nbio_socket(AF_INET, type, 0)) )
558 if ( !(sock = nbio_socket(domain, type, 0)) )
551559 return FALSE;
552560
553561 return tcp_unify_socket(socket, sock);
556564
557565 static foreign_t
558566 tcp_socket(term_t socket)
559 { return create_socket(socket, SOCK_STREAM);
567 { return create_socket(AF_INET, socket, SOCK_STREAM);
560568 }
561569
562570
563571 static foreign_t
564572 udp_socket(term_t socket)
565 { return create_socket(socket, SOCK_DGRAM);
566 }
567
573 { return create_socket(AF_INET, socket, SOCK_DGRAM);
574 }
575
576
577 #ifdef AF_UNIX
578 static foreign_t
579 unix_domain_socket(term_t socket)
580 { return create_socket(AF_UNIX, socket, SOCK_STREAM);
581 }
582
583 static int
584 af_unix_address(term_t Address,
585 struct sockaddr_un *sockaddr, int *addrlen,
586 int flags)
587 { char *file_name_chars;
588 int nmlen;
589
590 if ( !PL_get_file_name(Address, &file_name_chars,
591 PL_FILE_OSPATH|flags) )
592 return FALSE;
593 nmlen = strlen(file_name_chars);
594 if ( nmlen >= sizeof(sockaddr->sun_path) )
595 { PL_representation_error("af_unix_name");
596 return FALSE;
597 }
598
599 memset(sockaddr, 0, sizeof(*sockaddr));
600 sockaddr->sun_family = AF_UNIX;
601 memcpy(sockaddr->sun_path, file_name_chars, nmlen);
602 *addrlen = offsetof(struct sockaddr_un, sun_path) + nmlen + 1;
603
604 return TRUE;
605 }
606
607 #endif /*AF_UNIX*/
608
609 static int
610 af_unix_connect(nbio_sock_t sock, term_t Address)
611 {
612 #ifdef AF_UNIX
613 if ( nbio_domain(sock) == AF_UNIX )
614 { struct sockaddr_un sockaddr;
615 int addrlen;
616
617 return ( af_unix_address(Address, &sockaddr, &addrlen, PL_FILE_READ) &&
618 nbio_connect(sock, (struct sockaddr *)&sockaddr, addrlen) == 0 );
619 } else
620 #endif
621 { return -1;
622 }
623 }
624
625 static int
626 af_unix_bind(nbio_sock_t sock, term_t Address)
627 {
628 #ifdef AF_UNIX
629 if ( nbio_domain(sock) == AF_UNIX )
630 { struct sockaddr_un sockaddr;
631 int addrlen;
632
633 return ( af_unix_address(Address, &sockaddr, &addrlen, 0) &&
634 nbio_bind(sock, (struct sockaddr *)&sockaddr, addrlen) == 0 );
635 } else
636 #endif
637 { return -1;
638 }
639 }
568640
569641 static foreign_t
570642 pl_connect(term_t Socket, term_t Address)
571643 { nbio_sock_t sock;
572644 struct sockaddr_in sockaddr;
573
574 if ( !tcp_get_socket(Socket, &sock) ||
575 !nbio_get_sockaddr(Address, &sockaddr, NULL) )
645 int rc;
646
647 if ( !tcp_get_socket(Socket, &sock) )
648 return FALSE;
649
650 if ( (rc=af_unix_connect(sock, Address)) != -1 )
651 return rc;
652
653 if ( !nbio_get_sockaddr(Address, &sockaddr, NULL) )
576654 return FALSE;
577655
578656 if ( nbio_connect(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == 0 )
584662
585663 static foreign_t
586664 pl_bind(term_t Socket, term_t Address)
587 { struct sockaddr_in sockaddr;
588 nbio_sock_t socket;
589 term_t varport = 0;
590
591 memset(&sockaddr, 0, sizeof(sockaddr));
592
593 if ( !tcp_get_socket(Socket, &socket) ||
594 !nbio_get_sockaddr(Address, &sockaddr, &varport) )
595 return FALSE;
596
597 if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0 )
598 return FALSE;
599
600 if ( varport )
601 { SOCKET fd = nbio_fd(socket);
602 struct sockaddr_in addr;
665 { nbio_sock_t socket;
666 int rc;
667
668 if ( !tcp_get_socket(Socket, &socket) )
669 return FALSE;
670
671 if ( (rc=af_unix_bind(socket, Address)) != -1 )
672 { return rc;
673 } else
674 { struct sockaddr_in sockaddr;
675 term_t varport = 0;
676
677 memset(&sockaddr, 0, sizeof(sockaddr));
678 if ( !nbio_get_sockaddr(Address, &sockaddr, &varport) )
679 return FALSE;
680
681 if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0 )
682 return FALSE;
683
684 if ( varport )
685 { SOCKET fd = nbio_fd(socket);
686 struct sockaddr_in addr;
603687 #ifdef __WINDOWS__
604 int len = sizeof(addr);
688 int len = sizeof(addr);
605689 #else
606 socklen_t len = sizeof(addr);
607 #endif
608
609 if ( getsockname(fd, (struct sockaddr *) &addr, &len) )
610 return nbio_error(GET_ERRNO, TCP_ERRNO);
611 return PL_unify_integer(varport, ntohs(addr.sin_port));
612 }
613
614 return TRUE;
690 socklen_t len = sizeof(addr);
691 #endif
692
693 if ( getsockname(fd, (struct sockaddr *) &addr, &len) )
694 return nbio_error(GET_ERRNO, TCP_ERRNO);
695 return PL_unify_integer(varport, ntohs(addr.sin_port));
696 }
697
698 return TRUE;
699 }
615700 }
616701
617702
618703 static foreign_t
619704 pl_accept(term_t Master, term_t Slave, term_t Peer)
620705 { nbio_sock_t master, slave;
621 struct sockaddr_in addr;
622 socklen_t addrlen = sizeof(addr);
623706
624707 if ( !tcp_get_socket(Master, &master) )
625708 return FALSE;
626709
627 if ( !(slave = nbio_accept(master, (struct sockaddr*)&addr, &addrlen)) )
628 return FALSE;
629 /* TBD: close on failure */
630 if ( nbio_unify_ip4(Peer, ntohl(addr.sin_addr.s_addr)) &&
631 tcp_unify_socket(Slave, slave) )
710 #ifdef AF_UNIX
711 if ( nbio_domain(master) == AF_UNIX )
712 { struct sockaddr_un addr;
713 socklen_t addrlen = sizeof(addr);
714
715 if ( !PL_unify_atom(Peer, ATOM_af_unix) )
716 return FALSE;
717 if ( !(slave = nbio_accept(master, (struct sockaddr*)&addr, &addrlen)) )
718 return FALSE;
719 } else
720 #endif
721 { struct sockaddr_in addr;
722 socklen_t addrlen = sizeof(addr);
723
724 if ( !(slave = nbio_accept(master, (struct sockaddr*)&addr, &addrlen)) )
725 return FALSE;
726 if ( !nbio_unify_ip4(Peer, ntohl(addr.sin_addr.s_addr)) )
727 goto failure;
728 }
729
730 if ( tcp_unify_socket(Slave, slave) )
632731 return TRUE;
633732
733 failure:
734 nbio_closesocket(slave);
634735 return FALSE;
635736 }
636737
699800 ATOM_ip_add_membership = PL_new_atom("ip_add_membership");
700801 ATOM_ip_drop_membership = PL_new_atom("ip_drop_membership");
701802 ATOM_sndbuf = PL_new_atom("sndbuf");
803 ATOM_af_unix = PL_new_atom("af_unix");
702804
703805 FUNCTOR_socket1 = PL_new_functor(PL_new_atom("$socket"), 1);
704806
718820 PL_register_foreign("udp_receive", 4, udp_receive, 0);
719821 PL_register_foreign("udp_send", 4, udp_send, 0);
720822
823 #ifndef __WINDOWS__
824 PL_register_foreign("unix_domain_socket", 1, unix_domain_socket, 0);
825 #endif
826
721827 #ifdef O_DEBUG
722828 PL_register_foreign("tcp_debug", 1, pl_debug, 0);
723829 #endif
181181 :- use_foreign_library(foreign(socket), install_socket).
182182 :- public tcp_debug/1. % set debugging.
183183
184 :- if(current_predicate(unix_domain_socket/1)).
185 :- export(unix_domain_socket/1). % -Socket
186 :- endif.
187
184188 %! tcp_socket(-SocketId) is det.
185189 %
186190 % Creates an INET-domain stream-socket and unifies an identifier
260264
261265 %! tcp_accept(+Socket, -Slave, -Peer) is det.
262266 %
263 % This predicate waits on a server socket for a connection request
264 % by a client. On success, it creates a new socket for the client
265 % and binds the identifier to Slave. Peer is bound to the
266 % IP-address of the client.
267
268 %! tcp_connect(+SocketId, +HostAndPort) is det.
267 % This predicate waits on a server socket for a connection request by
268 % a client. On success, it creates a new socket for the client and
269 % binds the identifier to Slave. Peer is bound to the IP-address of
270 % the client or the atom `af_unix` if Socket is an AF_UNIX socket (see
271 % unix_domain_socket/1).
272
273 %! tcp_connect(+SocketId, +Address) is det.
269274 %
270275 % Connect SocketId. After successful completion, tcp_open_socket/3
271276 % can be used to create I/O-Streams to the remote socket. This
289294 % talk(StreamPair),
290295 % close(StreamPair))
291296 % ==
297 %
298 % If SocketId is an AF_UNIX socket (see unix_domain_socket/1), Address
299 % is an atom or string denoting a file name.
292300
293301
294302 /*******************************
328336 %! tcp_connect(+Address, -StreamPair, +Options) is det.
329337 %! tcp_connect(+Socket, +Address, -StreamPair) is det.
330338 %
331 % Establish a TCP communication as a client. The +,-,+ mode is the
332 % preferred way for a client to establish a connection. This
333 % predicate can be hooked to support network proxies. To use a
334 % proxy, the hook proxy_for_url/3 must be defined. Permitted
335 % options are:
339 % Establish a TCP communication as a client. The +,-,+ mode is the
340 % preferred way for a client to establish a connection. This predicate
341 % can be hooked to support network proxies. To use a proxy, the hook
342 % proxy_for_url/3 must be defined. Permitted options are:
336343 %
337344 % * bypass_proxy(+Boolean)
338345 % Defaults to =false=. If =true=, do not attempt to use any
342349 % Defaults to =false=. If =true=, set nodelay on the
343350 % resulting socket using tcp_setopt(Socket, nodelay)
344351 %
345 % The +,+,- mode is deprecated and does not support proxies. It
346 % behaves like tcp_connect/4, but creates a stream pair (see
352 % The +,+,- mode is deprecated and does not support proxies. It
353 % behaves like tcp_connect/4, but creates a stream pair (see
347354 % stream_pair/3).
348355 %
349 % @error proxy_error(tried(ResultList)) is raised by mode (+,-,+)
350 % if proxies are defines by proxy_for_url/3 but no proxy can
351 % establsh the connection. `ResultList` contains one or more terms
352 % of the form false(Proxy) for a hook that simply failed or
353 % error(Proxy, ErrorTerm) for a hook that raised an exception.
354 %
355 % @see library(http/http_proxy) defines a hook that allows to
356 % connect through HTTP proxies that support the =CONNECT= method.
356 % @arg Address is either a Host:Port term or a file name (atom or
357 % string). The latter connects to an AF_UNIX socket and requires
358 % unix_domain_socket/1.
359 %
360 % @error proxy_error(tried(ResultList)) is raised by mode (+,-,+) if
361 % proxies are defines by proxy_for_url/3 but no proxy can establsh the
362 % connection. `ResultList` contains one or more terms of the form
363 % false(Proxy) for a hook that simply failed or error(Proxy,
364 % ErrorTerm) for a hook that raised an exception.
365 %
366 % @see library(http/http_proxy) defines a hook that allows to connect
367 % through HTTP proxies that support the =CONNECT= method.
357368
358369 % Main mode: +,-,+
359370 tcp_connect(Address, StreamPair, Options) :-
386397
387398
388399 tcp_connect_direct(Address, Socket, StreamPair):-
389 tcp_socket(Socket),
400 make_socket(Address, Socket),
390401 catch(tcp_connect(Socket, Address, StreamPair),
391402 Error,
392403 ( tcp_close_socket(Socket),
393404 throw(Error)
394405 )).
406
407 :- if(current_predicate(unix_domain_socket/1)).
408 make_socket(Address, Socket) :-
409 ( atom(Address)
410 ; string(Address)
411 ),
412 !,
413 unix_domain_socket(Socket).
414 :- endif.
415 make_socket(_Address, Socket) :-
416 tcp_socket(Socket).
417
395418
396419 %! tcp_select(+ListOfStreams, -ReadyList, +TimeOut)
397420 %
0 /* Part of SWI-Prolog
1
2 Author: Jan Wielemaker
3 E-mail: J.Wielemaker@vu.nl
4 WWW: http://www.swi-prolog.org
5 Copyright (c) 2020, VU University Amsterdam
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 1. Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in
17 the documentation and/or other materials provided with the
18 distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 :- module(test_af_unix,
35 [ test_af_unix/0
36 ]).
37 :- use_module(library(socket)).
38
39 :- if(current_predicate(unix_domain_socket/1)).
40 :- use_module(library(debug)).
41 :- use_module(library(readutil)).
42
43 test_af_unix :-
44 tmp_file(af_unix, File),
45 server(File, Tid),
46 client(File),
47 thread_signal(Tid, throw(stop)),
48 thread_join(Tid, Status),
49 assertion(Status == exception(stop)).
50
51 server(File, Thread) :-
52 ( access_file(File, exist)
53 -> delete_file(File)
54 ; true
55 ),
56 unix_domain_socket(S),
57 tcp_bind(S, File),
58 !,
59 tcp_listen(S, 5),
60 tcp_open_socket(S, AcceptFd, _),
61 thread_create(dispatch(AcceptFd), Thread).
62
63 dispatch(AcceptFd) :-
64 tcp_accept(AcceptFd, Socket, Peer),
65 thread_create(process_client(Socket, Peer), _,
66 [ detached(true)
67 ]),
68 dispatch(AcceptFd).
69
70 process_client(Socket, Peer) :-
71 debug(af_unix, "Connected from ~p~n", [Peer]),
72 setup_call_cleanup(
73 tcp_open_socket(Socket, StreamPair),
74 handle_service(StreamPair),
75 close(StreamPair)).
76
77 handle_service(Stream) :-
78 read_line_to_string(Stream, String),
79 format(Stream, '~s~n', [String]),
80 flush_output(Stream),
81 ( String == "bye"
82 -> true
83 ; handle_service(Stream)
84 ).
85
86 client(File) :-
87 unix_domain_socket(Socket),
88 tcp_connect(Socket, File),
89 tcp_open_socket(Socket, Stream),
90 ping(Stream, "Hello world"),
91 ping(Stream, "bye"),
92 close(Stream).
93
94 ping(Stream, Data) :-
95 format(Stream, '~s~n', [Data]),
96 flush_output(Stream),
97 read_line_to_string(Stream, Reply),
98 assertion(Data == Reply).
99
100 :- else.
101
102 test_af_unix.
103
104 :- endif.
199199
200200 add_dependencies(doc.html ${pkg}.doc.html)
201201
202 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Documentation)
202203 prepend(doc_files ${CMAKE_CURRENT_BINARY_DIR}/ ${pkg}.html ${vimages})
203204 install(FILES ${doc_files}
204 DESTINATION ${SWIPL_INSTALL_PREFIX}/doc/packages
205 DESTINATION ${SWIPL_INSTALL_DOC}/packages
205206 COMPONENT Documentation
206207 OPTIONAL)
207208 endif(INSTALL_DOCUMENTATION)
255255 endif()
256256 endforeach()
257257
258 set(extdest ${SWIPL_INSTALL_PREFIX}/doc/packages/examples/${SWIPL_PKG})
258 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Documentation)
259 set(extdest ${SWIPL_INSTALL_DOC}/packages/examples/${SWIPL_PKG})
259260 if(subdir)
260261 set(extdest ${extdest}/${subdir})
261262 set(subdir_ ${subdir}_)
318319 -t halt)
319320 # Write db with lists of tests to be used with -DINSTALL_TESTS
320321 if(INSTALL_TESTS)
322 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Tests)
321323 file(RELATIVE_PATH rel_test_dir
322324 ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR})
323325 file(APPEND ${INSTALL_TESTS_DB}
2222
2323 if(HAVE_SOCKET)
2424 AC_CHECK_HEADERS(sys/socket.h)
25 AC_CHECK_HEADERS(sys/un.h)
2526 if(HAVE_SYS_SOCKET_H)
2627 set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} sys/socket.h)
2728 endif()
66 FILES SWI-cpp.h DESTINATION
77 ${SWIPL_INSTALL_INCLUDE})
88
9 swipl_examples(test.cpp likes.cpp likes.pl test.pl)
9 swipl_examples(test.cpp likes.cpp likes.pl test.pl README.md)
1010
1111 pkg_doc(
1212 pl2cpp
+0
-87
packages/cpp/ChangeLog less more
0 [Jul 21 2009]
1
2 * MODIFIED: Make initialization/1 ISO compliant
3 This patch is a modest cleanup to the implementation of '$load_file'/3
4 from init.pl and provides an ISO compatible implementation of
5 initialization/1. This executes the argument goal *after* loading the
6 file rather than when encountering the directive. Often this makes no
7 difference, but notably load_foreign_library/1 is an exception.
8 Therefore we added use_foreign_library/1,2 that act as a directive and
9 provides proper integration with saved-states automatically. Loading
10 code using initialization(load_foreign_library(...)) will load the
11 library immediately and issue a warning.
12
13 See initialization/1,2 for details and further hints for dealing with
14 possible compatibility problems.
15
16 [Jul 18 2009]
17
18 * BUILD: Supported way to install using links instead of copying (developers)
19 [Mar 19 2009]
20
21 * CLEANUP: Removed all trailing whitespace from all source-files. This avoids many GIT (merge) warnings.
22 [Dec 22 2008]
23
24 * ADDED: C++ registration for non-deterministic predicates. Willem Robert van Hage.
25
26 [Sep 11 2008]
27
28 * PORT: Add AC_PREREQ to configure.h for systems that auto-select autoconf
29 versions. After tip by Ulrich Neumerkel.
30
31 [Aug 11 2008]
32
33 * INSTALL: Remove all configure files from the git repository
34 [Dec 18 2007]
35
36 * FIXED: Handling of #define PROLOG_MODULE in the C++ interface.
37 * MODIFIED: Note that the PlRegister() class has an extra argument for
38 all initializers.
39 Sep 25, 2007
40
41 * FIXED: Allow multiple inclusions. Mary Ellen Foster.
42
43 Jan 18, 2007
44
45 * FIXED/MODIFIED: PlQuery(Module, Name, Args) now calls using Module
46 as context. Christian Mol.
47
48 Apr 11, 2004
49
50 * Fixed ambiguity in PlTermvDomainError constructor showing up with g++
51 3.3.
52
53 Jan 21, 2003
54
55 * One more const to avoid confusing the compiler. Thanks to Alan Baljeu
56 and Fabien Todescato.
57
58 Jan 12, 2003
59
60 * Patches by Alan Baljeu, adding many const declarations to the interface.
61
62 VERSION 1.0.4
63 =============
64
65 * ADDED: Destructor to PlEngine class, calling PL_cleanup(). Requires
66 SWI-Prolog 3.4.1 or later.
67
68 VERSION 1.0.3
69 =============
70
71 * FIXED: untyped 'operator =' declarations reported by gcc version 2.95.2.
72
73 VERSION 1.0.2
74 =============
75
76 * FIXED: PlException to pass exceptions other then domain and type errors
77 correctly. Thanks to Use Lesta.
78
79 VERSION 1.0.1
80 =============
81
82 * ADDED: conversion between PlTerm and void*
83
84
85 VERSION 1.0.0
86 =============
+0
-14
packages/cpp/README less more
0 SWI-Prolog C++ interface
1
2 Demo: make (must be GNU-make) produces
3
4 * embedded program likes. See likes.cpp
5 * test.so, load using test.pl holding the examples from
6 the manual and some more.
7
8 Note: I'm an amateur C++ programmer. Volker Wysk <post@volker-wysk.de>
9 has compiled a new C++ interface and announced it for
10 first public testing on January 14, 2002. This interface
11 may be downloaded from.
12
13 http://www.volker-wysk.de/swiprolog-c++/index.html
0 # SWI-Prolog C++ interface
1
2 ## Embedding SWI-Prolog in a C++ program
3
4 The files likes.pl and likes.cpp provide a simple example emedding
5 SWI-Prolog. To compile, run
6
7 swipl-ld -o likes likes.cpp likes.pl
8
9 Next, run as e.g.
10
11 ./likes john
12 ./likes -happy
13
14 ## Extending SWI-Prolog using C++ code
15
16 The files `test.pl` and `test.cpp` add foreign predicates to SWI-Prolog.
17 To compile, run
18
19 swipl-ld -o test -shared test.cpp
20
21 Next, run as e.g.
22
23 swipl test.pl
24 ?- hello(world).
25 Hello world
26 true.
+0
-1
packages/cpp/VERSION less more
0 1.0.4
+0
-238
packages/cpp/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
+0
-238
packages/cql/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
110110 PACKAGES clib sgml plunit ssl zlib
111111 PARENT_LIB)
112112
113 if(INSTALL_TESTS)
114 install(FILES examples/demo_body.pl
115 DESTINATION ${INSTALL_TESTS_DIR}/packages/http/examples)
113 has_package(ssl, HAVE_SSL_PACKAGE)
114 if(HAVE_SSL_PACKAGE)
115 set(doc_depends ssl)
116116 endif()
117117
118118 pkg_doc(http
120120 http
121121 SOURCES
122122 json.md
123 SOURCE post.md --lib=http/html_write
123 SOURCE
124 post.md --lib=http/html_write
125 DEPENDS
126 ${doc_depends}
124127 SECTION
125128 websocket.pl hub.pl
126129 SUBSECTION
18531853 { base64(Data, DataBase64),
18541854 atom_codes(DataBase64, Codes)
18551855 },
1856 string(Codes), "\r\n".
1856 string(Codes).
18571857 auth_field_value(negotiate) -->
1858 "Negotiate\r\n".
1858 "Negotiate".
18591859 auth_field_value(basic) -->
18601860 !,
1861 "Basic\r\n".
1861 "Basic".
18621862 auth_field_value(basic(Realm)) -->
1863 "Basic Realm=\"", atom(Realm), "\"\r\n".
1863 "Basic Realm=\"", atom(Realm), "\"".
18641864 auth_field_value(digest) -->
18651865 !,
1866 "Digest\r\n".
1866 "Digest".
18671867 auth_field_value(digest(Details)) -->
1868 "Digest ", atom(Details), "\r\n".
1868 "Digest ", atom(Details).
18691869
18701870 %! value_options(+List, +Field)//
18711871 %
6161 :- autoload(library(http/http_header),
6262 [ http_parse_header/2, http_post_data/3 ]).
6363 :- autoload(library(http/http_stream),[stream_range_open/3]).
64 :- if(exists_source(library(ssl))).
64 :- if(( exists_source(library(ssl)),
65 \+ current_prolog_flag(pldoc_to_tex,true))).
6566 :- autoload(library(ssl), [ssl_upgrade_legacy_options/2]).
6667 :- endif.
6768
5353 :- use_module(library(main)).
5454 :- use_module(library(readutil)).
5555
56 :- if(exists_source(library(http/http_ssl_plugin))).
56 :- if(( exists_source(library(http/http_ssl_plugin)),
57 \+ current_prolog_flag(pldoc_to_tex,true))).
5758 :- use_module(library(ssl)).
5859 :- use_module(library(http/http_ssl_plugin)).
5960 :- endif.
826827 repeat,
827828 State = deadline(Count),
828829 Deadline is FirstDeadline+Count*Interval,
829 ( thread_get_message(Me, Msg, [deadline(Deadline)])
830 ( thread_idle(thread_get_message(Me, Msg, [deadline(Deadline)]),
831 long)
830832 -> catch(ignore(handle_message(Msg)), E,
831833 print_message(error, E)),
832834 Msg == quit,
840842 wait(_) :-
841843 thread_self(Me),
842844 repeat,
843 thread_get_message(Me, Msg),
845 thread_idle(thread_get_message(Me, Msg), long),
844846 catch(ignore(handle_message(Msg)), E,
845847 print_message(error, E)),
846848 Msg == quit,
581581 option(queue(Queue), Options),
582582 option(max_idle_time(MaxIdle), Options, infinite),
583583 repeat,
584 garbage_collect,
585 trim_stacks,
584 thread_idle(get_work(Queue, Message, MaxIdle), long),
586585 debug(http(worker), 'Waiting for a job ...', []),
587 ( MaxIdle == infinite
588 -> thread_get_message(Queue, Message)
589 ; thread_get_message(Queue, Message, [timeout(MaxIdle)])
590 -> true
591 ; Message = quit(idle)
592 ),
593586 debug(http(worker), 'Got job ~p', [Message]),
594587 ( Message = quit(Sender)
595588 -> !,
617610 )
618611 ).
619612
613 get_work(Queue, Message, infinite) :-
614 !,
615 thread_get_message(Queue, Message).
616 get_work(Queue, Message, MaxIdle) :-
617 ( thread_get_message(Queue, Message, [timeout(MaxIdle)])
618 -> true
619 ; Message = quit(idle)
620 ).
621
620622
621623 %! open_client(+Message, +Queue, -Goal, -In, -Out,
622624 %! +Options, -ClientOptions) is semidet.
+0
-7
packages/inclpr/ChangeLog less more
0 Apr 20, 2006
1
2 * JW: Pass C?FLAGS from configure
3
4 Apr 19, 2006
5
6 * Initial version
+0
-22
packages/inclpr/README less more
0 SWI-Prolog INCLP(R)
1 -------------------
2
3 Author: Leslie De Koninck, K.U.Leuven
4
5 This software is a Constraint Logic Programming library, capable of
6 solving nonlinear (polynomial) constraints over the real numbers. It is
7 based on interval arithmetic techniques and is built on top of the
8 K.U.Leuven CHR implementation which is also part of SWI-Prolog. The
9 software is released with permission from the author under the standard
10 SWI-Prolog license schema: GPL-2 + statement to allow linking with
11 proprietary software.
12
13 The sources of this package are maintained in packages/inclpr in the
14 SWI-Prolog source distribution. The documentation source is in
15 man/lib/inclpr.doc as part of the overall SWI-Prolog documentation.
16
17 More information on INCLP(R) can be found at
18
19 http://www.cs.kuleuven.be/~leslie/INCLPR/
20
21
0 SWI-Prolog INCLP(R)
1 -------------------
2
3 Author: Leslie De Koninck, K.U.Leuven
4
5 This software is a Constraint Logic Programming library, capable of
6 solving nonlinear (polynomial) constraints over the real numbers. It is
7 based on interval arithmetic techniques and is built on top of the
8 K.U.Leuven CHR implementation which is also part of SWI-Prolog. The
9 software is released with permission from the author under the standard
10 SWI-Prolog license schema: GPL-2 + statement to allow linking with
11 proprietary software.
12
13 The sources of this package are maintained in packages/inclpr in the
14 SWI-Prolog source distribution. The documentation source is in
15 man/lib/inclpr.doc as part of the overall SWI-Prolog documentation.
16
17 More information on INCLP(R) can be found at
18
19 http://www.cs.kuleuven.be/~leslie/INCLPR/
20
21
+0
-238
packages/inclpr/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
135135
136136 if(INSTALL_TESTS)
137137 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/java/jpltest.jar
138 DESTINATION ${INSTALL_TESTS_DIR}/packages/jpl/src/java)
138 DESTINATION ${INSTALL_TESTS_DIR}/packages/jpl/src/java
139 COMPONENT Tests)
139140 endif()
140141
141142 else(JUNIT_JAR)
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1997-2018, University of Amsterdam
5 Copyright (c) 1997-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
5858 clean_tt/2, % +Raw, -Clean
5959 op(100, fx, #)
6060 ]).
61 :- use_module(library(quintus)).
62 :- use_module(library(filesex)).
63 :- use_module(library(option)).
64 :- use_module(library(apply)).
61 :- autoload(library(apply),[maplist/3]).
62 :- autoload(library(backcomp),[convert_time/8]).
63 :- autoload(library(ctypes),
64 [is_lower/1,to_upper/2,is_alpha/1,is_upper/1,to_lower/2]).
65 :- autoload(library(debug),[debug/3]).
66 :- autoload(library(filesex),[copy_file/2,directory_file_path/3]).
67 :- autoload(library(gui_tracer),[gtrace/0]).
68 :- autoload(library(lists),
69 [ reverse/2,
70 member/2,
71 flatten/2,
72 append/3,
73 select/3,
74 nth1/3,
75 last/2
76 ]).
77 :- autoload(library(main),[main/0,argv_options/3]).
78 :- autoload(library(occurs),[sub_term/2]).
79 :- autoload(library(option),[option/2,select_option/3]).
80 :- autoload(library(readutil),[read_file_to_codes/3]).
81 :- autoload(library(statistics),[statistics/0]).
6582
6683 ltx2htm_version('0.98'). % for SWI-Prolog 5.6.18
6784
12361253 cmd(rightline({Tex}), #right(+Tex)).
12371254
12381255 cmd(email({Address}), #url(URL, Address)) :-
1239 sformat(URL, 'mailto:~w', [Address]).
1256 format(string(URL), 'mailto:~w', [Address]).
12401257 cmd(url({Address}), #url(Address, Address)).
12411258 cmd(href({URL}, {Text}), #url(URL, +Text)).
12421259 cmd(file({File}), #tt(File)).
13431360 ps_extension(Ext),
13441361 file_base_name(Base, GifBase),
13451362 file_name_extension(GifBase, gif, GifFile),
1346 sformat(Img, '<img src="~w">', GifFile),
1363 format(string(Img), '<img src="~w">', GifFile),
13471364 make_output_directory,
13481365 html_output_dir(Dir),
13491366 atomic_list_concat([Dir, '/', GifFile], OutFile),
13711388 img_extension(Ext),
13721389 !,
13731390 file_base_name(AbsImgFile, ImgFile),
1374 sformat(Img, '<img src="~w">', ImgFile),
1391 format(string(Img), '<img src="~w">', ImgFile),
13751392 make_output_directory,
13761393 html_output_dir(Dir),
13771394 atomic_list_concat([Dir, '/', ImgFile], OutFile),
13901407 file_name_extension(Base, Ext, PsFile),
13911408 file_base_name(Base, GifBase),
13921409 file_name_extension(GifBase, gif, GifFile),
1393 sformat(Img, '<img src="~w">', GifFile),
1410 format(string(Img), '<img src="~w">', GifFile),
13941411 make_output_directory,
13951412 html_output_dir(Dir),
13961413 atomic_list_concat([Dir, '/', GifFile], OutFile),
14711488
14721489 cmd('HTML'({Tag}), #code(Tag)).
14731490 cmd(latexcmd({Cmd}), #code(BslCmd)) :-
1474 concat(\, Cmd, BslCmd).
1491 atom_concat(\, Cmd, BslCmd).
14751492 cmd(latexenv({Env}), #code(Env)).
14761493 cmd(mode({Mode}), #code(Mode)).
14771494
6666 ResY is Res0 * ScaleY,
6767 ( ResX =:= ResY
6868 -> Res = ResX
69 ; sformat(Res, '~wx~w', [ResX, ResY])
69 ; format(string(Res), '~wx~w', [ResX, ResY])
7070 ),
7171 BBX is -X1,
7272 BBY is -Y1,
119119 get_option(Options, device(Dev)),
120120 get_option(Options, tmp(Tmp)),
121121 ( get_option(Options, size(W, H))
122 -> sformat(SCmd, '-g~wx~w', [W, H])
122 -> format(string(SCmd), '-g~wx~w', [W, H])
123123 ; SCmd = ''
124124 ),
125125 aformat(Cmd,
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1997-2014, University of Amsterdam
5 Copyright (c) 1997-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
3333 */
3434
3535 :- module(latex2html4pl, []).
36 :- use_module(latex2html).
36 :- use_module(latex2html,
37 [ latex2html_module/0,
38 tex_load_commands/1,
39 translate_table/3,
40 clean_tt/2,
41 add_to_index/2,
42 add_to_index/1,
43 translate_section/5,
44 translate_section/4,
45 op(_,_,_)
46 ]).
47 :- autoload(library(apply),[maplist/3,maplist/2]).
48 :- autoload(library(lists),[append/3,delete/3]).
49 :- autoload(library(occurs),[sub_term/2]).
50 :- autoload(library(readutil),[read_line_to_codes/2]).
3751
3852 :- latex2html_module.
3953 :- tex_load_commands(pl).
8397 cmd(hrule, html('<hr>')).
8498 cmd(bug({TeX}), #footnote(bug, +TeX)).
8599 cmd(fileext({Ext}), #code(Text)) :-
86 sformat(Text, '.~w', [Ext]).
100 format(string(Text), '.~w', [Ext]).
87101
88102 cmd(var( {A1}), #var(+A1)).
89103 cmd(arg( {A1}), #var(+A1)).
116130 nospace(=)]), #var(+A2)]).
117131 cmd(fmtseq( {A1}), #code(A1)).
118132 cmd(versionshort, _, nospace(Version)) :-
119 feature(version, V),
133 current_prolog_flag(version, V),
120134 Major is V // 10000,
121135 Minor is (V // 100) mod 100,
122136 Patch is V mod 100,
130144 cmd(predref({RawName}, {Arity}), #lref(pred, RefName, Text)) :-
131145 clean_name(RawName, Name),
132146 predicate_refname(Name, Arity, RefName),
133 sformat(Text, '~w/~w', [Name, Arity]).
147 format(string(Text), '~w/~w', [Name, Arity]).
134148 cmd(funcref({RawName}, {Arity}), #lref(function, RefName, Text)) :-
135149 clean_name(RawName, Name),
136150 function_refname(Name, Arity, RefName),
137 sformat(Text, '~w/~w', [Name, Arity]).
151 format(string(Text), '~w/~w', [Name, Arity]).
138152 cmd(dcgref({RawName}, {DCGArity}), #lref(pred, RefName, Text)) :-
139153 clean_name(RawName, Name),
140154 atom_number(DCGArity, Arity),
141155 dcg_refname(Name, Arity, RefName),
142 sformat(Text, '~w//~w', [Name, Arity]).
156 format(string(Text), '~w//~w', [Name, Arity]).
143157 cmd(qpredref({Module}, {RawName}, {Arity}), #lref(pred, RefName, Text)) :-
144158 clean_name(RawName, Name),
145159 predicate_refname(Module:Name, Arity, RefName),
419433
420434 cmd(classitem({Class}),
421435 #defitem(#label(RefName, #strong(Class)))) :-
422 sformat(RefName, 'class:~w', [Class]).
436 format(string(RefName), 'class:~w', [Class]).
423437 cmd(constructor({Class}, {Args}),
424438 #defitem([#strong([Class, ::, Class]), #embrace(#var(+Args))])).
425439 cmd(destructor({Class}),
431445 % Some XPCE things
432446
433447 cmd(class({Name}), #lref(Label, Name)) :-
434 concat('class:', Name, Label),
448 atom_concat('class:', Name, Label),
435449 add_to_index(Name).
436450 cmd(noclass({Name}), #i(Name)).
437451 cmd(menuref({A1}), #lref(RefName, Name)) :-
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1999-2013, University of Amsterdam
5 Copyright (c) 1999-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
3333 */
3434
3535 :- module(latex2html4xpce, []).
36 :- use_module(library(latex2html/latex2html)).
36 :- autoload(library(apply),[maplist/3]).
37 :- autoload(library(lists),[append/3]).
38 :- autoload(library(latex2html/latex2html),
39 [ latex2html_module/0,
40 tex_load_commands/1,
41 translate/3,
42 add_to_index/1,
43 clean_tt/2,
44 add_to_index/2,
45 translate_table/3
46 ]).
3747
3848 :- latex2html_module.
3949 :- tex_load_commands(xpce).
7282 cmd(objectname({Name}), #b([nospace(@), Name])).
7383 cmd(noclass({Name}), #b(Name)).
7484 cmd(class({Name}), #lref(Label, Name)) :-
75 concat('class:', Name, Label),
85 atom_concat('class:', Name, Label),
7686 add_to_index(Name).
7787 cmd(classs({Name}), #lref(Label, NameS)) :-
78 concat('class:', Name, Label),
79 concat(Name, s, NameS),
88 atom_concat('class:', Name, Label),
89 atom_concat(Name, s, NameS),
8090 add_to_index(Name).
8191 cmd(tool({Name}), #strong(+Name)).
8292 cmd(demo({Name}), #strong(+Name)).
103113 #defitem([ #strong(+Descr), ' ', #i(#embrace(+Menu))])).
104114 cmd(secoverview({Label}, {Title}),
105115 [ html('<li>'), #lref(RefName, +Title) ]) :-
106 sformat(RefName, 'sec:~w', Label).
116 format(string(RefName), 'sec:~w', Label).
107117 cmd(classsummary(_M, {RawClass}, {Args}, {_FigRef}),
108118 #defitem(#label(Label, [#strong(Class), #embrace(#var(+Args))]))) :-
109119 clean_tt(RawClass, Class),
110 concat('class:', Class, Label),
120 atom_concat('class:', Class, Label),
111121 add_to_index(Class, +Label).
112122 cmd(fontalias({Alias}, {Term}), #defitem([#code(Alias), #i(+Term)])).
113123 cmd(noargpredicate(Name), HTML) :-
116126 % add_to_index(Term).
117127 cmd(glossitem({Term}), #defitem(#label(RefName, #strong(Term)))) :-
118128 canonicalise_glossitem(Term, Ref),
119 sformat(RefName, 'gloss:~w', [Ref]).
129 format(string(RefName), 'gloss:~w', [Ref]).
120130 cmd(g({Term}), #lref(RefName, Term)) :-
121131 canonicalise_glossitem(Term, Ref),
122 sformat(RefName, 'gloss:~w', [Ref]).
132 format(string(RefName), 'gloss:~w', [Ref]).
123133 cmd(line({Tokens}), #quote(Line)) :-
124134 translate(Tokens, normal, Line).
125135 cmd(classvar({Class}, {Var}), #b([#code([+Class,nospace('.'),+Var])])).
+0
-238
packages/paxos/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
5050 % Hook support
5151 paxos_replicate_key/3 % +Nodes, ?Key, +Options
5252 ]).
53 :- use_module(library(broadcast)).
54 :- use_module(library(debug)).
55 :- use_module(library(lists)).
56 :- use_module(library(settings)).
57 :- use_module(library(option)).
58 :- use_module(library(error)).
59 :- use_module(library(apply)).
60 :- use_module(library(solution_sequences)).
53 :- autoload(library(apply),[partition/4,maplist/3]).
54 :- autoload(library(broadcast),
55 [ listen/3,
56 broadcast_request/1,
57 broadcast/1,
58 unlisten/1,
59 listen/2,
60 unlisten/2
61 ]).
62 :- autoload(library(debug),[debug/3]).
63 :- autoload(library(error),
64 [permission_error/3,resource_error/1,must_be/2]).
65 :- autoload(library(lists),[select/3,nth1/3,max_list/2,member/2]).
66 :- autoload(library(option),[option/2,option/3]).
67 :- autoload(library(solution_sequences),[call_nth/2]).
68 :- use_module(library(settings),[setting/4,setting/2]).
6169
6270 /** <module> A Replicated Data Store
6371
172172 % day:20, month:4, year:2017}.
173173 %
174174 % ```
175 %
176 % @arg Options Only _execution_ options are processed. See re_match/3
177 % for the set of options. _Compilation_ options must be passed as
178 % `/flags` to Regex.
179 % @arg Regex See re_match/2 for a description of this argument.
175180
176181 re_matchsub(Regex, String, Subs, Options) :-
177182 re_compiled(Regex, Compiled),
+0
-238
packages/pengines/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
6666 @author Torbjörn Lager and Jan Wielemaker
6767 */
6868
69 :- use_module(library(http/http_dispatch)).
70 :- use_module(library(http/http_parameters)).
71 :- use_module(library(http/http_client)).
72 :- use_module(library(http/http_json)).
73 :- use_module(library(http/http_open)).
74 :- use_module(library(http/http_stream)).
75 :- use_module(library(http/http_wrapper)).
76 :- use_module(library(http/http_cors)).
77 :- use_module(library(thread_pool)).
78 :- use_module(library(broadcast)).
79 :- use_module(library(uri)).
80 :- use_module(library(filesex)).
81 :- use_module(library(time)).
82 :- use_module(library(lists)).
83 :- use_module(library(charsio)).
84 :- use_module(library(apply)).
85 :- use_module(library(aggregate)).
86 :- use_module(library(option)).
87 :- use_module(library(settings)).
88 :- use_module(library(debug)).
89 :- use_module(library(error)).
90 :- use_module(library(sandbox)).
91 :- use_module(library(modules)).
92 :- use_module(library(term_to_json)).
69 :- autoload(library(aggregate),[aggregate_all/3]).
70 :- autoload(library(apply),[maplist/2,partition/4,exclude/3,maplist/3]).
71 :- autoload(library(broadcast),[broadcast/1]).
72 :- autoload(library(charsio),[open_chars_stream/2]).
73 :- autoload(library(debug),[debug/1,debugging/1,debug/3,assertion/1]).
74 :- autoload(library(error),
75 [ must_be/2,
76 existence_error/2,
77 permission_error/3,
78 domain_error/2
79 ]).
80 :- autoload(library(filesex),[directory_file_path/3]).
81 :- autoload(library(listing),[listing/1]).
82 :- autoload(library(lists),[member/2,flatten/2,select/3,append/3]).
83 :- autoload(library(modules),[in_temporary_module/3]).
84 :- autoload(library(occurs),[sub_term/2]).
85 :- autoload(library(option),
86 [select_option/3,option/2,option/3,select_option/4]).
87 :- autoload(library(prolog_stack),[print_prolog_backtrace/2]).
88 :- autoload(library(sandbox),[safe_goal/1]).
89 :- autoload(library(statistics),[thread_statistics/2]).
90 :- autoload(library(term_to_json),[term_to_json/2]).
91 :- autoload(library(thread_pool),
92 [thread_pool_create/3,thread_create_in_pool/4]).
93 :- autoload(library(time),[alarm/4,call_with_time_limit/2]).
94 :- autoload(library(uri),
95 [ uri_components/2,
96 uri_query_components/2,
97 uri_data/3,
98 uri_data/4,
99 uri_encoded/3
100 ]).
101 :- autoload(library(http/http_client),[http_read_data/3]).
102 :- autoload(library(http/http_cors),[cors_enable/0,cors_enable/2]).
103 :- autoload(library(http/http_dispatch),
104 [http_handler/3,http_404/2,http_reply_file/3]).
105 :- autoload(library(http/http_open),[http_open/3]).
106 :- autoload(library(http/http_parameters),[http_parameters/2]).
107 :- autoload(library(http/http_stream),[is_cgi_stream/1]).
108 :- autoload(library(http/http_wrapper),[http_peer/2]).
109
110 :- use_module(library(settings),[setting/2,setting/4]).
111 :- use_module(library(http/http_json),
112 [http_read_json_dict/2,reply_json/1]).
113
93114 :- if(exists_source(library(uuid))).
94 :- use_module(library(uuid)).
115 :- autoload(library(uuid), [uuid/2]).
95116 :- endif.
96117
97118
688709 pengine_uuid(Id) :-
689710 uuid(Id, [version(4)]). % Version 4 is random.
690711 :- else.
691 :- use_module(library(random)).
692712 pengine_uuid(Id) :-
693713 ( current_prolog_flag(max_integer, Max1)
694714 -> Max is Max1-1
973993 %
974994 % On demand creation of a thread pool for a pengine application.
975995
996 :- multifile thread_pool:create_pool/1.
997
976998 thread_pool:create_pool(Application) :-
977999 current_application(Application),
9781000 setting(Application:thread_pool_size, Size),
6060
6161 message_lines_to_html/3 % +Lines, +Classes, -HTML
6262 ]).
63 :- use_module(library(lists)).
64 :- use_module(library(pengines)).
65 :- use_module(library(option)).
66 :- use_module(library(debug)).
67 :- use_module(library(error)).
68 :- use_module(library(apply)).
69 :- use_module(library(settings)).
70 :- use_module(library(listing)).
71 :- use_module(library(yall)).
63 :- autoload(library(apply),[foldl/4,maplist/3,maplist/4]).
64 :- autoload(library(backcomp),[thread_at_exit/1]).
65 :- autoload(library(debug),[assertion/1]).
66 :- autoload(library(error),[must_be/2]).
67 :- autoload(library(listing),[listing/1,portray_clause/1]).
68 :- autoload(library(lists),[append/2,append/3,subtract/3]).
69 :- autoload(library(option),[option/3,merge_options/3]).
70 :- autoload(library(pengines),
71 [ pengine_self/1,
72 pengine_output/1,
73 pengine_input/2,
74 pengine_property/2
75 ]).
76 :- autoload(library(prolog_stream),[open_prolog_stream/4]).
77 :- autoload(library(readutil),[read_line_to_string/2]).
78 :- autoload(library(yall),[(>>)/4]).
79 :- autoload(library(http/html_write),[html/3,print_html/1]).
80 :- autoload(library(http/term_html),[term/4]).
81 :- use_module(library(settings),[setting/4,setting/2]).
82
7283 :- use_module(library(sandbox), []).
73 :- use_module(library(http/html_write)).
74 :- use_module(library(http/term_html)).
7584 :- if(exists_source(library(prolog_stream))).
76 :- use_module(library(prolog_stream)).
7785 :- endif.
7886
7987 :- html_meta send_html(html).
3333
3434 :- module(pengines_sandbox, []).
3535 :- use_module(library(pengines), []).
36 :- use_module(library(lists)).
37 :- use_module(library(error)).
36 :- autoload(library(error),[instantiation_error/1]).
37 :- autoload(library(lists),[append/3]).
3838
3939 /** <module> Declare Pengine interaction sandbox-safe
4040
3737 [ term_to_json/3, % +Term, +Bindings, -Json
3838 term_to_json/2 % +Term, -Json
3939 ]).
40 :- use_module(library(apply)).
41 :- use_module(library(error)).
40 :- autoload(library(apply),[maplist/2,maplist/3]).
41 :- autoload(library(error),[must_be/2,domain_error/2]).
4242
4343 %! term_to_json(+Term, +Bindings, -JsonTerm) is det.
4444 %! term_to_json(+Term, -JsonTerm) is det.
+0
-14
packages/pengines/test_local.pl less more
0 % setup paths to load relevant packages from development environment
1 :- asserta(user:file_search_path(foreign, '../http')).
2 :- asserta(user:file_search_path(foreign, '../clib')).
3 :- asserta(user:file_search_path(foreign, '../sgml')).
4 :- asserta(user:file_search_path(library, '.')).
5 :- asserta(user:file_search_path(library, '..')).
6 :- asserta(user:file_search_path(library, '../sgml')).
7 :- asserta(user:file_search_path(library, '../plunit')).
8 :- asserta(user:file_search_path(library, '../clib')).
9 :- asserta(user:file_search_path(dtd, '../sgml/DTD')).
10
11 % Hack: auto-loading this does not work.
12 :- [library(charsio)].
13 :- [charsio:library(memfile)].
3535 [ test_pengines/0,
3636 pengine_server/0 % start server
3737 ]).
38 :- include(test_local).
3938
4039 :- debug(pengine(delay)).
4140 % run pengine server for remote tests in a separate process.
3535 [ test_term_html/0,
3636 term_html_string/3 % @Term, -String, +Options
3737 ]).
38 :- include(test_local).
3938
4039 :- use_module(library(plunit)).
4140 :- use_module(library(debug)).
8282 synonym(char, character, 0.8).
8383 synonym(clone, duplicate, 0.3).
8484 synonym(close, destroy, 0.3).
85 synonym(comma, conjunction, 0.3).
8586 synonym(concat, concatenate, 0.8).
8687 synonym(console, terminal, 0.7).
8788 synonym(consult, compile, 0.7).
144145 synonym(run, call, 0.3).
145146 synonym(same, equivalent, 0.8).
146147 synonym(screen, console, 0.5).
148 synonym(semincolon,disjunction, 0.3).
147149 synonym(sin, sine, 0.9).
148150 synonym(size, memory, 0.3).
149151 synonym(smaller, less, 0.5).
5353 @license GPL+SWI-exception or Artistic 2.0
5454 */
5555
56 :- use_module(library(apply)).
57 :- use_module(library(ordsets), [ord_intersection/3]).
56 :- autoload(library(apply),[maplist/3,include/3]).
57 :- autoload(library(lists),[member/2,append/2]).
58 :- autoload(library(option),[option/3,option/2]).
59 :- autoload(library(ordsets),[ord_intersection/3]).
60 :- autoload(library(pairs),[group_pairs_by_key/2,pairs_values/2]).
61
5862 :- meta_predicate valid_options(+, 1).
5963
6064
114118 throw(error(Error_term,context(Impldef,_))).
115119
116120 :- set_prolog_flag(generate_debug_info, false).
117 :- use_module(library(option)).
118 :- use_module(library(pairs)).
119
120121 current_test_flag(Name, Value) :-
121122 current_prolog_flag(Name, Value).
122123
140141 throw_error(Error_term,Impldef) :-
141142 throw(error(Error_term,i(Impldef))). % SICStus 3 work around
142143
143 :- use_module(swi). % SWI-Compatibility
144 :- use_module(library(terms)).
144 % SWI-Compatibility
145145 :- op(700, xfx, =@=).
146146
147147 '$set_source_module'(_, _).
183183 /*******************************
184184 * IMPORTS *
185185 *******************************/
186
187 :- use_module(library(lists)).
188186
189187 :- initialization
190188 ( current_test_flag(test_options, _)
474472 *******************************/
475473
476474 :- if(swi).
477 :- use_module(library(error)).
478475 :- else.
479476 must_be(list, X) :-
480477 !,
3636 [ show_coverage/1, % :Goal
3737 show_coverage/2
3838 ]).
39 :- use_module(library(ordsets)).
40 :- use_module(library(apply)).
39 :- autoload(library(apply),[exclude/3,maplist/3,include/3,maplist/2]).
40 :- autoload(library(edinburgh),[nodebug/0]).
41 :- autoload(library(ordsets),
42 [ord_intersect/2,ord_intersection/3,ord_subtract/3]).
43 :- autoload(library(pairs),[group_pairs_by_key/2]).
4144
4245 :- set_prolog_flag(generate_debug_info, false).
4346
3636 [ make_tests/3, % +Module, +File, +Out
3737 make_test/3 % +Callable, -Module, -Test
3838 ]).
39 :- use_module(library(time)).
40 :- use_module(library(lists)).
41 :- use_module(library(listing)).
42 :- use_module(library(readutil)).
39 :- autoload(library(apply),[maplist/2]).
40 :- autoload(library(listing),[portray_clause/2]).
41 :- autoload(library(lists),[member/2]).
42 :- autoload(library(readutil),[read_file_to_terms/3]).
43 :- autoload(library(time),[call_with_time_limit/2]).
4344
4445 /** <module> Test Generation Wizard
4546
+0
-238
packages/readline/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
1414 rdfs.rdfs dc.rdfs eor.rdfs owl.owl rdf_library.ttl)
1515 prepend(SWIPL_SEMWEB_DATA ${CMAKE_CURRENT_SOURCE_DIR} ${SWIPL_SEMWEB_DATA})
1616
17 if(HAVE_LIBATOMIC)
18 set(RDFDB_CLIBS atomic)
19 else()
20 set(RDFDB_CLIBS)
21 endif()
22
1723 swipl_plugin(
1824 rdf_db
1925 C_SOURCES rdf_db.c atom.c md5.c atom_map.c debug.c
2026 hash.c murmur.c query.c resource.c error.c skiplist.c
2127 snapshot.c xsd.c
22 C_LIBS
28 C_LIBS ${RDFDB_CLIBS}
2329 PL_LIB_SUBDIR semweb
2430 PL_LIBS rdf_db.pl rdfs.pl rdf_edit.pl rdf_litindex.pl
2531 rdf_persistency.pl rdf_turtle.pl rdf_cache.pl
3333
3434 #ifndef PL_DEFER_FREE_H_INCLUDED
3535 #define PL_DEFER_FREE_H_INCLUDED
36 #include "memory.h"
3637
3738 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3839 This header supports freeing data in datastructures that are designed
127128 do
128129 { o = df->free_cells;
129130 last->next = o;
130 } while ( !__sync_bool_compare_and_swap(&df->free_cells, o, list) );
131 } while ( !COMPARE_AND_SWAP_PTR(&df->free_cells, o, list) );
131132 }
132133
133134
147148 } else
148149 return NULL;
149150 }
150 } while ( !__sync_bool_compare_and_swap(&df->free_cells, c, c->next) );
151 } while ( !COMPARE_AND_SWAP_PTR(&df->free_cells, c, c->next) );
151152
152153 return c;
153154 }
167168 do
168169 { o = df->freed;
169170 c->next = o;
170 } while ( !__sync_bool_compare_and_swap(&df->freed, o, c) );
171 } while ( !COMPARE_AND_SWAP_PTR(&df->freed, o, c) );
171172 }
172173
173174
185186 do
186187 { o = df->freed;
187188 c->next = o;
188 } while ( !__sync_bool_compare_and_swap(&df->freed, o, c) );
189 } while ( !COMPARE_AND_SWAP_PTR(&df->freed, o, c) );
189190 }
190191
191192
192193
193194 static inline void
194195 enter_scan(defer_free *df)
195 { __sync_add_and_fetch(&df->active, 1);
196 { ATOMIC_INC(&df->active);
196197 }
197198
198199
200201 exit_scan(defer_free *df)
201202 { defer_cell *o = df->freed;
202203
203 if ( __sync_sub_and_fetch(&df->active, 1) == 0 )
204 { if ( o && __sync_bool_compare_and_swap(&df->freed, o, NULL) )
204 if ( ATOMIC_DEC(&df->active) == 0 )
205 { if ( o && COMPARE_AND_SWAP_PTR(&df->freed, o, NULL) )
205206 { defer_cell *fl = o;
206207
207208 for(;;)
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2011-2013, VU University Amsterdam
5 Copyright (c) 2011-2020, VU University Amsterdam
66 All rights reserved.
77
88 Redistribution and use in source and binary forms, with or without
3232 */
3333
3434 #include "rdf_db.h"
35 #include "memory.h"
3536
3637
3738 /*******************************
7778
7879
7980 typedef struct prefix_cache
80 { atom_t local;
81 atom_t alias;
82 atom_t uri;
83 int generation;
84 int locked;
81 { atom_t local;
82 atom_t alias;
83 atom_t uri;
84 int generation;
85 unsigned int locked;
8586 } prefix_cache;
8687
8788 #define PREFIX_EXPAND_ENTRIES 4
113114 for(i=(++cache_ptr%PREFIX_EXPAND_ENTRIES); ; i = (i+1)%PREFIX_EXPAND_ENTRIES)
114115 { prefix_cache *c = &cache[i];
115116
116 if ( __sync_bool_compare_and_swap(&c->locked, 0, 1) )
117 if ( COMPARE_AND_SWAP_UINT(&c->locked, 0, 1) )
117118 { atom_t olocal = c->local;
118119 atom_t ouri = c->uri;
119120
145146 for( i=0; i<PREFIX_EXPAND_ENTRIES; i++)
146147 { prefix_cache *c = &cache[i];
147148
148 while( !__sync_bool_compare_and_swap(&c->locked, 0, 1) )
149 ;
149 while( !COMPARE_AND_SWAP_UINT(&c->locked, 0, 1) )
150 ; /* spin lock */
150151
151152 { atom_t olocal = c->local;
152153 atom_t ouri = c->uri;
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2011-2013, VU University Amsterdam
5 Copyright (c) 2011-2020, VU University Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
8081 #elif defined(__GNUC__) /* GCC version */
8182
8283 #define MSB(i) ((i) ? (32 - __builtin_clz(i)) : 0)
83 #define MEMORY_BARRIER() __sync_synchronize()
84 #define MEMORY_BARRIER() __atomic_thread_fence(__ATOMIC_SEQ_CST)
8485 #define PREFETCH_FOR_WRITE(p) __builtin_prefetch(p, 1, 0)
8586 #define PREFETCH_FOR_READ(p) __builtin_prefetch(p, 0, 0)
86 #define ATOMIC_ADD(ptr, v) __sync_add_and_fetch(ptr, v)
87 #define ATOMIC_SUB(ptr, v) __sync_sub_and_fetch(ptr, v)
87 #define ATOMIC_ADD(ptr, v) __atomic_add_fetch(ptr, v, __ATOMIC_SEQ_CST)
88 #define ATOMIC_SUB(ptr, v) __atomic_sub_fetch(ptr, v, __ATOMIC_SEQ_CST)
8889 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
8990 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
91
92 #define __COMPARE_AND_SWAP(at, from, to) \
93 __atomic_compare_exchange_n(at, &(from), to, FALSE, \
94 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
95
96 static inline int
97 COMPARE_AND_SWAP_PTR(void *at, void *from, void *to)
98 { void **ptr = at;
99
100 return __COMPARE_AND_SWAP(ptr, from, to);
101 }
102
103 static inline int
104 COMPARE_AND_SWAP_UINT(unsigned int *at, unsigned int from, unsigned int to)
105 { return __COMPARE_AND_SWAP(at, from, to);
106 }
107
90108
91109 #endif /*_MSC_VER|__GNUC__*/
92110
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2003-2016, University of Amsterdam
5 Copyright (c) 2003-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
10881088 do
10891089 { o = a->freelist;
10901090 last->fnext = o;
1091 } while ( !__sync_bool_compare_and_swap(&a->freelist, o, list) );
1091 } while ( !COMPARE_AND_SWAP_PTR(&a->freelist, o, list) );
10921092 }
10931093
10941094 static int
11641164 resize_triple_array(db);
11651165 simpleMutexUnlock(&db->locks.misc);
11661166 }
1167 } while ( !__sync_bool_compare_and_swap(&a->freelist, e, e->fnext) );
1167 } while ( !COMPARE_AND_SWAP_PTR(&a->freelist, e, e->fnext) );
11681168
11691169 e->triple = t;
11701170
579579 rdf_meta_specification(G, IM, Spec),
580580 rdf_expand(G, Spec, Expanded, LM).
581581
582 system:term_expansion(Module:Fact, Expanded) :-
583 atom(Module),
584 rdf_meta_specification(Fact, Module, Spec),
585 rdf_expand(Fact, Spec, ExpandedFact, Module),
586 Fact \== ExpandedFact,
587 Expanded = (Module:ExpandedFact).
582588 system:term_expansion(Fact, Expanded) :-
583589 prolog_load_context(module, Module),
584590 rdf_meta_specification(Fact, Module, Spec),
585591 rdf_expand(Fact, Spec, Expanded, Module),
586592 Fact \== Expanded.
593 system:term_expansion((Module:Head :- Body), (Expanded :- Body)) :-
594 atom(Module),
595 rdf_meta_specification(Head, Module, Spec),
596 rdf_expand(Head, Spec, ExpandedHead, Module),
597 Head \== ExpandedHead,
598 Expanded = (Module:ExpandedHead).
587599 system:term_expansion((Head :- Body), (Expanded :- Body)) :-
588600 prolog_load_context(module, Module),
589601 rdf_meta_specification(Head, Module, Spec),
3838 #include <string.h>
3939 #include <stdlib.h>
4040 #include "skiplist.h"
41 #include "memory.h"
4142
4243 static int debuglevel;
4344
8687 { n0 = next;
8788
8889 n = n0 * 1103515245 + 12345;
89 } while(n != n0 && !__sync_bool_compare_and_swap(&next, n0, n));
90 } while(n != n0 && !COMPARE_AND_SWAP_UINT(&next, n0, n));
9091
9192 return((unsigned int)(n/65536) % 32768);
9293 }
9393 % modifications on g2 (in a snapshot).
9494
9595 test(N) :-
96 test(g1, N).
96 test(-, N).
9797
9898 test(G, N*M) :-
9999 !,
262262 :- dynamic
263263 record_stream/2. % Graph, Out
264264
265 record_in(-, -) :-
266 !.
265267 record_in(Graph, Out) :-
266268 file_name_extension(Graph, rec, File),
267269 open(File, write, Out),
2525 PL_LIBS ${DTD_FILES}
2626 THREADED)
2727
28 test_libs(sgml sgml_write xsd
29 TEST_DIRS Test)
28 test_libs(sgml sgml_write xsd c14n
29 TEST_DIRS Test testdata)
3030
3131 pkg_doc(sgml
3232 SECTION
152152 put_elemns(Name, CName, InNS, OutNS0, OutNS, []) :-
153153 put_ns(Name, CName, InNS, OutNS0, OutNS).
154154
155 put_ns(ns('', xml):Name, xml:Name, _InNS, OutNS, OutNS) :-
156 !.
155157 put_ns(ns(NS, URL):Name, CName, _InNS, OutNS, OutNS) :-
156158 get_dict(URL, OutNS, NS),
157159 !,
671671
672672 add_missing_ns([], Atts, Atts).
673673 add_missing_ns([H|T], Atts0, Atts) :-
674 generate_ns(H, NS),
675 add_missing_ns(T, [xmlns:NS=H|Atts0], Atts).
676
677 %! generate_ns(+URI, -NS) is det.
674 generate_ns(H, NS, URL),
675 add_missing_ns(T, [xmlns:NS=URL|Atts0], Atts).
676
677 %! generate_ns(+URI, -NS, -URL) is det.
678678 %
679679 % Generate a namespace (NS) identifier for URI.
680680
681 generate_ns(URI, NS) :-
681 generate_ns(URI, NS, URI) :-
682682 xmlns(NS, URI),
683683 !.
684 generate_ns(URI, NS) :-
684 generate_ns(ns(NS, URI), NS, URI) :-
685 !.
686 generate_ns(URI, NS, URI) :-
685687 default_ns(URI, NS),
686688 !.
687 generate_ns(_, NS) :-
689 generate_ns(URI, NS, URI) :-
688690 gensym(xns, NS).
689691
690692 %! xmlns(?NS, ?URI) is nondet.
745747
746748 missing_ns(ns(NS, URI):_, Def, M0, M) :-
747749 !,
748 ( memberchk(NS=URI, Def)
750 ( ( memberchk(NS=URI, Def)
751 ; memberchk(NS=URI, M0)
752 )
749753 -> M = M0
750754 ; NS == ''
751755 -> M = M0
752 ; M = [URI|M0]
756 ; M = [ns(NS, URI)|M0]
753757 ).
754758 missing_ns(URI:_, Def, M0, M) :-
755759 !,
0 /* Part of SWI-Prolog
1
2 Author: Matt Lilley
3 E-mail: matt.lilley@securitease.com
4 WWW: http://www.swi-prolog.org
5 Copyright (c) 2013-2020, University of Amsterdam
6 VU University Amsterdam
7 CWI, Amsterdam
8 All rights reserved.
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 :- module(test_c14n,
37 [ test_c14n/0
38 ]).
39
40 :- use_module(library(c14n2)).
41
42 test_c14n :-
43 run_tests([ c14n ]).
44
45 :-begin_tests(c14n).
46
47
48 %! xml_file(+File, -Absolute)
49 %
50 % Find an absolute path to the xml sample data in the `testdata` directory.
51
52 xml_file(File, Abs) :-
53 source_file(xml_file(_,_), MyFile),
54 file_directory_name(MyFile, MyDir),
55 atomic_list_concat([MyDir, File], /, Abs).
56
57 %! c14n_test(+InputFile, +XPath, +TargetFile).
58 %
59 % Canonicalize the document obtained by applying the XPath specification to
60 % the document specified by InputFile and confirm it matches exactly the
61 % bytes in TargetFile.
62 % The XPath specification is a shorthand for logic that a built-in XPath
63 % expression cannot directly express
64
65 c14n_test(InputFile, XPathSpec, TargetFile):-
66 xml_file(InputFile, InputFilename),
67 xml_file(TargetFile, TargetFilename),
68 setup_call_cleanup(open(InputFilename, read, InputStream),
69 load_structure(InputStream, InputDocument, [dialect(xmlns), space(preserve), keep_prefix(true)]),
70 close(InputStream)),
71 setup_call_cleanup(open(TargetFilename, read, TargetStream),
72 read_string(TargetStream, _, TargetDocument),
73 close(TargetStream)),
74 findall(SubDocument,
75 extract_subdocument(InputDocument, XPathSpec, SubDocument),
76 SubDocuments),
77 with_output_to(string(GeneratedDocument),
78 forall(member(SubDocument, SubDocuments),
79 xml_write_canonical(current_output, SubDocument, [method('http://www.w3.org/2001/10/xml-exc-c14n#')]))),
80 %format(user_error, '~w~n~n', [GeneratedDocument]),
81 TargetDocument == GeneratedDocument.
82
83 extract_subdocument(InputDocument, (A ; B), SubDocument):-
84 !,
85 ( extract_subdocument(InputDocument, A, SubDocument)
86 ; extract_subdocument(InputDocument, B, SubDocument)
87 ).
88
89 extract_subdocument(InputDocument, (A, \+B), SubDocument):-
90 !,
91 extract_subdocument(InputDocument, A, Intermediate),
92 delete_subdocument([Intermediate], B, [SubDocument]).
93
94 extract_subdocument(InputDocument, ElementName, SubDocument):-
95 xpath(InputDocument, //(_:ElementName), SubDocument).
96
97 delete_subdocument(Document, (A ; B), SubDocument):-
98 !,
99 delete_subdocument(Document, A, S1),
100 delete_subdocument(S1, B, SubDocument).
101
102 delete_subdocument([], _, []):- !.
103
104 delete_subdocument(Document, Element, Document):-
105 % Nothing to do - fail quickly
106 \+xpath_chk(Document, //(_:Element), _),
107 !.
108
109 delete_subdocument([element(_:Element, _, _)|Siblings], Element, NewSiblings):-
110 !,
111 delete_subdocument(Siblings, Element, NewSiblings).
112
113 delete_subdocument([element(NS:OtherElement, Attributes, Children)|Siblings], Element, [element(NS:OtherElement, Attributes, NewChildren)|NewSiblings]):-
114 !,
115 delete_subdocument(Children, Element, NewChildren),
116 delete_subdocument(Siblings, Element, NewSiblings).
117
118 delete_subdocument([Atom|Siblings], Element, [Atom|NewSiblings]):-
119 delete_subdocument(Siblings, Element, NewSiblings).
120
121
122
123 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
124 These tests are derived from the w3c tests available at
125 https://www.w3.org/TR/xmldsig2ed-tests/#TestCases-C14n11
126 The input/target documents are stored in testdata/
127 The xpath expressions are encoded inline in the tests. This is because the
128 SWI-Prolog implementation of xpath is not syntax-compatible with the w3c one
129 The test names include the section of the source document they pertain to
130 Note that the tests originally are for xml-c14n and not xml-c14n-exc
131 I have extracted the equivalent *-exc.output documents using xmlstarlet and
132 the appropriate xpath files
133 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
134
135 test('3.2.1.1 Test case c14n11/xmllang-1'):-
136 c14n_test('testdata/xmllang-input.xml', e1, 'testdata/xmllang-1-exc.output').
137
138 test('3.2.1.2 Test case c14n11/xmllang-2'):-
139 c14n_test('testdata/xmllang-input.xml', e2, 'testdata/xmllang-2-exc.output').
140
141 test('3.2.1.3 Test case c14n11/xmllang-3'):-
142 c14n_test('testdata/xmllang-input.xml', e11, 'testdata/xmllang-3-exc.output').
143
144 test('3.2.1.4 Test case c14n11/xmllang-4'):-
145 c14n_test('testdata/xmllang-input.xml', (e11 ; e12), 'testdata/xmllang-4-exc.output').
146
147 % These 4 tests all produce an SGML warning that xml:space="true" is invalid
148 % It is indeed invalid, but that is what is in the official input document
149 test('3.2.2.1 Test case c14n11/xmlspace-1'):-
150 c14n_test('testdata/xmlspace-input.xml', e1, 'testdata/xmlspace-1-exc.output').
151
152 test('3.2.2.2 Test case c14n11/xmlspace-2'):-
153 c14n_test('testdata/xmlspace-input.xml', e2, 'testdata/xmlspace-2-exc.output').
154
155 test('3.2.2.3 Test case c14n11/xmlspace-3'):-
156 c14n_test('testdata/xmlspace-input.xml', e11, 'testdata/xmlspace-3-exc.output').
157
158 test('3.2.2.4 Test case c14n11/xmlspace-4'):-
159 c14n_test('testdata/xmlspace-input.xml', (e11 ; e12), 'testdata/xmlspace-4-exc.output').
160
161 test('3.2.3.1 Test case c14n11/xmlid-1'):-
162 c14n_test('testdata/xmlid-input.xml', e1, 'testdata/xmlid-1-exc.output').
163
164 test('3.2.3.2 Test case c14n11/xmlid-2'):-
165 c14n_test('testdata/xmlid-input.xml', (e11 ; e12), 'testdata/xmlid-2-exc.output').
166
167 test('3.2.4.1,1 Test case c14n11/xmlbase-prop-1'):-
168 c14n_test('testdata/xmlbase-prop-input.xml', (c14n11XmlBaseDoc1, \+e2), 'testdata/xmlbase-prop-1-exc.output').
169
170 test('3.2.4.1.2 Test case c14n11/xmlbase-prop-2'):-
171 c14n_test('testdata/xmlbase-prop-input.xml', e1, 'testdata/xmlbase-prop-2-exc.output').
172
173 test('3.2.4.1.3 Test case c14n11/xmlbase-prop-3'):-
174 c14n_test('testdata/xmlbase-prop-input.xml', e11, 'testdata/xmlbase-prop-3-exc.output').
175
176 test('3.2.4.1.4 Test case c14n11/xmlbase-prop-4'):-
177 c14n_test('testdata/xmlbase-prop-input.xml', e111, 'testdata/xmlbase-prop-4-exc.output').
178
179 test('3.2.4.1.5 Test case c14n11/xmlbase-prop-5'):-
180 c14n_test('testdata/xmlbase-prop-input.xml', e21, 'testdata/xmlbase-prop-5-exc.output').
181
182 test('3.2.4.1.6 Test case c14n11/xmlbase-prop-6'):-
183 c14n_test('testdata/xmlbase-prop-input.xml', e3, 'testdata/xmlbase-prop-6-exc.output').
184
185 test('3.2.4.1.7 Test case c14n11/xmlbase-prop-7'):-
186 c14n_test('testdata/xmlbase-prop-input.xml', (c14n11XmlBaseDoc1, \+(e1 ; e2)), 'testdata/xmlbase-prop-7-exc.output').
187
188 test('3.2.4.2.1 Test case c14n11/xmlbase-c14n11spec-102', [blocked('Cannot express [self::ietf:e1 or (parent::ietf:e1 and not(self::text() or self::e2)) or count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node())] using builtin xpath')]):-
189 c14n_test('testdata/xmlbase-c14n11spec-input.xml', unknown, 'xmlbase-c14n11spec-102.output').
190
191 test('3.2.4.2.2 Test case c14n11/xmlbase-c14n11spec-102', [blocked('Cannot express [self::ietf:e1 or (parent::ietf:e1 and not(self::text() or self::e2)) or count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node())] using builtin xpath')]):-
192 c14n_test('testdata/xmlbase-c14n11spec2-input.xml', unknown, 'xmlbase-c14n11spec2-102.output').
193
194 test('3.2.4.2.3 Test case c14n11/xmlbase-c14n11spec-102', [blocked('Cannot express [self::a or ancestor-or-self::d] using builtin xpath')]):-
195 c14n_test('testdata/xmlbase-c14n11spec3-input.xml', unknown 'xmlbase-c14n11spec3-102.output').
196
197
198 :-end_tests(c14n).
44 user:file_search_path(library, '../plunit').
55
66 :- use_module(library(sgml)).
7 :- use_module(library(apply)).
78 :- use_module(library(debug)).
89 :- use_module(library(plunit)).
910
0 <e1 xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://www.example.com/something/else"><e3 xmlns="" id="E3" xml:base="../bar/foo" xml:space="preserve"></e3></e1>
0 <!DOCTYPE doc [
1 <!ATTLIST e2 xml:space (default|preserve) 'preserve'>
2 <!ATTLIST e3 id ID #IMPLIED>
3 ]>
4 <doc xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://www.example.com/something/else">
5 <e1>
6 <e2 xmlns="" xml:id="abc" xml:base="../bar/">
7 <e3 id="E3" xml:base="foo"/>
8 </e2>
9 </e1>
10 </doc>
0 <e1 xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="something/else"><e3 xmlns="" id="E3" xml:base="bar/foo" xml:space="preserve"></e3></e1>
0 <!DOCTYPE doc [
1 <!ATTLIST e2 xml:space (default|preserve) 'preserve'>
2 <!ATTLIST e3 id ID #IMPLIED>
3 ]>
4 <doc xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="something/else">
5 <e1>
6 <e2 xmlns="" xml:id="abc" xml:base="bar/">
7 <e3 id="E3" xml:base="foo"/>
8 </e2>
9 </e1>
10 </doc>
0 <a xml:base="foo/bar"><d xml:base="../../x">
1 </d></a>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <a xml:base="foo/bar">
2 <b xml:base="..">
3 <c xml:base="..">
4 <d xml:base="x">
5 </d>
6 </c>
7 </b>
8 </a>
0 <ietf:c14n11XmlBaseDoc1 xmlns:ietf="http://www.ietf.org" xml:base="http://xmlbase.example.org/xmlbase0/">
1 <ietf:e1 xml:base="/xmlbase1/">
2 <ietf:e11 xml:base="/xmlbase11/">
3 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
4 </ietf:e11>
5 <ietf:e12 at="2">
6 <ietf:e121 xml:base="/xmlbase121/"></ietf:e121>
7 </ietf:e12>
8 </ietf:e1>
9
10 <ietf:e3>
11 <ietf:e31 at="3"></ietf:e31>
12 </ietf:e3>
13 </ietf:c14n11XmlBaseDoc1>
0 <ietf:c14n11XmlBaseDoc1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase0/">
1 <ietf:e1 xml:base="/xmlbase1/">
2 <ietf:e11 xml:base="/xmlbase11/">
3 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
4 </ietf:e11>
5 <ietf:e12 at="2">
6 <ietf:e121 xml:base="/xmlbase121/"></ietf:e121>
7 </ietf:e12>
8 </ietf:e1>
9
10 <ietf:e3>
11 <ietf:e31 at="3"></ietf:e31>
12 </ietf:e3>
13 </ietf:c14n11XmlBaseDoc1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:c14n11XmlBaseDoc1 and not(ancestor-or-self::ietf:e2)]</XPath>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xml:base="/xmlbase1/">
1 <ietf:e11 xml:base="/xmlbase11/">
2 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121 xml:base="/xmlbase121/"></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase1/">
1 <ietf:e11 xml:base="/xmlbase11/">
2 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121 xml:base="/xmlbase121/"></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e1]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xml:base="/xmlbase11/">
1 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
2 </ietf:e11>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase11/">
1 <ietf:e111 xml:base="/xmlbase111/"></ietf:e111>
2 </ietf:e11>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e11]</XPath>
0 <ietf:e111 xmlns:ietf="http://www.ietf.org" xml:base="/xmlbase111/"></ietf:e111>
0 <ietf:e111 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase111/"></ietf:e111>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e111]</XPath>
0 <ietf:e21 xmlns:ietf="http://www.ietf.org" xml:base="/xmlbase21/"></ietf:e21>
0 <ietf:e21 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase21/"></ietf:e21>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e21]</XPath>
0 <ietf:e3 xmlns:ietf="http://www.ietf.org">
1 <ietf:e31 at="3"></ietf:e31>
2 </ietf:e3>
0 <ietf:e3 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase0/">
1 <ietf:e31 at="3"></ietf:e31>
2 </ietf:e3>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e3]</XPath>
0 <ietf:c14n11XmlBaseDoc1 xmlns:ietf="http://www.ietf.org" xml:base="http://xmlbase.example.org/xmlbase0/">
1
2
3 <ietf:e3>
4 <ietf:e31 at="3"></ietf:e31>
5 </ietf:e3>
6 </ietf:c14n11XmlBaseDoc1>
0 <ietf:c14n11XmlBaseDoc1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase0/">
1
2
3 <ietf:e3>
4 <ietf:e31 at="3"></ietf:e31>
5 </ietf:e3>
6 </ietf:c14n11XmlBaseDoc1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:c14n11XmlBaseDoc1 and not(ancestor-or-self::ietf:e1 or ancestor-or-self::ietf:e2)]</XPath>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <ietf:c14n11XmlBaseDoc1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:base="http://xmlbase.example.org/xmlbase0/">
2 <ietf:e1 xml:base="/xmlbase1/">
3 <ietf:e11 xml:base="/xmlbase11/">
4 <ietf:e111 xml:base="/xmlbase111/"/>
5 </ietf:e11>
6 <ietf:e12 at="2">
7 <ietf:e121 xml:base="/xmlbase121/"/>
8 </ietf:e12>
9 </ietf:e1>
10 <ietf:e2>
11 <ietf:e21 xml:base="/xmlbase21/"/>
12 </ietf:e2>
13 <ietf:e3>
14 <ietf:e31 at="3"/>
15 </ietf:e3>
16 </ietf:c14n11XmlBaseDoc1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xml:id="IdInterop">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:id="IdInterop">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e1]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" at="2">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" at="2">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e11 or ancestor-or-self::ietf:e12]</XPath>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <ietf:c14n11XmlIdDoc1 xmlns:ietf="http://www.ietf.org"
2 xmlns:w3c="http://www.w3.org">
3 <ietf:e1 xml:id="IdInterop">
4 <ietf:e11>
5 <ietf:e111 />
6 </ietf:e11>
7 <ietf:e12 at="2">
8 <ietf:e121 />
9 </ietf:e12>
10 </ietf:e1>
11 <ietf:e2 >
12 <ietf:e21 />
13 </ietf:e2>
14 </ietf:c14n11XmlIdDoc1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xml:lang="EN">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:lang="EN">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*)[ancestor-or-self::ietf:e1]</XPath>
0 <ietf:e2 xmlns:ietf="http://www.ietf.org">
1 <ietf:e21></ietf:e21>
2 </ietf:e2>
0 <ietf:e2 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org">
1 <ietf:e21></ietf:e21>
2 </ietf:e2>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*)[ancestor-or-self::ietf:e2]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:lang="EN">
1 <ietf:e111></ietf:e111>
2 </ietf:e11>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*)[ancestor-or-self::ietf:e11]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" at="2">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:lang="EN">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" at="2" xml:lang="EN">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*)[ancestor-or-self::ietf:e11 or ancestor-or-self::ietf:e12]</XPath>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <ietf:c14n11Xmllang xmlns:ietf="http://www.ietf.org"
2 xmlns:w3c="http://www.w3.org">
3 <ietf:e1 xml:lang="EN">
4 <ietf:e11>
5 <ietf:e111 />
6 </ietf:e11>
7 <ietf:e12 at="2">
8 <ietf:e121 />
9 </ietf:e12>
10 </ietf:e1>
11 <ietf:e2 >
12 <ietf:e21 />
13 </ietf:e2>
14 </ietf:c14n11Xmllang>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xml:space="true">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <ietf:e1 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:space="true">
1 <ietf:e11>
2 <ietf:e111></ietf:e111>
3 </ietf:e11>
4 <ietf:e12 at="2">
5 <ietf:e121></ietf:e121>
6 </ietf:e12>
7 </ietf:e1>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e1]</XPath>
0 <ietf:e2 xmlns:ietf="http://www.ietf.org">
1 <ietf:e21></ietf:e21>
2 </ietf:e2>
0 <ietf:e2 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org">
1 <ietf:e21></ietf:e21>
2 </ietf:e2>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e2]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:space="true">
1 <ietf:e111></ietf:e111>
2 </ietf:e11>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e11]</XPath>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" at="2">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <ietf:e11 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" xml:space="true">
1 <ietf:e111></ietf:e111>
2 </ietf:e11><ietf:e12 xmlns:ietf="http://www.ietf.org" xmlns:w3c="http://www.w3.org" at="2" xml:space="true">
3 <ietf:e121></ietf:e121>
4 </ietf:e12>
0 <XPath xmlns:ietf="http://www.ietf.org">(//. | //@* | //namespace::*) [ancestor-or-self::ietf:e11 or ancestor-or-self::ietf:e12]</XPath>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <ietf:c14n11XmlSpaceDoc1 xmlns:ietf="http://www.ietf.org"
2 xmlns:w3c="http://www.w3.org">
3 <ietf:e1 xml:space="true">
4 <ietf:e11>
5 <ietf:e111 />
6 </ietf:e11>
7 <ietf:e12 at="2">
8 <ietf:e121 />
9 </ietf:e12>
10 </ietf:e1>
11 <ietf:e2 >
12 <ietf:e21 />
13 </ietf:e2>
14 </ietf:c14n11XmlSpaceDoc1>
163163
164164 if(INSTALL_TESTS)
165165 install(FILES https.pl
166 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl)
166 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl
167 COMPONENT Tests)
167168 install(DIRECTORY etc
168 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl)
169 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl
170 COMPONENT Tests)
169171 install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests
170 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl)
172 DESTINATION ${INSTALL_TESTS_DIR}/packages/ssl
173 COMPONENT Tests)
171174 endif()
172175 endif()
173176 endif(BUILD_TESTING)
223226 install_src(pkg_ssl_etc
224227 DIRECTORY etc
225228 DESTINATION
226 ${SWIPL_INSTALL_PREFIX}/doc/packages/examples/${SWIPL_PKG})
229 ${SWIPL_INSTALL_SHARE_PREFIX}/doc/packages/examples/${SWIPL_PKG}
230 COMPONENT Examples)
227231
228232 pkg_doc(ssl
229233 SOURCES
286286 /*
287287 * Control function. Currently only supports flushing and detecting EOF.
288288 * There are several more mandatory, but as-yet unsupported functions...
289 *
290 * We should not consider a timeout to be end-of-file. If we do so,
291 * OpenSSL as of 1.1.1e will propagate this as an SSL_ERROR_SSL and we
292 * cannot resume the connection. Note that the TIMEOUT flag is cleared
293 * by the next read operation. Also, if this flag is set, the last read
294 * operation did call Sfillbuf(), and we thus do know the buffer is
295 * empty. Diagnosed by Matt Lilley.
289296 */
290297
291298 static long
298305 Sflush(stream);
299306 return 1;
300307 case BIO_CTRL_EOF:
301 return Sfeof(stream);
308 return !(stream->flags&SIO_TIMEOUT) && Sfeof(stream);
302309 }
303310
304311 return 0;
11 Data:
22 Version: 3 (0x2)
33 Serial Number:
4 a6:11:83:6b:46:29:8a:72
5 Signature Algorithm: sha1WithRSAEncryption
4 9d:c0:87:97:a0:f6:3f:7c
5 Signature Algorithm: sha256WithRSAEncryption
66 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
77 Validity
8 Not Before: Jul 3 15:11:14 2008 GMT
9 Not After : Nov 19 15:11:14 2035 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=University of Amsterdam, OU=Client, CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
8 Not Before: Apr 1 09:34:34 2020 GMT
9 Not After : Apr 1 09:34:34 2021 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=Diff Automatisering, OU=Client, CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
1111 Subject Public Key Info:
1212 Public Key Algorithm: rsaEncryption
13 RSA Public Key: (1024 bit)
14 Modulus (1024 bit):
15 00:b0:f8:4b:6f:fb:04:72:e5:79:5e:07:14:45:d3:
16 9d:4f:2f:ab:ee:ba:6e:07:52:ce:34:37:b5:4b:31:
17 a8:0f:02:a5:24:bb:41:37:6c:2f:17:e2:7f:fe:c0:
18 2a:84:6d:e7:3b:fb:b9:4a:df:09:ea:0d:47:2a:d0:
19 fe:7b:82:12:ca:6b:5f:70:bb:a5:91:a3:d0:f9:4c:
20 c7:7b:4b:8d:7f:a7:6a:f9:27:34:32:43:7b:f2:e4:
21 d6:8f:d2:42:ed:21:28:1c:67:62:6e:84:75:ab:da:
22 90:a8:1e:09:70:47:c5:51:ae:d1:74:88:73:74:e7:
23 65:f3:ea:4d:e0:75:a6:64:6f
13 Public-Key: (2048 bit)
14 Modulus:
15 00:a4:cf:45:ac:02:9b:ba:01:48:79:50:2f:f4:58:
16 7b:e0:47:c8:0e:12:9c:f6:9f:29:71:24:e4:41:cc:
17 02:45:03:51:5f:34:69:da:b6:7d:83:29:dd:c7:d8:
18 e0:05:29:9c:7e:a9:a0:31:83:53:3c:df:17:fb:12:
19 da:1a:c3:6b:44:78:b3:17:9b:44:f7:8d:3e:12:5f:
20 cc:31:58:a7:20:ab:d3:dd:45:c7:52:99:d2:48:8b:
21 72:85:d3:bb:04:cd:f9:e0:b7:56:ab:79:b7:66:40:
22 c7:e8:7a:52:ed:ed:55:1b:db:5b:1d:9b:dd:0e:ad:
23 68:2d:c3:da:67:3c:be:6e:08:8f:a3:88:2a:d7:27:
24 0d:b6:90:f0:2d:a8:0b:54:db:95:ba:b9:0a:67:f4:
25 00:65:a0:a7:cf:81:2e:e5:6a:52:6b:18:28:74:82:
26 9f:52:14:11:96:d1:dd:23:25:74:70:81:1e:41:00:
27 ec:65:3b:ac:18:30:06:f6:ed:58:d7:2c:0f:77:fa:
28 53:7c:40:02:e5:70:4a:b8:e0:b3:7b:c5:34:93:f1:
29 77:af:2f:37:a6:09:c9:e6:3d:c4:0f:15:d7:8e:6c:
30 3c:10:ab:2a:5f:38:77:b1:7d:f1:06:6d:49:1e:5a:
31 0f:26:68:fc:eb:e7:c9:b1:b7:87:4e:a6:12:de:b5:
32 5a:1b
2433 Exponent: 65537 (0x10001)
2534 X509v3 extensions:
2635 X509v3 Basic Constraints:
2837 Netscape Comment:
2938 OpenSSL Generated Certificate
3039 X509v3 Subject Key Identifier:
31 F1:3E:D8:C4:80:01:24:70:79:03:AB:76:81:A4:4F:50:A8:F1:B2:FD
40 BD:79:A2:A6:3C:EC:1A:80:75:8D:60:9B:A6:F9:02:6B:C0:ED:E4:8A
3241 X509v3 Authority Key Identifier:
33 keyid:20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
42 keyid:E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
3443
35 Signature Algorithm: sha1WithRSAEncryption
36 2d:9f:13:8b:ca:d6:0a:f0:ef:75:52:ab:a0:fe:6f:f1:14:16:
37 f9:4e:f5:77:ac:55:9b:bb:31:d3:fa:e5:4f:9a:83:91:7d:c5:
38 90:b1:94:d1:1b:3b:a2:b4:fa:5f:43:79:20:ec:b2:48:61:fc:
39 bf:75:25:75:64:2d:c6:02:61:4b:4a:d9:50:eb:bc:ba:e7:cb:
40 31:91:f2:18:6b:62:8f:e4:29:ea:83:29:54:53:05:40:5c:86:
41 11:d2:56:0d:4a:39:f6:b4:f0:78:86:98:15:da:3a:cd:86:7e:
42 c0:bc:71:dc:7d:69:f8:0b:56:17:a3:3b:6d:e3:65:73:1d:64:
43 21:f0
44 Signature Algorithm: sha256WithRSAEncryption
45 45:62:87:35:99:a7:74:b9:de:08:7c:2f:41:f5:c8:1e:3e:df:
46 c6:54:f3:e4:fa:25:a7:7b:8f:b3:1e:89:d2:83:97:50:fd:84:
47 c8:53:1d:ab:9c:61:80:44:5f:72:29:6b:59:35:ab:11:45:42:
48 4f:0b:02:88:55:b9:4b:40:9a:b0:0b:ed:aa:a6:7a:44:b1:f6:
49 01:f2:3c:fd:54:d5:93:8b:9a:68:18:ed:77:c3:39:79:f5:59:
50 c2:7a:7f:d0:03:b1:a5:d8:27:62:c8:33:06:7c:c5:26:32:cd:
51 92:ce:b0:2e:7f:16:e8:e3:3f:28:8e:b3:66:cd:a5:b1:64:db:
52 33:0f:c6:12:f3:22:66:0f:6f:b2:1c:fb:81:bb:a4:ad:c8:27:
53 9f:62:72:44:9b:b7:da:3c:10:0e:95:87:33:91:59:a3:0c:ca:
54 d9:15:f0:de:52:25:f9:14:16:da:69:d8:af:00:87:f8:f1:6f:
55 26:07:9a:f7:4e:ad:07:23:ef:e2:aa:94:b2:45:2a:f7:55:65:
56 e4:59:ee:1c:5d:69:64:4f:b3:2f:a7:54:03:36:05:10:8a:43:
57 3c:ce:8c:97:91:b6:17:4b:85:ab:a9:51:8f:de:1a:89:4b:1e:
58 5f:39:47:b3:ab:cc:14:f4:c6:ba:d3:4a:6f:6a:fe:aa:2d:2c:
59 81:53:9a:53
4460 -----BEGIN CERTIFICATE-----
45 MIIDOzCCAqSgAwIBAgIJAKYRg2tGKYpyMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
46 VQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBB
47 dXRvbWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQ
61 MIIEPjCCAyagAwIBAgIJAJ3Ah5eg9j98MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
62 VQQGEwJOTDEWMBQGA1UECAwNTm9vcmQtSG9sbGFuZDEcMBoGA1UECgwTRGlmZiBB
63 dXRvbWF0aXNlcmluZzEWMBQGA1UECwwNU3VwcG9ydCBncm91cDEZMBcGA1UEAwwQ
4864 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
49 DTA4MDcwMzE1MTExNFoXDTM1MTExOTE1MTExNFowga0xCzAJBgNVBAYTAk5MMRYw
50 FAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNV
51 BAoTF1VuaXZlcnNpdHkgb2YgQW1zdGVyZGFtMQ8wDQYDVQQLEwZDbGllbnQxFzAV
52 BgNVBAMTDkphbiBXaWVsZW1ha2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0Bz
53 Y2llbmNlLnV2YS5ubDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsPhLb/sE
54 cuV5XgcURdOdTy+r7rpuB1LONDe1SzGoDwKlJLtBN2wvF+J//sAqhG3nO/u5St8J
55 6g1HKtD+e4ISymtfcLulkaPQ+UzHe0uNf6dq+Sc0MkN78uTWj9JC7SEoHGdiboR1
56 q9qQqB4JcEfFUa7RdIhzdOdl8+pN4HWmZG8CAwEAAaN7MHkwCQYDVR0TBAIwADAs
57 BglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYD
58 VR0OBBYEFPE+2MSAASRweQOrdoGkT1Co8bL9MB8GA1UdIwQYMBaAFCAbQOQAGHzm
59 Z3qAFv4VB569dycmMA0GCSqGSIb3DQEBBQUAA4GBAC2fE4vK1grw73VSq6D+b/EU
60 FvlO9XesVZu7MdP65U+ag5F9xZCxlNEbO6K0+l9DeSDsskhh/L91JXVkLcYCYUtK
61 2VDrvLrnyzGR8hhrYo/kKeqDKVRTBUBchhHSVg1KOfa08HiGmBXaOs2GfsC8cdx9
62 afgLVhejO23jZXMdZCHw
65 DTIwMDQwMTA5MzQzNFoXDTIxMDQwMTA5MzQzNFowgasxCzAJBgNVBAYTAk5MMRYw
66 FAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHDAlBbXN0ZXJkYW0xHDAaBgNV
67 BAoME0RpZmYgQXV0b21hdGlzZXJpbmcxDzANBgNVBAsMBkNsaWVudDEZMBcGA1UE
68 AwwQSi4gdmFuIGRlciBTdGVlbjEmMCQGCSqGSIb3DQEJARYXSi52YW4uZGVyLlN0
69 ZWVuQGRpZmYubmwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkz0Ws
70 Apu6AUh5UC/0WHvgR8gOEpz2nylxJORBzAJFA1FfNGnatn2DKd3H2OAFKZx+qaAx
71 g1M83xf7Etoaw2tEeLMXm0T3jT4SX8wxWKcgq9PdRcdSmdJIi3KF07sEzfngt1ar
72 ebdmQMfoelLt7VUb21sdm90OrWgtw9pnPL5uCI+jiCrXJw22kPAtqAtU25W6uQpn
73 9ABloKfPgS7lalJrGCh0gp9SFBGW0d0jJXRwgR5BAOxlO6wYMAb27VjXLA93+lN8
74 QALlcEq44LN7xTST8XevLzemCcnmPcQPFdeObDwQqypfOHexffEGbUkeWg8maPzr
75 58mxt4dOphLetVobAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8W
76 HU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBS9eaKmPOwa
77 gHWNYJum+QJrwO3kijAfBgNVHSMEGDAWgBTie2CMd7uydLj91iyp07k1lxKH7DAN
78 BgkqhkiG9w0BAQsFAAOCAQEARWKHNZmndLneCHwvQfXIHj7fxlTz5Polp3uPsx6J
79 0oOXUP2EyFMdq5xhgERfcilrWTWrEUVCTwsCiFW5S0CasAvtqqZ6RLH2AfI8/VTV
80 k4uaaBjtd8M5efVZwnp/0AOxpdgnYsgzBnzFJjLNks6wLn8W6OM/KI6zZs2lsWTb
81 Mw/GEvMiZg9vshz7gbukrcgnn2JyRJu32jwQDpWHM5FZowzK2RXw3lIl+RQW2mnY
82 rwCH+PFvJgea906tByPv4qqUskUq91Vl5FnuHF1pZE+zL6dUAzYFEIpDPM6Ml5G2
83 F0uFq6lRj94aiUseXzlHs6vMFPTGutNKb2r+qi0sgVOaUw==
6384 -----END CERTIFICATE-----
0 -----BEGIN RSA PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: DES-EDE3-CBC,2A0D4B5A7F746951
3
4 PVt0XRMXqvvZpSyfsPlDjXlemkSeqA4hGSq+FXyCE2vY7jF6nG8OEyFLzBQK1QHb
5 /rGNrX81s3vwuqAhtikM8CtBbLCyKXKzv5gka6f0FoD2TfcLZxQyO98AK7mY70/i
6 gPYN+8hsl/riEtdTrMIbD/4hVGivgVS592iFpfFyjuv/utgJF/gEqMS3J7IPwF7q
7 NvqWHQ0N1RBQdHv0zLjqpi582h/XagqOGzO0ShtesSgDw6WDxAztJXGzjb8aOA2a
8 EvU6zdhKYVdvwGySIEJ0CVE8Mawmp1rBIPNGSl6MPP8lb4zGSsX6kraAb9ZFaZqr
9 TjZv438VlzMILtSOzHguT49gpjkqSf/3erQ9GLo+CYGZToQXbyUSKhTCxO37sQxU
10 +tWZfXyDp8s5NJV5G3y+wrPFq4TKkPe+F11cerX/IsIefUaLCDMWCohVY2g05e9H
11 puWkGxj8Ry/ca1Y7IPmSj/tqtH36I1beio9m0tMSc/cZM9AYAS/gvUUGCTvSUouV
12 HO5lTrTc0frRF9fbMDLrlziS6IZbyJEN32irEiSF2UkQRsf3O3mdmV/UJ2U55gLy
13 /lbe+qD0imjMZOk+pFmPm3ZrZR7hEbvG5k/P58mdoqAKRbq19MU1fATM8DlkJaHi
14 38MJMlEfnME5l7bAa1FRAf/j89/H+NgnDsDlhC5DeNzAMW6RbaA9oG3MaA6OBBlg
15 jHxJgjk95VlJrWquBdSxVhknEE2sHOm8+ulhRPxzgYJkxAWeZU9yrOwtEl4JU+s+
16 lLS/IXF4ba499oPjd5CKSmqBQL6KWb1o8Pay8zD8MX+MmPM9tZY+MA==
17 -----END RSA PRIVATE KEY-----
18 -----BEGIN CERTIFICATE REQUEST-----
19 MIICLjCCAZcCAQAwga0xCzAJBgNVBAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1Ib2xs
20 YW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNVBAoTF1VuaXZlcnNpdHkgb2Yg
21 QW1zdGVyZGFtMQ8wDQYDVQQLEwZDbGllbnQxFzAVBgNVBAMTDkphbiBXaWVsZW1h
22 a2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0BzY2llbmNlLnV2YS5ubDCBnzAN
23 BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsPhLb/sEcuV5XgcURdOdTy+r7rpuB1LO
24 NDe1SzGoDwKlJLtBN2wvF+J//sAqhG3nO/u5St8J6g1HKtD+e4ISymtfcLulkaPQ
25 +UzHe0uNf6dq+Sc0MkN78uTWj9JC7SEoHGdiboR1q9qQqB4JcEfFUa7RdIhzdOdl
26 8+pN4HWmZG8CAwEAAaBAMBUGCSqGSIb3DQEJBzEIEwZhYXBqZXMwJwYJKoZIhvcN
27 AQkCMRoTGDpVbml2ZXJzaXR5IG9mIEFtc3RlcmRhbTANBgkqhkiG9w0BAQQFAAOB
28 gQAiPUUThFT51aUzGnSW3A5XR7bsExSptWWtVO/hQOiReEKRYUuf1mKCaSQz+Nt5
29 n3VZRV3w01yhnv4WVQwYRAdwkBP0Cuc1oXmatY7Tc93SiKO6yEvUhdlQxeeCih/Q
30 axIQqWm+/Rwh42XxJuVR+jOEr5m/bZuCOHJfAe9clLMpmQ==
31 -----END CERTIFICATE REQUEST-----
0 -----BEGIN ENCRYPTED PRIVATE KEY-----
1 MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQInpQwcijL1RYCAggA
2 MBQGCCqGSIb3DQMHBAhIc52+Uha4wQSCBMjmMOwEzC6itEG8h4rBZyvXve8m5aOe
3 LUjpdHShjAYrOeCcX9bRIrwczW7+y2zDYlWd9b6a22/Yijc35O5cPyzeoxHgv9bY
4 ChaZN0xnqo/4g+c7vSGi+hMnT1wzBsfyJ3GawWbDL7C4Zto1V92gxxZSQM8NqXDH
5 9SrOY+RMvD6mBk1s94g+LSPtDlcTvNEN7aBvVZGLVgREtsDT5p1AMZivrzTZO2Z0
6 V2N8D92zeLxwiAmN+ymgNgMrwZ5jy9b6X7vvdVgqpmohNugi4oK1llfSP7V77MMG
7 uLCZzJHQlb/aZwWR7XH+GtBpGChyo2MCErdGvBtHTgwzbHUGZuaVZNISuN+xH8bY
8 s9e3D20qU0+m4hoEKowtydCEj5+MBtIQVpp2Kasa68b+HEJbecyhOf0Rrkn83G43
9 n8h49mH7ltjkCqcaXPjQ7O1l0TiqqrUvSvuzU4Bh51PimzpEme/Y0NJ0nQy5pCxP
10 bh7mArQyr4F68TXOB5Pxp5JmH3x7FpBjFTXu/shOE828Xq97c1o0fsNiH0xmgJQE
11 PBrSqUPL+4ezjHbP11MMx28e6wOIUtvXThnkyvP9xp0/p4U+Jm8Otw2YDJ5AFmey
12 rLPy/yvEbQ+Y6jnwetsSDBkZYWGoWy2dWSOjzT8KpWg7ozYFKJ6fO72I6tELRIWr
13 83db6o+DlgSxiMyoRmOjkQ+2nBA6CYe59DUQQnYcnbmWJBlnxgeAqx22oq0MxAhE
14 D+N9cxVAbko6f7Izz4on1RcvKGfRVjGuYzuONXUdtVTN0LgHTq6s1fvf/VOsq/nW
15 SzNjA5slC/19EypbC7aoGSdBDBBG5mGd8O1yZ/L6nDGsi8za5DAhxDayXoQSrs+Z
16 OIdtdZ7pEog3I/X6N0X9VeAcCmuvrQYbOrNoX9ryKJeMM0TRUjAJyezyx0QOap9A
17 iPiNTUZz6zyGKxLRmN2VoRlZkjs55/Jod/zhy/5tMhOfHTRW75ve5dRVMxlTeoXm
18 BtzpVWqOa4r38HrXnwgSA4Z1mTJputg5biZgGIiUwrc3DdorGWR3vbKTSVJdB9ZD
19 26GzEBLrsOnB0Yc1ZjZWKs8+xlXqfAV3Z0IMVheZqx8tbxG1Z4LUIIKq51BGdFNx
20 6+gKTnPhZJoQePD5TI9vDklY7QGe/vpvllC0Wi0NtgCn/vgUlc1ljXY8aT2hRE3W
21 KrQFB7ekPSodtBpARu8skgfgERKAYEnSJgdt2Y9soUw9h0Teyinecptl51DgFXPn
22 9c1vqlEbtkKqcQJiPcfvLKwgbzArIDdSK25Vz81ctZh1d3Qu2NrfO/JjXFPAA1hh
23 5A6AoZqHWB2150pDMOLSMH/XgcFi7AV5RWT8D/pEIChNlExKLUNc6VpU1nAmCbWw
24 8VxuLO/wFV9nSgQJUM4Hzgu8jeyR+ZCMH0A9VENztoOFKhgFezRfn73bCipMKlGa
25 EE5QbPo/+O2k9mcNHAv+/ZgN1RBekjnWkVd2WoLjtOrzDzASaMzK381a/x9qQ+6P
26 cwcKkRGCaCopjUA5Ddki9dSSY+IosojuM/sH+NGNfnN6/M6z5MNqURbEpLXYeZDx
27 CLgos3Y1dV2BKZwvaWWsqw5aCTjcM0HPs/d52FMMo2u/qLYPvVRbBR7USokY+Izd
28 Tds=
29 -----END ENCRYPTED PRIVATE KEY-----
11 Data:
22 Version: 3 (0x2)
33 Serial Number:
4 ea:f9:b5:1b:4a:64:0b:4e
5 Signature Algorithm: sha1WithRSAEncryption
4 9d:c0:87:97:a0:f6:3f:7b
5 Signature Algorithm: sha256WithRSAEncryption
66 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
77 Validity
8 Not Before: Feb 27 21:51:56 2010 GMT
9 Not After : Jul 15 21:51:56 2037 GMT
8 Not Before: Apr 1 09:32:06 2020 GMT
9 Not After : Apr 1 09:32:06 2023 GMT
1010 Subject: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
1111 Subject Public Key Info:
1212 Public Key Algorithm: rsaEncryption
13 RSA Public Key: (1024 bit)
14 Modulus (1024 bit):
15 00:a3:89:65:d6:f6:34:38:be:8d:bf:0c:7b:95:0e:
16 01:0a:6e:3f:d6:54:c4:c4:d9:65:db:48:14:be:98:
17 79:e0:bc:f8:be:76:57:d3:91:f9:15:16:12:53:24:
18 ec:12:15:71:bd:c6:96:bc:cf:5c:5f:d0:1e:2d:f4:
19 79:ab:81:aa:29:76:a5:14:bb:0c:84:bd:93:84:43:
20 0b:51:ef:f4:64:8c:14:cc:6e:f2:f5:b5:cd:d7:66:
21 72:6b:96:e6:4f:e4:66:53:f0:95:7e:de:c5:8d:af:
22 ba:3b:83:43:7a:80:4b:b7:a0:47:c1:75:6e:97:3f:
23 ca:a0:bb:50:a3:a9:f3:7b:bf
13 Public-Key: (2048 bit)
14 Modulus:
15 00:d1:37:67:ad:b9:9f:0c:a7:93:cf:20:bf:1d:c0:
16 a8:ba:5c:ad:c6:ff:48:68:a0:93:9e:89:a7:1c:4e:
17 ff:88:07:2d:45:59:e1:a5:ae:2f:71:b1:30:b9:d1:
18 95:2b:a8:46:69:62:f2:25:8e:d4:15:e0:f5:2f:68:
19 26:21:f7:8e:7a:83:81:63:4e:63:0c:a5:3f:20:c7:
20 60:37:9f:c6:d8:e8:c7:95:6f:85:23:b9:4d:df:a3:
21 1d:2e:94:02:9a:14:db:28:c7:c3:0e:41:d5:68:7a:
22 82:11:98:8d:fc:ef:2f:8b:85:70:33:fa:26:ff:d4:
23 88:73:11:22:dc:0e:28:49:0b:5a:74:a3:a0:9a:44:
24 e8:0c:2d:47:42:29:c1:cc:d9:77:04:4f:42:f5:a3:
25 87:19:4c:72:b2:9e:9d:f0:3b:58:2e:18:cf:2d:4d:
26 e2:b5:c2:00:9e:67:11:0c:78:bb:53:43:16:55:b1:
27 c6:f6:8a:ea:43:6d:2b:59:48:da:21:d7:32:84:d9:
28 f5:d6:1c:af:03:f7:4a:b7:d3:db:24:f4:85:24:9b:
29 de:17:e5:b8:58:f4:a2:2c:eb:86:59:3b:ac:1e:13:
30 8c:a3:7c:5d:eb:42:db:1b:5b:8d:86:4c:2f:ad:b0:
31 1a:65:32:5f:fd:ad:cb:13:a6:ff:fe:e2:d6:5e:1b:
32 f0:a1
2433 Exponent: 65537 (0x10001)
2534 X509v3 extensions:
2635 X509v3 Subject Key Identifier:
27 20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
36 E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
2837 X509v3 Authority Key Identifier:
29 keyid:20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
30 DirName:/C=NL/ST=Noord-Holland/O=Diff Automatisering/OU=Support group/CN=J. van der Steen/emailAddress=info@diff.nl
31 serial:EA:F9:B5:1B:4A:64:0B:4E
38 keyid:E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
3239
3340 X509v3 Basic Constraints:
3441 CA:TRUE
35 Signature Algorithm: sha1WithRSAEncryption
36 8e:06:3b:75:99:ac:d4:da:04:e7:b7:fa:46:27:82:56:06:39:
37 dd:5c:04:ab:24:7f:a6:48:84:51:83:ca:8e:75:6f:dd:91:bc:
38 ca:30:7a:25:18:d2:dd:84:71:f2:ed:ea:21:fe:99:19:be:0b:
39 82:0a:8b:7c:2e:c1:ad:f0:6a:5c:f0:c4:85:2a:f6:23:30:78:
40 1d:e4:83:c5:4a:e4:be:3f:b5:3b:e7:c3:82:53:39:98:9b:ca:
41 45:e1:4c:4b:7f:9c:3d:73:93:46:75:50:17:fc:52:53:43:7c:
42 a1:30:b2:72:c0:d1:d6:c0:26:0b:a9:04:a7:d2:4f:f7:f6:bd:
43 0c:a3
42 Signature Algorithm: sha256WithRSAEncryption
43 2a:0f:94:6c:75:27:e1:f4:0a:6a:a0:0e:0e:f1:c9:ef:b2:83:
44 ae:56:d9:6e:e2:e2:69:ea:a4:2d:ad:fd:79:57:64:00:0c:bd:
45 c8:d3:65:2d:d8:4d:5a:e5:b2:14:21:9c:d5:64:1b:ed:86:0d:
46 c4:92:28:c5:14:b4:c2:8c:72:fa:4a:97:4f:2d:e9:35:80:5a:
47 e4:ad:2d:f3:61:4b:c7:b0:bc:6d:42:e2:07:50:88:5c:42:bf:
48 3b:ac:65:25:b4:6a:ef:e2:cd:30:6b:1e:59:10:97:27:dd:10:
49 61:3e:e1:2f:c0:fd:5a:53:c1:6f:bb:54:94:90:fb:a0:d9:6b:
50 2e:6e:77:79:d6:52:ba:04:70:9d:1e:72:d6:62:a6:e2:c6:60:
51 1f:2e:99:e0:62:97:41:b4:f8:a3:5e:a4:78:80:ee:51:b8:4a:
52 7c:07:a0:6d:c5:a2:0d:c7:91:d1:7b:3c:84:ee:41:c7:60:e5:
53 7f:52:f9:ef:1c:d3:98:35:8c:da:f7:e0:78:1f:13:0d:ea:64:
54 d2:38:a5:47:71:32:65:63:7a:7e:d1:de:73:18:b3:73:ed:d3:
55 f1:0c:f7:56:f5:1e:2b:a6:5d:9b:ac:9a:27:52:fe:ea:51:2a:
56 ef:76:55:d3:31:20:87:e4:5f:f4:dc:50:66:49:02:53:ac:ff:
57 fb:35:ac:21
4458 -----BEGIN CERTIFICATE-----
45 MIIDojCCAwugAwIBAgIJAOr5tRtKZAtOMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
46 VQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBB
47 dXRvbWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQ
59 MIID+zCCAuOgAwIBAgIJAJ3Ah5eg9j97MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
60 VQQGEwJOTDEWMBQGA1UECAwNTm9vcmQtSG9sbGFuZDEcMBoGA1UECgwTRGlmZiBB
61 dXRvbWF0aXNlcmluZzEWMBQGA1UECwwNU3VwcG9ydCBncm91cDEZMBcGA1UEAwwQ
4862 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
49 DTEwMDIyNzIxNTE1NloXDTM3MDcxNTIxNTE1NlowgZMxCzAJBgNVBAYTAk5MMRYw
50 FAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRwwGgYDVQQKExNEaWZmIEF1dG9tYXRpc2Vy
51 aW5nMRYwFAYDVQQLEw1TdXBwb3J0IGdyb3VwMRkwFwYDVQQDExBKLiB2YW4gZGVy
52 IFN0ZWVuMRswGQYJKoZIhvcNAQkBFgxpbmZvQGRpZmYubmwwgZ8wDQYJKoZIhvcN
53 AQEBBQADgY0AMIGJAoGBAKOJZdb2NDi+jb8Me5UOAQpuP9ZUxMTZZdtIFL6YeeC8
54 +L52V9OR+RUWElMk7BIVcb3GlrzPXF/QHi30eauBqil2pRS7DIS9k4RDC1Hv9GSM
55 FMxu8vW1zddmcmuW5k/kZlPwlX7exY2vujuDQ3qAS7egR8F1bpc/yqC7UKOp83u/
56 AgMBAAGjgfswgfgwHQYDVR0OBBYEFCAbQOQAGHzmZ3qAFv4VB569dycmMIHIBgNV
57 HSMEgcAwgb2AFCAbQOQAGHzmZ3qAFv4VB569dycmoYGZpIGWMIGTMQswCQYDVQQG
58 EwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBBdXRv
59 bWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQSi4g
60 dmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sggkA6vm1
61 G0pkC04wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCOBjt1mazU2gTn
62 t/pGJ4JWBjndXASrJH+mSIRRg8qOdW/dkbzKMHolGNLdhHHy7eoh/pkZvguCCot8
63 LsGt8Gpc8MSFKvYjMHgd5IPFSuS+P7U758OCUzmYm8pF4UxLf5w9c5NGdVAX/FJT
64 Q3yhMLJywNHWwCYLqQSn0k/39r0Mow==
63 DTIwMDQwMTA5MzIwNloXDTIzMDQwMTA5MzIwNlowgZMxCzAJBgNVBAYTAk5MMRYw
64 FAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRwwGgYDVQQKDBNEaWZmIEF1dG9tYXRpc2Vy
65 aW5nMRYwFAYDVQQLDA1TdXBwb3J0IGdyb3VwMRkwFwYDVQQDDBBKLiB2YW4gZGVy
66 IFN0ZWVuMRswGQYJKoZIhvcNAQkBFgxpbmZvQGRpZmYubmwwggEiMA0GCSqGSIb3
67 DQEBAQUAA4IBDwAwggEKAoIBAQDRN2etuZ8Mp5PPIL8dwKi6XK3G/0hooJOeiacc
68 Tv+IBy1FWeGlri9xsTC50ZUrqEZpYvIljtQV4PUvaCYh9456g4FjTmMMpT8gx2A3
69 n8bY6MeVb4UjuU3fox0ulAKaFNsox8MOQdVoeoIRmI387y+LhXAz+ib/1IhzESLc
70 DihJC1p0o6CaROgMLUdCKcHM2XcET0L1o4cZTHKynp3wO1guGM8tTeK1wgCeZxEM
71 eLtTQxZVscb2iupDbStZSNoh1zKE2fXWHK8D90q309sk9IUkm94X5bhY9KIs64ZZ
72 O6weE4yjfF3rQtsbW42GTC+tsBplMl/9rcsTpv/+4tZeG/ChAgMBAAGjUDBOMB0G
73 A1UdDgQWBBTie2CMd7uydLj91iyp07k1lxKH7DAfBgNVHSMEGDAWgBTie2CMd7uy
74 dLj91iyp07k1lxKH7DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAq
75 D5RsdSfh9ApqoA4O8cnvsoOuVtlu4uJp6qQtrf15V2QADL3I02Ut2E1a5bIUIZzV
76 ZBvthg3EkijFFLTCjHL6SpdPLek1gFrkrS3zYUvHsLxtQuIHUIhcQr87rGUltGrv
77 4s0wax5ZEJcn3RBhPuEvwP1aU8Fvu1SUkPug2Wsubnd51lK6BHCdHnLWYqbixmAf
78 LpngYpdBtPijXqR4gO5RuEp8B6BtxaINx5HRezyE7kHHYOV/UvnvHNOYNYza9+B4
79 HxMN6mTSOKVHcTJlY3p+0d5zGLNz7dPxDPdW9R4rpl2brJonUv7qUSrvdlXTMSCH
80 5F/03FBmSQJTrP/7Nawh
6581 -----END CERTIFICATE-----
00 -----BEGIN CERTIFICATE REQUEST-----
1 MIIB6DCCAVECAQAwgacxCzAJBgNVBAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1Ib2xs
2 YW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xHDAaBgNVBAoTE0RpZmYgQXV0b21hdGlz
3 ZXJpbmcxFjAUBgNVBAsTDVN1cHBvcnQgZ3JvdXAxGTAXBgNVBAMTEEouIHZhbiBk
4 ZXIgU3RlZW4xGzAZBgkqhkiG9w0BCQEWDGluZm9AZGlmZi5ubDCBnzANBgkqhkiG
5 9w0BAQEFAAOBjQAwgYkCgYEAo4ll1vY0OL6Nvwx7lQ4BCm4/1lTExNll20gUvph5
6 4Lz4vnZX05H5FRYSUyTsEhVxvcaWvM9cX9AeLfR5q4GqKXalFLsMhL2ThEMLUe/0
7 ZIwUzG7y9bXN12Zya5bmT+RmU/CVft7Fja+6O4NDeoBLt6BHwXVulz/KoLtQo6nz
8 e78CAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBABKUDD8OpX4aB9xLS3PIkyZybMHl
9 Q4IqHBYruyKEIjGqn+Sijo5yq2AAgPpiM4wyGTpAj1HamykdiI6OZO7lVYnbWy5z
10 GC9aEhcNRcVU/I4CaZUx900kJT8APekdUqJXZs1+/IxAYN5+8kqElbQu6fv8Y038
11 5xu4UNWN+2jYZGqf
1 MIIC7TCCAdUCAQAwgacxCzAJBgNVBAYTAk5MMRYwFAYDVQQIDA1Ob29yZC1Ib2xs
2 YW5kMRIwEAYDVQQHDAlBbXN0ZXJkYW0xHDAaBgNVBAoME0RpZmYgQXV0b21hdGlz
3 ZXJpbmcxFjAUBgNVBAsMDVN1cHBvcnQgZ3JvdXAxGTAXBgNVBAMMEEouIHZhbiBk
4 ZXIgU3RlZW4xGzAZBgkqhkiG9w0BCQEWDGluZm9AZGlmZi5ubDCCASIwDQYJKoZI
5 hvcNAQEBBQADggEPADCCAQoCggEBANE3Z625nwynk88gvx3AqLpcrcb/SGigk56J
6 pxxO/4gHLUVZ4aWuL3GxMLnRlSuoRmli8iWO1BXg9S9oJiH3jnqDgWNOYwylPyDH
7 YDefxtjox5VvhSO5Td+jHS6UApoU2yjHww5B1Wh6ghGYjfzvL4uFcDP6Jv/UiHMR
8 ItwOKEkLWnSjoJpE6AwtR0IpwczZdwRPQvWjhxlMcrKenfA7WC4Yzy1N4rXCAJ5n
9 EQx4u1NDFlWxxvaK6kNtK1lI2iHXMoTZ9dYcrwP3SrfT2yT0hSSb3hfluFj0oizr
10 hlk7rB4TjKN8XetC2xtbjYZML62wGmUyX/2tyxOm//7i1l4b8KECAwEAAaAAMA0G
11 CSqGSIb3DQEBCwUAA4IBAQCKVJwFCm9LeY9onvksGuku2UhioOQAjqhMuzjOedLP
12 tdsaBwFCVbvxKu/TGIwkmK2PWvKJvbn+GlXhlQlPsYDPrIeUf/9xl0hD4L9LQ0Aw
13 J+e4025Tb9kLajXAnpwqFk+Z7KbGc3TbFvUCr7lLJsygdYQE+OtlBlaxrOmidIn6
14 s2GHON9nRDkeoTD6coCuMTgBWBB6ZSHCcgFy7gKNT4U3/+hYuBkg3FDZfVbXuuwn
15 rveqzFfuBXlnHmJVIjqa6oXtBG/7Jm0JDOSQS2vskp3/jQAx3V4u0M77taMSC4C9
16 +pBoiH94n8fG87LbE6EQyit4KhLAluWf0jrx7vCIKGSD
1217 -----END CERTIFICATE REQUEST-----
0 V 080226140317Z A611836B46298A6F unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=Diff Automatisering/OU=Server/CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
1 V 080226140535Z A611836B46298A70 unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=Diff Automatisering/OU=Client/CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
2 V 351119151103Z A611836B46298A71 unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=University of Amsterdam/OU=Server/CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
3 V 351119151114Z A611836B46298A72 unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=University of Amsterdam/OU=Client/CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
0 V 230401093206Z 9DC08797A0F63F7B unknown /C=NL/ST=Noord-Holland/O=Diff Automatisering/OU=Support group/CN=J. van der Steen/emailAddress=info@diff.nl
1 V 210401093434Z 9DC08797A0F63F7C unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=Diff Automatisering/OU=Client/CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
2 V 210401093537Z 9DC08797A0F63F7D unknown /C=NL/ST=Noord-Holland/L=Amsterdam/O=Diff Automatisering/OU=Server/CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
0 unique_subject = no
0 unique_subject = yes
0 Certificate:
1 Data:
2 Version: 3 (0x2)
3 Serial Number:
4 9d:c0:87:97:a0:f6:3f:7c
5 Signature Algorithm: sha256WithRSAEncryption
6 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
7 Validity
8 Not Before: Apr 1 09:34:34 2020 GMT
9 Not After : Apr 1 09:34:34 2021 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=Diff Automatisering, OU=Client, CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
11 Subject Public Key Info:
12 Public Key Algorithm: rsaEncryption
13 Public-Key: (2048 bit)
14 Modulus:
15 00:a4:cf:45:ac:02:9b:ba:01:48:79:50:2f:f4:58:
16 7b:e0:47:c8:0e:12:9c:f6:9f:29:71:24:e4:41:cc:
17 02:45:03:51:5f:34:69:da:b6:7d:83:29:dd:c7:d8:
18 e0:05:29:9c:7e:a9:a0:31:83:53:3c:df:17:fb:12:
19 da:1a:c3:6b:44:78:b3:17:9b:44:f7:8d:3e:12:5f:
20 cc:31:58:a7:20:ab:d3:dd:45:c7:52:99:d2:48:8b:
21 72:85:d3:bb:04:cd:f9:e0:b7:56:ab:79:b7:66:40:
22 c7:e8:7a:52:ed:ed:55:1b:db:5b:1d:9b:dd:0e:ad:
23 68:2d:c3:da:67:3c:be:6e:08:8f:a3:88:2a:d7:27:
24 0d:b6:90:f0:2d:a8:0b:54:db:95:ba:b9:0a:67:f4:
25 00:65:a0:a7:cf:81:2e:e5:6a:52:6b:18:28:74:82:
26 9f:52:14:11:96:d1:dd:23:25:74:70:81:1e:41:00:
27 ec:65:3b:ac:18:30:06:f6:ed:58:d7:2c:0f:77:fa:
28 53:7c:40:02:e5:70:4a:b8:e0:b3:7b:c5:34:93:f1:
29 77:af:2f:37:a6:09:c9:e6:3d:c4:0f:15:d7:8e:6c:
30 3c:10:ab:2a:5f:38:77:b1:7d:f1:06:6d:49:1e:5a:
31 0f:26:68:fc:eb:e7:c9:b1:b7:87:4e:a6:12:de:b5:
32 5a:1b
33 Exponent: 65537 (0x10001)
34 X509v3 extensions:
35 X509v3 Basic Constraints:
36 CA:FALSE
37 Netscape Comment:
38 OpenSSL Generated Certificate
39 X509v3 Subject Key Identifier:
40 BD:79:A2:A6:3C:EC:1A:80:75:8D:60:9B:A6:F9:02:6B:C0:ED:E4:8A
41 X509v3 Authority Key Identifier:
42 keyid:E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
43
44 Signature Algorithm: sha256WithRSAEncryption
45 45:62:87:35:99:a7:74:b9:de:08:7c:2f:41:f5:c8:1e:3e:df:
46 c6:54:f3:e4:fa:25:a7:7b:8f:b3:1e:89:d2:83:97:50:fd:84:
47 c8:53:1d:ab:9c:61:80:44:5f:72:29:6b:59:35:ab:11:45:42:
48 4f:0b:02:88:55:b9:4b:40:9a:b0:0b:ed:aa:a6:7a:44:b1:f6:
49 01:f2:3c:fd:54:d5:93:8b:9a:68:18:ed:77:c3:39:79:f5:59:
50 c2:7a:7f:d0:03:b1:a5:d8:27:62:c8:33:06:7c:c5:26:32:cd:
51 92:ce:b0:2e:7f:16:e8:e3:3f:28:8e:b3:66:cd:a5:b1:64:db:
52 33:0f:c6:12:f3:22:66:0f:6f:b2:1c:fb:81:bb:a4:ad:c8:27:
53 9f:62:72:44:9b:b7:da:3c:10:0e:95:87:33:91:59:a3:0c:ca:
54 d9:15:f0:de:52:25:f9:14:16:da:69:d8:af:00:87:f8:f1:6f:
55 26:07:9a:f7:4e:ad:07:23:ef:e2:aa:94:b2:45:2a:f7:55:65:
56 e4:59:ee:1c:5d:69:64:4f:b3:2f:a7:54:03:36:05:10:8a:43:
57 3c:ce:8c:97:91:b6:17:4b:85:ab:a9:51:8f:de:1a:89:4b:1e:
58 5f:39:47:b3:ab:cc:14:f4:c6:ba:d3:4a:6f:6a:fe:aa:2d:2c:
59 81:53:9a:53
60 -----BEGIN CERTIFICATE-----
61 MIIEPjCCAyagAwIBAgIJAJ3Ah5eg9j98MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
62 VQQGEwJOTDEWMBQGA1UECAwNTm9vcmQtSG9sbGFuZDEcMBoGA1UECgwTRGlmZiBB
63 dXRvbWF0aXNlcmluZzEWMBQGA1UECwwNU3VwcG9ydCBncm91cDEZMBcGA1UEAwwQ
64 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
65 DTIwMDQwMTA5MzQzNFoXDTIxMDQwMTA5MzQzNFowgasxCzAJBgNVBAYTAk5MMRYw
66 FAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHDAlBbXN0ZXJkYW0xHDAaBgNV
67 BAoME0RpZmYgQXV0b21hdGlzZXJpbmcxDzANBgNVBAsMBkNsaWVudDEZMBcGA1UE
68 AwwQSi4gdmFuIGRlciBTdGVlbjEmMCQGCSqGSIb3DQEJARYXSi52YW4uZGVyLlN0
69 ZWVuQGRpZmYubmwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkz0Ws
70 Apu6AUh5UC/0WHvgR8gOEpz2nylxJORBzAJFA1FfNGnatn2DKd3H2OAFKZx+qaAx
71 g1M83xf7Etoaw2tEeLMXm0T3jT4SX8wxWKcgq9PdRcdSmdJIi3KF07sEzfngt1ar
72 ebdmQMfoelLt7VUb21sdm90OrWgtw9pnPL5uCI+jiCrXJw22kPAtqAtU25W6uQpn
73 9ABloKfPgS7lalJrGCh0gp9SFBGW0d0jJXRwgR5BAOxlO6wYMAb27VjXLA93+lN8
74 QALlcEq44LN7xTST8XevLzemCcnmPcQPFdeObDwQqypfOHexffEGbUkeWg8maPzr
75 58mxt4dOphLetVobAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8W
76 HU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBS9eaKmPOwa
77 gHWNYJum+QJrwO3kijAfBgNVHSMEGDAWgBTie2CMd7uydLj91iyp07k1lxKH7DAN
78 BgkqhkiG9w0BAQsFAAOCAQEARWKHNZmndLneCHwvQfXIHj7fxlTz5Polp3uPsx6J
79 0oOXUP2EyFMdq5xhgERfcilrWTWrEUVCTwsCiFW5S0CasAvtqqZ6RLH2AfI8/VTV
80 k4uaaBjtd8M5efVZwnp/0AOxpdgnYsgzBnzFJjLNks6wLn8W6OM/KI6zZs2lsWTb
81 Mw/GEvMiZg9vshz7gbukrcgnn2JyRJu32jwQDpWHM5FZowzK2RXw3lIl+RQW2mnY
82 rwCH+PFvJgea906tByPv4qqUskUq91Vl5FnuHF1pZE+zL6dUAzYFEIpDPM6Ml5G2
83 F0uFq6lRj94aiUseXzlHs6vMFPTGutNKb2r+qi0sgVOaUw==
84 -----END CERTIFICATE-----
0 Certificate:
1 Data:
2 Version: 3 (0x2)
3 Serial Number:
4 9d:c0:87:97:a0:f6:3f:7d
5 Signature Algorithm: sha256WithRSAEncryption
6 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
7 Validity
8 Not Before: Apr 1 09:35:37 2020 GMT
9 Not After : Apr 1 09:35:37 2021 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=Diff Automatisering, OU=Server, CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
11 Subject Public Key Info:
12 Public Key Algorithm: rsaEncryption
13 Public-Key: (2048 bit)
14 Modulus:
15 00:e7:6c:7a:c1:e9:17:aa:ea:d8:32:73:66:b3:62:
16 ee:3c:7d:c8:e4:3c:59:67:57:67:8d:98:61:24:31:
17 98:23:8f:ef:c3:41:2a:0f:82:1e:6a:6f:2d:00:9e:
18 bf:19:ad:6b:46:42:17:c2:1e:cc:27:b5:c7:66:7a:
19 a5:7b:cc:8c:15:0a:1c:d2:c5:87:23:94:88:42:5e:
20 42:9f:41:22:5a:ad:71:b2:29:54:23:39:cd:05:db:
21 cf:6d:3b:8e:9a:b0:f3:e6:ca:9f:2d:39:28:d6:1c:
22 76:da:34:54:27:f9:a0:0f:1d:ae:32:30:c4:7f:9e:
23 53:18:64:27:2f:05:2b:bf:66:ce:39:52:99:8e:10:
24 1a:80:bf:5e:3a:54:fb:85:da:fc:a7:2d:90:99:42:
25 c7:e2:cf:6a:db:56:1d:3b:bc:0e:97:bf:c5:d4:58:
26 c4:76:33:a2:25:8c:56:94:b4:8d:a9:d3:ab:76:2a:
27 f9:4c:15:de:d1:b8:23:66:3f:36:9a:4b:51:9e:1a:
28 27:e5:f0:38:a3:2a:2a:ab:cd:1c:88:7c:e4:df:82:
29 44:6f:e9:c1:0d:6f:55:98:f4:c0:06:41:ff:1f:c7:
30 30:6a:9a:14:57:73:bd:e0:a7:f7:43:0f:f4:ae:49:
31 b3:48:de:42:fd:0d:be:26:e1:39:4d:24:b8:36:d7:
32 16:43
33 Exponent: 65537 (0x10001)
34 X509v3 extensions:
35 X509v3 Basic Constraints:
36 CA:FALSE
37 Netscape Comment:
38 OpenSSL Generated Certificate
39 X509v3 Subject Key Identifier:
40 01:84:17:EF:98:0D:F4:DD:FC:24:63:09:EF:2F:E6:BE:52:97:7C:17
41 X509v3 Authority Key Identifier:
42 keyid:E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
43
44 Signature Algorithm: sha256WithRSAEncryption
45 9a:b1:75:61:08:bb:ca:dc:b9:cd:3e:5e:30:f8:86:20:2c:e1:
46 47:41:50:c6:a3:e5:b0:d2:08:43:eb:86:9e:5c:2c:7b:4c:40:
47 f9:f2:64:1d:7d:9e:f7:31:78:ef:12:05:ff:b9:4e:48:dc:0c:
48 b9:9d:df:6f:3e:27:e4:a4:55:b7:61:70:9c:6d:97:30:78:5f:
49 72:7a:61:ad:68:96:e6:db:7f:fe:3a:82:52:71:88:42:08:67:
50 ce:13:00:af:8f:e1:fd:bb:fd:c8:a4:cc:a9:4e:93:8f:c2:91:
51 b8:e8:22:86:c0:65:36:e7:25:fb:c3:ca:bb:23:b2:33:fa:41:
52 2c:9c:e7:d8:9f:14:82:1f:a7:ea:20:77:8d:7b:82:3f:22:ea:
53 9b:87:8f:86:eb:f7:15:14:17:12:c0:90:6b:cd:7b:e1:9f:da:
54 96:aa:59:7c:21:01:98:2f:d6:19:e4:7d:60:04:d3:64:65:a3:
55 7b:a4:0f:59:d0:ce:90:1b:e0:6b:55:4f:94:d2:a5:aa:0f:c4:
56 05:b9:e8:e4:7e:11:33:db:77:3f:73:ab:ea:2d:6e:00:07:7e:
57 5a:6c:42:79:dc:06:86:85:3f:44:25:e7:d6:44:b8:b2:2e:f4:
58 f1:a4:60:97:3f:b3:74:29:d7:ec:6d:f1:c4:9c:7b:e4:57:a3:
59 3c:be:17:bb
60 -----BEGIN CERTIFICATE-----
61 MIIEPjCCAyagAwIBAgIJAJ3Ah5eg9j99MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
62 VQQGEwJOTDEWMBQGA1UECAwNTm9vcmQtSG9sbGFuZDEcMBoGA1UECgwTRGlmZiBB
63 dXRvbWF0aXNlcmluZzEWMBQGA1UECwwNU3VwcG9ydCBncm91cDEZMBcGA1UEAwwQ
64 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
65 DTIwMDQwMTA5MzUzN1oXDTIxMDQwMTA5MzUzN1owgasxCzAJBgNVBAYTAk5MMRYw
66 FAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHDAlBbXN0ZXJkYW0xHDAaBgNV
67 BAoME0RpZmYgQXV0b21hdGlzZXJpbmcxDzANBgNVBAsMBlNlcnZlcjEZMBcGA1UE
68 AwwQSi4gdmFuIGRlciBTdGVlbjEmMCQGCSqGSIb3DQEJARYXSi52YW4uZGVyLlN0
69 ZWVuQGRpZmYubmwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnbHrB
70 6Req6tgyc2azYu48fcjkPFlnV2eNmGEkMZgjj+/DQSoPgh5qby0Anr8ZrWtGQhfC
71 HswntcdmeqV7zIwVChzSxYcjlIhCXkKfQSJarXGyKVQjOc0F289tO46asPPmyp8t
72 OSjWHHbaNFQn+aAPHa4yMMR/nlMYZCcvBSu/Zs45UpmOEBqAv146VPuF2vynLZCZ
73 Qsfiz2rbVh07vA6Xv8XUWMR2M6IljFaUtI2p06t2KvlMFd7RuCNmPzaaS1GeGifl
74 8DijKiqrzRyIfOTfgkRv6cENb1WY9MAGQf8fxzBqmhRXc73gp/dDD/SuSbNI3kL9
75 Db4m4TlNJLg21xZDAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8W
76 HU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQBhBfvmA30
77 3fwkYwnvL+a+Upd8FzAfBgNVHSMEGDAWgBTie2CMd7uydLj91iyp07k1lxKH7DAN
78 BgkqhkiG9w0BAQsFAAOCAQEAmrF1YQi7yty5zT5eMPiGICzhR0FQxqPlsNIIQ+uG
79 nlwse0xA+fJkHX2e9zF47xIF/7lOSNwMuZ3fbz4n5KRVt2FwnG2XMHhfcnphrWiW
80 5tt//jqCUnGIQghnzhMAr4/h/bv9yKTMqU6Tj8KRuOgihsBlNucl+8PKuyOyM/pB
81 LJzn2J8Ugh+n6iB3jXuCPyLqm4ePhuv3FRQXEsCQa8174Z/alqpZfCEBmC/WGeR9
82 YATTZGWje6QPWdDOkBvga1VPlNKlqg/EBbno5H4RM9t3P3Or6i1uAAd+WmxCedwG
83 hoU/RCXn1kS4si708aRglz+zdCnX7G3xxJx75FejPL4Xuw==
84 -----END CERTIFICATE-----
+0
-64
packages/ssl/etc/demoCA/newcerts/A611836B46298A71.pem less more
0 Certificate:
1 Data:
2 Version: 3 (0x2)
3 Serial Number:
4 a6:11:83:6b:46:29:8a:71
5 Signature Algorithm: sha1WithRSAEncryption
6 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
7 Validity
8 Not Before: Jul 3 15:11:03 2008 GMT
9 Not After : Nov 19 15:11:03 2035 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=University of Amsterdam, OU=Server, CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
11 Subject Public Key Info:
12 Public Key Algorithm: rsaEncryption
13 RSA Public Key: (1024 bit)
14 Modulus (1024 bit):
15 00:bd:19:49:a3:5b:44:61:19:47:31:f4:d5:8c:c2:
16 bc:fc:86:08:c0:8f:d3:1c:1d:c6:f7:4f:93:f8:d1:
17 57:bf:17:d6:c5:db:34:f3:fc:af:0d:ff:0b:74:61:
18 76:14:b0:72:89:03:37:5c:d6:47:6e:c2:0c:35:f9:
19 7f:52:23:79:4b:ae:59:d8:ae:09:f5:5b:61:ed:d9:
20 29:45:80:df:fc:9b:bb:7f:5a:3b:08:dd:75:2b:29:
21 e8:07:aa:49:29:ba:4c:e8:39:b3:9e:be:03:71:e7:
22 b0:02:14:3a:de:29:17:86:14:68:b2:49:aa:9c:64:
23 01:60:1b:9f:7f:e0:ab:7c:8b
24 Exponent: 65537 (0x10001)
25 X509v3 extensions:
26 X509v3 Basic Constraints:
27 CA:FALSE
28 Netscape Comment:
29 OpenSSL Generated Certificate
30 X509v3 Subject Key Identifier:
31 8F:1F:C9:B8:13:2E:8C:0A:85:B3:50:B4:57:E7:6C:09:16:5F:CE:62
32 X509v3 Authority Key Identifier:
33 keyid:20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
34
35 Signature Algorithm: sha1WithRSAEncryption
36 56:f8:23:86:30:6d:3e:ae:1f:91:1d:d5:4e:48:49:d7:cb:72:
37 74:7c:0e:34:07:f1:0d:cd:43:89:ba:ab:10:94:7b:71:2e:22:
38 61:55:ec:14:dd:56:c4:fa:ca:2b:c6:1c:6c:e8:f4:af:36:2d:
39 ca:6e:ed:d8:df:b3:b2:89:57:01:d3:61:53:56:90:02:ab:a8:
40 66:c5:96:19:7e:2e:cc:70:5c:50:bf:fb:6e:e5:58:40:74:5b:
41 de:d3:57:24:09:fb:32:fd:92:c1:07:7c:c0:1f:db:73:de:76:
42 6e:93:c9:e5:97:f7:fa:87:9e:07:1f:09:13:d2:86:17:3f:70:
43 0c:a2
44 -----BEGIN CERTIFICATE-----
45 MIIDOzCCAqSgAwIBAgIJAKYRg2tGKYpxMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
46 VQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBB
47 dXRvbWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQ
48 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
49 DTA4MDcwMzE1MTEwM1oXDTM1MTExOTE1MTEwM1owga0xCzAJBgNVBAYTAk5MMRYw
50 FAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNV
51 BAoTF1VuaXZlcnNpdHkgb2YgQW1zdGVyZGFtMQ8wDQYDVQQLEwZTZXJ2ZXIxFzAV
52 BgNVBAMTDkphbiBXaWVsZW1ha2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0Bz
53 Y2llbmNlLnV2YS5ubDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvRlJo1tE
54 YRlHMfTVjMK8/IYIwI/THB3G90+T+NFXvxfWxds08/yvDf8LdGF2FLByiQM3XNZH
55 bsIMNfl/UiN5S65Z2K4J9Vth7dkpRYDf/Ju7f1o7CN11KynoB6pJKbpM6Dmznr4D
56 ceewAhQ63ikXhhRoskmqnGQBYBuff+CrfIsCAwEAAaN7MHkwCQYDVR0TBAIwADAs
57 BglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYD
58 VR0OBBYEFI8fybgTLowKhbNQtFfnbAkWX85iMB8GA1UdIwQYMBaAFCAbQOQAGHzm
59 Z3qAFv4VB569dycmMA0GCSqGSIb3DQEBBQUAA4GBAFb4I4YwbT6uH5Ed1U5ISdfL
60 cnR8DjQH8Q3NQ4m6qxCUe3EuImFV7BTdVsT6yivGHGzo9K82Lcpu7djfs7KJVwHT
61 YVNWkAKrqGbFlhl+LsxwXFC/+27lWEB0W97TVyQJ+zL9ksEHfMAf23Pedm6TyeWX
62 9/qHngcfCRPShhc/cAyi
63 -----END CERTIFICATE-----
+0
-64
packages/ssl/etc/demoCA/newcerts/A611836B46298A72.pem less more
0 Certificate:
1 Data:
2 Version: 3 (0x2)
3 Serial Number:
4 a6:11:83:6b:46:29:8a:72
5 Signature Algorithm: sha1WithRSAEncryption
6 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
7 Validity
8 Not Before: Jul 3 15:11:14 2008 GMT
9 Not After : Nov 19 15:11:14 2035 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=University of Amsterdam, OU=Client, CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
11 Subject Public Key Info:
12 Public Key Algorithm: rsaEncryption
13 RSA Public Key: (1024 bit)
14 Modulus (1024 bit):
15 00:b0:f8:4b:6f:fb:04:72:e5:79:5e:07:14:45:d3:
16 9d:4f:2f:ab:ee:ba:6e:07:52:ce:34:37:b5:4b:31:
17 a8:0f:02:a5:24:bb:41:37:6c:2f:17:e2:7f:fe:c0:
18 2a:84:6d:e7:3b:fb:b9:4a:df:09:ea:0d:47:2a:d0:
19 fe:7b:82:12:ca:6b:5f:70:bb:a5:91:a3:d0:f9:4c:
20 c7:7b:4b:8d:7f:a7:6a:f9:27:34:32:43:7b:f2:e4:
21 d6:8f:d2:42:ed:21:28:1c:67:62:6e:84:75:ab:da:
22 90:a8:1e:09:70:47:c5:51:ae:d1:74:88:73:74:e7:
23 65:f3:ea:4d:e0:75:a6:64:6f
24 Exponent: 65537 (0x10001)
25 X509v3 extensions:
26 X509v3 Basic Constraints:
27 CA:FALSE
28 Netscape Comment:
29 OpenSSL Generated Certificate
30 X509v3 Subject Key Identifier:
31 F1:3E:D8:C4:80:01:24:70:79:03:AB:76:81:A4:4F:50:A8:F1:B2:FD
32 X509v3 Authority Key Identifier:
33 keyid:20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
34
35 Signature Algorithm: sha1WithRSAEncryption
36 2d:9f:13:8b:ca:d6:0a:f0:ef:75:52:ab:a0:fe:6f:f1:14:16:
37 f9:4e:f5:77:ac:55:9b:bb:31:d3:fa:e5:4f:9a:83:91:7d:c5:
38 90:b1:94:d1:1b:3b:a2:b4:fa:5f:43:79:20:ec:b2:48:61:fc:
39 bf:75:25:75:64:2d:c6:02:61:4b:4a:d9:50:eb:bc:ba:e7:cb:
40 31:91:f2:18:6b:62:8f:e4:29:ea:83:29:54:53:05:40:5c:86:
41 11:d2:56:0d:4a:39:f6:b4:f0:78:86:98:15:da:3a:cd:86:7e:
42 c0:bc:71:dc:7d:69:f8:0b:56:17:a3:3b:6d:e3:65:73:1d:64:
43 21:f0
44 -----BEGIN CERTIFICATE-----
45 MIIDOzCCAqSgAwIBAgIJAKYRg2tGKYpyMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
46 VQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBB
47 dXRvbWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQ
48 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
49 DTA4MDcwMzE1MTExNFoXDTM1MTExOTE1MTExNFowga0xCzAJBgNVBAYTAk5MMRYw
50 FAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNV
51 BAoTF1VuaXZlcnNpdHkgb2YgQW1zdGVyZGFtMQ8wDQYDVQQLEwZDbGllbnQxFzAV
52 BgNVBAMTDkphbiBXaWVsZW1ha2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0Bz
53 Y2llbmNlLnV2YS5ubDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsPhLb/sE
54 cuV5XgcURdOdTy+r7rpuB1LONDe1SzGoDwKlJLtBN2wvF+J//sAqhG3nO/u5St8J
55 6g1HKtD+e4ISymtfcLulkaPQ+UzHe0uNf6dq+Sc0MkN78uTWj9JC7SEoHGdiboR1
56 q9qQqB4JcEfFUa7RdIhzdOdl8+pN4HWmZG8CAwEAAaN7MHkwCQYDVR0TBAIwADAs
57 BglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYD
58 VR0OBBYEFPE+2MSAASRweQOrdoGkT1Co8bL9MB8GA1UdIwQYMBaAFCAbQOQAGHzm
59 Z3qAFv4VB569dycmMA0GCSqGSIb3DQEBBQUAA4GBAC2fE4vK1grw73VSq6D+b/EU
60 FvlO9XesVZu7MdP65U+ag5F9xZCxlNEbO6K0+l9DeSDsskhh/L91JXVkLcYCYUtK
61 2VDrvLrnyzGR8hhrYo/kKeqDKVRTBUBchhHSVg1KOfa08HiGmBXaOs2GfsC8cdx9
62 afgLVhejO23jZXMdZCHw
63 -----END CERTIFICATE-----
0 -----BEGIN RSA PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: DES-EDE3-CBC,451F2D191DB34CCE
3
4 KjPvyYKFWfUegzyq8fBtsDGaGDfLXeZ/RWHnTWSSoUXzODLrbOzKguwLES89EltO
5 9zuMBBWjRU2eNFu06Eb1KelDI69WvIpL5J1/rQptluKSYRXP+2GbtQsNEqtLBwE4
6 oLEWWtr/PoJ9CUQImYtmea4rG+TeS9eJSIV0OCrfg/UW18jknSUbnr/YczU9i77Q
7 x2ZDE6WIsxv1H8gNQF13wHOoz9K6zzJDOWxDWaQoogsddXIJEnvDp5vH9seGyfzF
8 W/uxobS367uAd2NOYWyv960zc6EEBMeHcGZu0/zeoqiEoD9D4DBVx/P/4ZcWjh6L
9 rRnD3Y4pG0UTND1EJQwEq7Ep2ZxRztz3rIVhcpLQtwNSCRvdg2tPR1AftXPzd84D
10 ZG0nJMpvvo3FwueXHKuEenZbC8C2rDBQwBqxpgJZxMOJkYr1vqaApWs/jncjqGgU
11 tDAjSZ8OpdQxl4QwbLD8AA3Sieplwh2AANlnqQndy+5qsHThO4CjgCZV62i3tlix
12 +voydAknHxBVq2O7fVBDveGmr2J2uYezTaWTTQrQ/EdpZjp5hcXamuimMKw0VFkh
13 mUrFnos/r5mbcXdn1lAosHiU9sEhXokrOBo7AO0k+EcLf3RsdSBV/1k6tRYIuj11
14 Dx6IKCVu+jlni9CzVa4YD9wv8KqoY0cedLNZP9QdlExJZ5UIuagApyM0sijQA+X1
15 EXcuomvVrNLyC68kVySbSqae9gMygCBsQt9ZSln4GkAWgmJcSVU53hckGdh/Fk0l
16 bWTXGuaQvYdsVlXCtiTMW17pSeIZ43eK14s23JtH5WtuFGlNWxE92w==
17 -----END RSA PRIVATE KEY-----
0 -----BEGIN ENCRYPTED PRIVATE KEY-----
1 MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIQIKJS+m0aHQCAggA
2 MBQGCCqGSIb3DQMHBAjpS40JcLsn6gSCBMgq47RGhd+pzf9kWFX47wB+s2oUOFhQ
3 tliBdHa523eG7enigUHrufv7eNiQ9KNpWGKXSV9eb2HBWmrizdJu93s48CzxDXVU
4 hmglHf339bGh89U2MleJcIoeqSeqLHvYb8P28soJ0R5zaW32XgxTy47jGOjlAzac
5 c7xm0YyrV4Tj94J7AKQAsyU7ScyYDe9SSlUIWpmn/dRAz8F6uA4spHRixpXywZPI
6 8pab9WvvB04U6BgT5g0qAKmvssADyhAtguEjgEBjZcOxFWpL4kgY4SEezpez/12t
7 HBUNj0iNV27POTg+jL9LHktjTcqgYxOtSyl/W3NYLFxrkh3Ww4cz7MxzPkOVUOeb
8 LKWEerc8IEaIMzSh+LxbFKgttUxscU6ov9YlGUZx5upqhrT9tQHjhvGtXVUrlSOz
9 1b9BFSq+D23HxugZVXbhabtPW6gnL3z8U2nLIrey2Obt2WjQIn2TiR1uLrcuYz2D
10 EM55EkinW0v7pawok3+d8D5inHc/sOLPyVYcwma84zQ+9Mhlw0DfdiRd/rH5ROcF
11 yc8WA1+BAWvPscJzuqW7nYvpTX6i6FEQPgX8iuz+X2E+M2SSFBM0Jyw1B4Ggsl6u
12 H0zPpQMO8uGxRXl7JXigNdTruIHk0Xwf6fx5Lo+XOEk7zoAyq3LNTQXggjBReAKJ
13 V8qvk4lagBQeEdF8a5YIa2jBhqjc4FlWRAbMZ4f2vVH+LAk+J2qjlbJ3U7+H1w7I
14 A61c7BFdlkhWYuxjx/06khQbx5o46zVT19ykBjOpigJ8fRB2gQyr8346k1i/WZ7/
15 IVJVjWS0jM+o8a2Fin/XxPcKWAJ5t+ePcxl2cytmf9Q703eMdPHjFp2ApPVMGaRC
16 Zkzk/LIgEzXuFIMkLb8+KXKHe1+kRMJDjgT5Nq771K1aE87KWM31qUIfGeLBwUh5
17 YIwLRV5U03Vep7bcwoLUyxUf5i0y/ePBhG01Epng1KFLcIZ3GSUJ6wsrVETE1ggq
18 IM9py9gYhMiuPRZ5VLEP1eJoTSsDv47oh58Tp5REPOjmMSTBYdxG1XxESQBiSlr+
19 2ZrE5i49Zn3Bbz5lkgNE/dpcGunn+cIBXGGcODomtbcKUACWXnOK2+4OsaKLUFr7
20 S+AUP9sNigUDPWZuQQZtoJim1+YZyR+77BXfkeX39KPcsvE7O7cZ/LBFmZRLkRvv
21 2E7n6GymUYrY2DgFiTSfUGafBtb24ALR8xEJ6CmGOeGIl0pGfS3ra7Ar9s2NdHPN
22 yfE0fkgXnXW+misEamPU0SuTXKutTg/+NyCAw9qZrI0X17W8bTeb2xFbi3QNm3Qe
23 sYgUF/9Huia8I+LVvv8dkHZ9ediw1hmAliGOuREb/e/v7d0EshGpxUouNGKcyICX
24 GArW0cEwIjQpm8M+jOigXs49QmWiejuWclEpap6pqUXC15oMpKloJYpinIzyqYft
25 v/P4XhMK5pWHXRRbWzgXGjXS2leMP+uEgwTzROwr3ptLKZUN1e8wpg0HgpVU1YGh
26 ZriiP8R6FLUlPBwd69oqybiqEhDLepbXloegN9uvS5LJM73hIuEZuSW0f/lGOM35
27 fvDqBrcoo3DJTNUBxh/BB0jwoJzeXC6oivIrlMl8nf5fRzIcFcei04PUK5UMSczh
28 5Pk=
29 -----END ENCRYPTED PRIVATE KEY-----
0 A611836B46298A73
0 9DC08797A0F63F7E
11 Data:
22 Version: 3 (0x2)
33 Serial Number:
4 a6:11:83:6b:46:29:8a:71
5 Signature Algorithm: sha1WithRSAEncryption
4 9d:c0:87:97:a0:f6:3f:7d
5 Signature Algorithm: sha256WithRSAEncryption
66 Issuer: C=NL, ST=Noord-Holland, O=Diff Automatisering, OU=Support group, CN=J. van der Steen/emailAddress=info@diff.nl
77 Validity
8 Not Before: Jul 3 15:11:03 2008 GMT
9 Not After : Nov 19 15:11:03 2035 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=University of Amsterdam, OU=Server, CN=Jan Wielemaker/emailAddress=wielemak@science.uva.nl
8 Not Before: Apr 1 09:35:37 2020 GMT
9 Not After : Apr 1 09:35:37 2021 GMT
10 Subject: C=NL, ST=Noord-Holland, L=Amsterdam, O=Diff Automatisering, OU=Server, CN=J. van der Steen/emailAddress=J.van.der.Steen@diff.nl
1111 Subject Public Key Info:
1212 Public Key Algorithm: rsaEncryption
13 RSA Public Key: (1024 bit)
14 Modulus (1024 bit):
15 00:bd:19:49:a3:5b:44:61:19:47:31:f4:d5:8c:c2:
16 bc:fc:86:08:c0:8f:d3:1c:1d:c6:f7:4f:93:f8:d1:
17 57:bf:17:d6:c5:db:34:f3:fc:af:0d:ff:0b:74:61:
18 76:14:b0:72:89:03:37:5c:d6:47:6e:c2:0c:35:f9:
19 7f:52:23:79:4b:ae:59:d8:ae:09:f5:5b:61:ed:d9:
20 29:45:80:df:fc:9b:bb:7f:5a:3b:08:dd:75:2b:29:
21 e8:07:aa:49:29:ba:4c:e8:39:b3:9e:be:03:71:e7:
22 b0:02:14:3a:de:29:17:86:14:68:b2:49:aa:9c:64:
23 01:60:1b:9f:7f:e0:ab:7c:8b
13 Public-Key: (2048 bit)
14 Modulus:
15 00:e7:6c:7a:c1:e9:17:aa:ea:d8:32:73:66:b3:62:
16 ee:3c:7d:c8:e4:3c:59:67:57:67:8d:98:61:24:31:
17 98:23:8f:ef:c3:41:2a:0f:82:1e:6a:6f:2d:00:9e:
18 bf:19:ad:6b:46:42:17:c2:1e:cc:27:b5:c7:66:7a:
19 a5:7b:cc:8c:15:0a:1c:d2:c5:87:23:94:88:42:5e:
20 42:9f:41:22:5a:ad:71:b2:29:54:23:39:cd:05:db:
21 cf:6d:3b:8e:9a:b0:f3:e6:ca:9f:2d:39:28:d6:1c:
22 76:da:34:54:27:f9:a0:0f:1d:ae:32:30:c4:7f:9e:
23 53:18:64:27:2f:05:2b:bf:66:ce:39:52:99:8e:10:
24 1a:80:bf:5e:3a:54:fb:85:da:fc:a7:2d:90:99:42:
25 c7:e2:cf:6a:db:56:1d:3b:bc:0e:97:bf:c5:d4:58:
26 c4:76:33:a2:25:8c:56:94:b4:8d:a9:d3:ab:76:2a:
27 f9:4c:15:de:d1:b8:23:66:3f:36:9a:4b:51:9e:1a:
28 27:e5:f0:38:a3:2a:2a:ab:cd:1c:88:7c:e4:df:82:
29 44:6f:e9:c1:0d:6f:55:98:f4:c0:06:41:ff:1f:c7:
30 30:6a:9a:14:57:73:bd:e0:a7:f7:43:0f:f4:ae:49:
31 b3:48:de:42:fd:0d:be:26:e1:39:4d:24:b8:36:d7:
32 16:43
2433 Exponent: 65537 (0x10001)
2534 X509v3 extensions:
2635 X509v3 Basic Constraints:
2837 Netscape Comment:
2938 OpenSSL Generated Certificate
3039 X509v3 Subject Key Identifier:
31 8F:1F:C9:B8:13:2E:8C:0A:85:B3:50:B4:57:E7:6C:09:16:5F:CE:62
40 01:84:17:EF:98:0D:F4:DD:FC:24:63:09:EF:2F:E6:BE:52:97:7C:17
3241 X509v3 Authority Key Identifier:
33 keyid:20:1B:40:E4:00:18:7C:E6:67:7A:80:16:FE:15:07:9E:BD:77:27:26
42 keyid:E2:7B:60:8C:77:BB:B2:74:B8:FD:D6:2C:A9:D3:B9:35:97:12:87:EC
3443
35 Signature Algorithm: sha1WithRSAEncryption
36 56:f8:23:86:30:6d:3e:ae:1f:91:1d:d5:4e:48:49:d7:cb:72:
37 74:7c:0e:34:07:f1:0d:cd:43:89:ba:ab:10:94:7b:71:2e:22:
38 61:55:ec:14:dd:56:c4:fa:ca:2b:c6:1c:6c:e8:f4:af:36:2d:
39 ca:6e:ed:d8:df:b3:b2:89:57:01:d3:61:53:56:90:02:ab:a8:
40 66:c5:96:19:7e:2e:cc:70:5c:50:bf:fb:6e:e5:58:40:74:5b:
41 de:d3:57:24:09:fb:32:fd:92:c1:07:7c:c0:1f:db:73:de:76:
42 6e:93:c9:e5:97:f7:fa:87:9e:07:1f:09:13:d2:86:17:3f:70:
43 0c:a2
44 Signature Algorithm: sha256WithRSAEncryption
45 9a:b1:75:61:08:bb:ca:dc:b9:cd:3e:5e:30:f8:86:20:2c:e1:
46 47:41:50:c6:a3:e5:b0:d2:08:43:eb:86:9e:5c:2c:7b:4c:40:
47 f9:f2:64:1d:7d:9e:f7:31:78:ef:12:05:ff:b9:4e:48:dc:0c:
48 b9:9d:df:6f:3e:27:e4:a4:55:b7:61:70:9c:6d:97:30:78:5f:
49 72:7a:61:ad:68:96:e6:db:7f:fe:3a:82:52:71:88:42:08:67:
50 ce:13:00:af:8f:e1:fd:bb:fd:c8:a4:cc:a9:4e:93:8f:c2:91:
51 b8:e8:22:86:c0:65:36:e7:25:fb:c3:ca:bb:23:b2:33:fa:41:
52 2c:9c:e7:d8:9f:14:82:1f:a7:ea:20:77:8d:7b:82:3f:22:ea:
53 9b:87:8f:86:eb:f7:15:14:17:12:c0:90:6b:cd:7b:e1:9f:da:
54 96:aa:59:7c:21:01:98:2f:d6:19:e4:7d:60:04:d3:64:65:a3:
55 7b:a4:0f:59:d0:ce:90:1b:e0:6b:55:4f:94:d2:a5:aa:0f:c4:
56 05:b9:e8:e4:7e:11:33:db:77:3f:73:ab:ea:2d:6e:00:07:7e:
57 5a:6c:42:79:dc:06:86:85:3f:44:25:e7:d6:44:b8:b2:2e:f4:
58 f1:a4:60:97:3f:b3:74:29:d7:ec:6d:f1:c4:9c:7b:e4:57:a3:
59 3c:be:17:bb
4460 -----BEGIN CERTIFICATE-----
45 MIIDOzCCAqSgAwIBAgIJAKYRg2tGKYpxMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD
46 VQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEcMBoGA1UEChMTRGlmZiBB
47 dXRvbWF0aXNlcmluZzEWMBQGA1UECxMNU3VwcG9ydCBncm91cDEZMBcGA1UEAxMQ
61 MIIEPjCCAyagAwIBAgIJAJ3Ah5eg9j99MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
62 VQQGEwJOTDEWMBQGA1UECAwNTm9vcmQtSG9sbGFuZDEcMBoGA1UECgwTRGlmZiBB
63 dXRvbWF0aXNlcmluZzEWMBQGA1UECwwNU3VwcG9ydCBncm91cDEZMBcGA1UEAwwQ
4864 Si4gdmFuIGRlciBTdGVlbjEbMBkGCSqGSIb3DQEJARYMaW5mb0BkaWZmLm5sMB4X
49 DTA4MDcwMzE1MTEwM1oXDTM1MTExOTE1MTEwM1owga0xCzAJBgNVBAYTAk5MMRYw
50 FAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNV
51 BAoTF1VuaXZlcnNpdHkgb2YgQW1zdGVyZGFtMQ8wDQYDVQQLEwZTZXJ2ZXIxFzAV
52 BgNVBAMTDkphbiBXaWVsZW1ha2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0Bz
53 Y2llbmNlLnV2YS5ubDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvRlJo1tE
54 YRlHMfTVjMK8/IYIwI/THB3G90+T+NFXvxfWxds08/yvDf8LdGF2FLByiQM3XNZH
55 bsIMNfl/UiN5S65Z2K4J9Vth7dkpRYDf/Ju7f1o7CN11KynoB6pJKbpM6Dmznr4D
56 ceewAhQ63ikXhhRoskmqnGQBYBuff+CrfIsCAwEAAaN7MHkwCQYDVR0TBAIwADAs
57 BglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYD
58 VR0OBBYEFI8fybgTLowKhbNQtFfnbAkWX85iMB8GA1UdIwQYMBaAFCAbQOQAGHzm
59 Z3qAFv4VB569dycmMA0GCSqGSIb3DQEBBQUAA4GBAFb4I4YwbT6uH5Ed1U5ISdfL
60 cnR8DjQH8Q3NQ4m6qxCUe3EuImFV7BTdVsT6yivGHGzo9K82Lcpu7djfs7KJVwHT
61 YVNWkAKrqGbFlhl+LsxwXFC/+27lWEB0W97TVyQJ+zL9ksEHfMAf23Pedm6TyeWX
62 9/qHngcfCRPShhc/cAyi
65 DTIwMDQwMTA5MzUzN1oXDTIxMDQwMTA5MzUzN1owgasxCzAJBgNVBAYTAk5MMRYw
66 FAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHDAlBbXN0ZXJkYW0xHDAaBgNV
67 BAoME0RpZmYgQXV0b21hdGlzZXJpbmcxDzANBgNVBAsMBlNlcnZlcjEZMBcGA1UE
68 AwwQSi4gdmFuIGRlciBTdGVlbjEmMCQGCSqGSIb3DQEJARYXSi52YW4uZGVyLlN0
69 ZWVuQGRpZmYubmwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnbHrB
70 6Req6tgyc2azYu48fcjkPFlnV2eNmGEkMZgjj+/DQSoPgh5qby0Anr8ZrWtGQhfC
71 HswntcdmeqV7zIwVChzSxYcjlIhCXkKfQSJarXGyKVQjOc0F289tO46asPPmyp8t
72 OSjWHHbaNFQn+aAPHa4yMMR/nlMYZCcvBSu/Zs45UpmOEBqAv146VPuF2vynLZCZ
73 Qsfiz2rbVh07vA6Xv8XUWMR2M6IljFaUtI2p06t2KvlMFd7RuCNmPzaaS1GeGifl
74 8DijKiqrzRyIfOTfgkRv6cENb1WY9MAGQf8fxzBqmhRXc73gp/dDD/SuSbNI3kL9
75 Db4m4TlNJLg21xZDAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8W
76 HU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQBhBfvmA30
77 3fwkYwnvL+a+Upd8FzAfBgNVHSMEGDAWgBTie2CMd7uydLj91iyp07k1lxKH7DAN
78 BgkqhkiG9w0BAQsFAAOCAQEAmrF1YQi7yty5zT5eMPiGICzhR0FQxqPlsNIIQ+uG
79 nlwse0xA+fJkHX2e9zF47xIF/7lOSNwMuZ3fbz4n5KRVt2FwnG2XMHhfcnphrWiW
80 5tt//jqCUnGIQghnzhMAr4/h/bv9yKTMqU6Tj8KRuOgihsBlNucl+8PKuyOyM/pB
81 LJzn2J8Ugh+n6iB3jXuCPyLqm4ePhuv3FRQXEsCQa8174Z/alqpZfCEBmC/WGeR9
82 YATTZGWje6QPWdDOkBvga1VPlNKlqg/EBbno5H4RM9t3P3Or6i1uAAd+WmxCedwG
83 hoU/RCXn1kS4si708aRglz+zdCnX7G3xxJx75FejPL4Xuw==
6384 -----END CERTIFICATE-----
0 -----BEGIN RSA PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: DES-EDE3-CBC,E3E8E2A5E1403F5E
3
4 Q5tlYh5soGvk/arzLBEawOWJHRF9ISivcjlWPE9fqH3pkvvthA7ntCEjKSXlzRPA
5 eNP3yZVL59zmgyZiS3QlpX4XwEugoSmXaLiDY3AWKBrQ6G+KHipJ+LmDPzupbPia
6 078nR6jIDPkS99lg3ogk27UbyI2E9iPoVHKsWiX/L0IvdxB8NjsHdwa+97EoVXRB
7 pyLTpEuXQHopqtDikMlfinE1u/yhybrXRNBncQ083+rZ2gTDGQsm7AXtynPRvlgG
8 BaJl0FGeruVihbJ5o0D8xzN2IdHKsDtde/udyE8njD3f+yLDuM91qHnoeefm8J+X
9 Txc+mQ3srqiaI5ZyYVZG728lEHeNooddIsrrM2VGkd9CveGzYCuMOc4LUTrLorb9
10 wV9te2hTRICI+b+7i7yN6yVKcsrIX249HNFQ2E6i5tZcyZIrL2TzL/niS5g+jlwN
11 FLk2WgldG3kHGhFzNWDFkM64YShYHWGPvysUYx0/hcixrJsXJV8AbmdsG6Mzw3XJ
12 z4A9dPUTyYi7vqPzm6aMohZp/RSY0D6o6qBYtDL/toj5btzEf1T2jzwZwPovRWwT
13 5sPxWts2g7bqhMnpRCwo+pEd51sBZAFz4MOMEJR7zzvO9mcAWvO3zopRH0ugzuwl
14 yHXSXPdU/04Auv63EEiZO01/PDNm6KAvAsEIkj9x6n678wJ609J+G2IC0E7i7ZfQ
15 lkcX18AWq7ydcxAygfl/RT8tOKhTpXRemqu9JU7c9yjD3HqRpOW6VrPsLXKXL4UC
16 6R1n88SinCCnPMSVeNhhJrpI1L3XgJPb9zh9I7tpE7o2KvwBoc8/rg==
17 -----END RSA PRIVATE KEY-----
18 -----BEGIN CERTIFICATE REQUEST-----
19 MIICLjCCAZcCAQAwga0xCzAJBgNVBAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1Ib2xs
20 YW5kMRIwEAYDVQQHEwlBbXN0ZXJkYW0xIDAeBgNVBAoTF1VuaXZlcnNpdHkgb2Yg
21 QW1zdGVyZGFtMQ8wDQYDVQQLEwZTZXJ2ZXIxFzAVBgNVBAMTDkphbiBXaWVsZW1h
22 a2VyMSYwJAYJKoZIhvcNAQkBFhd3aWVsZW1ha0BzY2llbmNlLnV2YS5ubDCBnzAN
23 BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvRlJo1tEYRlHMfTVjMK8/IYIwI/THB3G
24 90+T+NFXvxfWxds08/yvDf8LdGF2FLByiQM3XNZHbsIMNfl/UiN5S65Z2K4J9Vth
25 7dkpRYDf/Ju7f1o7CN11KynoB6pJKbpM6Dmznr4DceewAhQ63ikXhhRoskmqnGQB
26 YBuff+CrfIsCAwEAAaBAMBYGCSqGSIb3DQEJBzEJEwdub290amVzMCYGCSqGSIb3
27 DQEJAjEZExdVbml2ZXJzaXR5IG9mIEFtc3RlcmRhbTANBgkqhkiG9w0BAQQFAAOB
28 gQBophWFXJO86vms/b86illcnZTb/vfRM9aKT4DrfpOjgW6Dmk95VwPqGFIoxfnd
29 yRokzKvOoW2JMZ+u9Jz7q1R2AEkRivRjVoSY8Cd+YqsFBiD5vt8eHI8jqqoMEl2D
30 iQWjre7hFij7bY6flVerTV0dsz6MHRPbzAkvJohAceHgKQ==
31 -----END CERTIFICATE REQUEST-----
0 -----BEGIN ENCRYPTED PRIVATE KEY-----
1 MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIUZoWaoXwEL4CAggA
2 MBQGCCqGSIb3DQMHBAiLJma8RXDpzQSCBMhVAz+QXJhiJw5epX1BiJL7j/09s8mb
3 uXxgpJhE40kAbwAvykq6FOmjubrE6bPx0n8Dk4b/KroKjjS6DV0AX4jvrep43T/z
4 IRHqjDdYOHAyIi9yXQGsFkeHdIEo7vXU1zA4Om+K3wreK07Pz4YfiKAWF6/6xJj4
5 fue8zXGgLB6fiWQs4EbH7EiCYgVuypU50sUa/AnpWXe9ITVBssjeHCjTphxHtL8j
6 rT+JBv0XpdAYcBOX4irk8zEq+432/RL7DPi2ercBpDQeaAsMfyTOrhptUkAcyj0/
7 PTFsrxchtyS5HQbR7yKhio2bxAGCinsWD/WSLU95RzT83rSgMth4q9nURqVKE7Y1
8 LsnMa9YIyITdKPSzyA8rmcylghK23PDGhYDw1pZIhbpcGNjiLSyI4js68urIwpK1
9 xdQv9Oouq8U5SJNLH7jNJVIfmtOIVnJEy+GoSgNtQn7f9LrLfZtccWNsejuKxvDi
10 NKmhrUvoMLD7lN6CH7CWtUe3o523Q/a4XXJYnTrFz4viKS8ig5ljfzOzq1XimJJb
11 /EmKStoiRIeTC0MBmCu0uo43oaT+AihvZZB+TPUV/L0T0kV7rd0n59RxFmwOlO7j
12 iSOz1cy2jmILiDh4gAdH43H6WG6I38q23rLyt/EMVh/1DgJlndfdVVKk4VvFT/Bx
13 MjgEEvrf/VC7idy6mQea4tWJ+lXag64phwXt0zja3v/tVKhVJPyFlFLgslve7ZKt
14 8r8nFTFcZSyVt2Qi+kRL3Iuu/lRkvOcaeK5VdtjV4PV+Pmk6VvecptSr2pkfUTdy
15 wFgKWBjwruINfcIoFyegL4cUyWWcQDwSfWTT0WAWt6kLvf0xjK6jjcFvFn46RHFf
16 zQbnmyqo20nKRhR88EJTuqevyLRUG1EBQwSyWuq4m/5XTy5nFIWcWIx6bF/hsk9C
17 ZB/aq2+4pw6oZlEb7yXdaLvlRXuhmiqUbff2xW/lcG77AWDm3as0J7O6OZg+7170
18 DdP99viL/K1+O0gZZDkl/YGdJgy6eHA0GXC1Xz6vARRxexxwvJQfXb5R2FnMENxm
19 sCTqZwIXYPCWnQ7IoRUHl4q8uMTdxCZiIoXglzX+O5XTxPUOYk8HeEohIppAt5l/
20 dB9lMfQmM/GEOXYlI8gEPNJ4vVBiulpzbIfHT9qAZVpH4+++Hwo6xYT2z/L46Ax2
21 IlFS1TMd9f9PkPf/Vh+aezcw6YfIUEJ6YTuOjmSgSpPshQKC4mgTtIayOEJTuBih
22 EAf+nq940RaKlittUi5s1YZbxwkV+YXz6DsK6L4UypmU2Dlg/aWaEFQsIUULSNgi
23 FrlzJZwRJdFhcQhvkr2WUk5JxcScydPRqhhk7ZL2EVzgGqdNfg3aq9jZGBQYthqL
24 DxcSQcrolOj2p2DUAUGJdtBGpzddz77qB81E4Sy3rsratycaDBARADORqrPEXdSi
25 DBhSFCCARpZtIxALPjANLL8Jx1kz9H4bZcp0z+M9l+pSfjpXEbWOKD/OpCqlvhCK
26 4EiLhYYoUZWPQeZf0khgIZk9n0PvnUb5oJYONdnCb4fBgEDUMQ0wijCw3D5QMC0Y
27 Es2tHhIGqwxjaI5SmmOET1tYznInffvsWhvN8WESirISrjM9KZx608bpHRV47oXi
28 O7g=
29 -----END ENCRYPTED PRIVATE KEY-----
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2007-2018, University of Amsterdam
5 Copyright (c) 2007-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
3737 :- use_module(library(ssl),
3838 [ ssl_context/3,
3939 ssl_secure_ciphers/1,
40 ssl_property/2,
4041 ssl_set_options/3,
4142 ssl_negotiate/5
4243 ]).
5354
5455 :- autoload(library(lists),[select/3]).
5556 :- autoload(library(option),[option/2,option/3]).
57 :- autoload(library(apply), [include/3]).
5658 :- autoload(library(http/http_header),[http_read_reply_header/2]).
5759 :- autoload(library(http/thread_httpd),[http_enough_workers/3]).
5860
9698 add_secure_ciphers(SSLOptions0, SSLOptions1),
9799 disable_sslv3(SSLOptions1, SSLOptions),
98100 make_socket(Port, Socket, Options1),
99 ssl_context(server, SSL0, M:SSLOptions),
100 ( http:ssl_server_create_hook(SSL0, SSL, Options1)
101 -> true
101 ssl_context(server, SSL0, M:[close_parent(true)|SSLOptions]),
102 ( http:ssl_server_create_hook(SSL0, SSL1, Options1)
103 -> ensure_close_parent(SSL1, SSL)
102104 ; SSL = SSL0
103105 ),
104106 atom_concat('httpsd', Port, Queue),
108110 | Options1
109111 ].
110112
113 ensure_close_parent(SSL0, SSL) :-
114 ( ssl_property(SSL0, close_parent(true))
115 -> SSL = SSL0
116 ; ssl_set_options(SSL0, SSL, [close_parent(true)])
117 ).
118
111119 %! add_secure_ciphers(+SSLOptions0, -SSLOptions)
112120 %
113121 % Add ciphers from ssl_secure_ciphers/1 if no ciphers are provided.
153161 % Implement the accept for HTTPS connections.
154162
155163 thread_httpd:accept_hook(Goal, Options) :-
156 memberchk(ssl_instance(SSL), Options),
164 memberchk(ssl_instance(SSL0), Options),
157165 !,
158166 memberchk(queue(Queue), Options),
159167 memberchk(tcp_socket(Socket), Options),
160168 tcp_accept(Socket, Client, Peer),
161169 debug(http(connection), 'New HTTPS connection from ~p', [Peer]),
162170 http_enough_workers(Queue, accept, Peer),
171 ensure_close_parent(SSL0, SSL),
163172 thread_send_message(Queue, ssl_client(SSL, Client, Goal, Peer)).
164173
165174 %! http:ssl_server_create_hook(+SSL0, -SSL, +Options) is semidet.
187196 Goal, In, Out,
188197 [peer(Peer), protocol(https)],
189198 Options) :-
190 ( http:ssl_server_open_client_hook(SSL0, SSL1, Options)
199 ( http:ssl_server_open_client_hook(SSL0, SSL, Options)
191200 -> true
192 ; SSL1 = SSL0
201 ; SSL = SSL0
193202 ),
194203 option(timeout(TMO), Options, 60),
195204 tcp_open_socket(Client, Read, Write),
196205 set_stream(Read, timeout(TMO)),
197206 set_stream(Write, timeout(TMO)),
198 ssl_set_options(SSL1, SSL, [close_parent(true)]),
199207 catch(ssl_negotiate(SSL, Read, Write, In, Out),
200208 E,
201209 ssl_failed(Read, Write, E)).
223231
224232 ssl_protocol_hook(Parts, PlainStreamPair, StreamPair, Options) :-
225233 memberchk(host(Host), Parts),
234 include(ssl_option, Options, SSLOptions),
226235 ssl_context(client, SSL, [ host(Host),
227236 close_parent(true)
228 | Options
237 | SSLOptions
229238 ]),
230239 stream_pair(PlainStreamPair, PlainIn, PlainOut),
231240 % if an exception arises, http_open/3 closes the stream for us
232241 ssl_negotiate(SSL, PlainIn, PlainOut, In, Out),
233242 stream_pair(StreamPair, In, Out).
234243
244 % Might be better to be more selective, but passing the options from
245 % http_open/3 with more than 1 argument makes ssl_context/3 fail.
246
247 ssl_option(Term) :-
248 compound(Term),
249 compound_name_arity(Term, _, 1).
235250
236251 %! http:http_connection_over_proxy(+Proxy, +Parts, +HostPort, -StreamPair,
237252 %! +OptionsIn, -OptionsOut)
44 WWW: http://www.swi-prolog.org
55 Copyright (c) 2004-2020, SWI-Prolog Foundation
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
4748 ssl_context/3, % +Role, -Config, :Options
4849 ssl_add_certificate_key/4, % +Config, +Cert, +Key, -Config
4950 ssl_set_options/3, % +Config0, -Config, +Options
51 ssl_property/2, % +Config, ?Property
5052 ssl_negotiate/5, % +Config, +PlainRead, +PlainWrite,
5153 % -SSLRead, -SSLWrite
5254 ssl_peer_certificate/2, % +Stream, -Certificate
7274 :- predicate_options(ssl_context/3, 3,
7375 [ host(atom),
7476 port(integer),
77 cacerts(list),
7578 certificate_file(atom),
7679 key_file(atom),
7780 certificate_key_pairs(any),
358361 ssl_copy_context(SSL0, SSL),
359362 '_ssl_add_certificate_key'(SSL, Cert, Key).
360363
361 ssl_copy_context(SSL0, SSL) :-
362 ssl_context(server, SSL, []),
363 '_ssl_init_from_context'(SSL0, SSL).
364
365364 %! ssl_set_options(+SSL0, -SSL, +Options)
366365 %
367366 % SSL is the same as SSL0, except for the options specified in
377376 ssl_set_options(SSL0, SSL, Options) :-
378377 ssl_copy_context(SSL0, SSL),
379378 '_ssl_set_options'(SSL, Options).
379
380 %! ssl_property(+SSL, ?Property) is semidet.
381 %
382 % True when Property is a property of SSL. Defined properties are:
383 %
384 % - close_parent(?Bool)
385 %
386 % @tbd This version is a very minimal implementation of the generic
387 % property interface. Future versions will add more properties and
388 % non-determinism.
380389
381390 %! ssl_negotiate(+SSL,
382391 %! +PlainRead, +PlainWrite,
33 Markus Triska and James Cash
44 E-mail: J.Wielemaker@vu.nl
55 WWW: http://www.swi-prolog.org
6 Copyright (c) 2004-2018, SWI-Prolog Foundation
6 Copyright (c) 2004-2020, SWI-Prolog Foundation
77 VU University Amsterdam
8 CWI, Amsterdam
89 All rights reserved.
910
1011 Redistribution and use in source and binary forms, with or without
144145 static functor_t FUNCTOR_certificate1;
145146
146147 typedef enum
147 { PL_SSL_NONE
148 , PL_SSL_SERVER
149 , PL_SSL_CLIENT
148 { PL_SSL_NONE,
149 PL_SSL_SERVER,
150 PL_SSL_CLIENT
150151 } PL_SSL_ROLE;
151152
152153 typedef enum
153 { SSL_PL_OK
154 , SSL_PL_RETRY
155 , SSL_PL_ERROR
154 { SSL_PL_OK,
155 SSL_PL_RETRY,
156 SSL_PL_ERROR
156157 } SSL_PL_STATUS;
157158
158159 #define SSL_CERT_VERIFY_MORE 0
167168 static int ssl_idx;
168169 static int ctx_idx;
169170
170 typedef struct pl_cert_key_pair {
171 X509 *certificate_X509;
172 char *key;
173 char *certificate;
171 typedef struct pl_cert_key_pair
172 { X509 *certificate_X509;
173 char *key;
174 char *certificate;
174175 } PL_CERT_KEY_PAIR;
175176
176 typedef struct pl_ssl_callback {
177 record_t goal;
178 module_t module;
177 typedef struct pl_ssl_callback
178 { record_t goal;
179 module_t module;
179180 } PL_SSL_CALLBACK;
180181
181 typedef struct pl_ssl_protocol {
182 BOOL is_set;
183 int version;
182 typedef struct pl_ssl_protocol
183 { BOOL is_set;
184 int version;
184185 } PL_SSL_PROTOCOL;
185186
186 typedef struct pl_ssl {
187 long magic;
187 typedef struct
188 { int references;
189 STACK_OF(X509) *cacerts;
190 } cacert_stack;
191
192 typedef struct pl_ssl
193 { long magic;
188194 /*
189195 * Are we server or client
190196 */
191 PL_SSL_ROLE role;
192
193 int close_parent;
194 atom_t atom;
195 BOOL close_notify;
196
197 /*
198 * Context, Certificate, SSL info
199 */
200 SSL_CTX *ctx;
201 int idx;
202 X509 *peer_cert;
203
204 /*
205 * In case of the client the host we're connecting to.
206 */
207 char *host;
208
209 /*
210 * Various parameters affecting the SSL layer
211 */
212 STACK_OF(X509) *cacerts;
213
214 char *certificate_file;
215 char *key_file;
216 PL_CERT_KEY_PAIR cert_key_pairs[SSL_MAX_CERT_KEY_PAIRS];
217 int num_cert_key_pairs;
218
219 char *cipher_list;
220 char *ecdh_curve;
221 STACK_OF(X509_CRL) *crl_list;
222 char *password;
223 BOOL crl_required;
224 BOOL peer_cert_required;
225
226 PL_SSL_PROTOCOL min_protocol;
227 PL_SSL_PROTOCOL max_protocol;
228
229 /*
230 * Application defined handlers
231 */
232 PL_SSL_CALLBACK cb_cert_verify;
233 PL_SSL_CALLBACK cb_pem_passwd;
234 PL_SSL_CALLBACK cb_sni;
235 PL_SSL_CALLBACK cb_alpn_proto;
197 PL_SSL_ROLE role;
198
199 int close_parent;
200 atom_t atom;
201 BOOL close_notify;
202
203 /*
204 * Context, Certificate, SSL info
205 */
206 SSL_CTX *ctx;
207 int idx;
208 X509 *peer_cert;
209
210 /*
211 * In case of the client the host we're connecting to.
212 */
213 char *host;
214
215 /*
216 * Various parameters affecting the SSL layer
217 */
218 cacert_stack *cacerts;
219
220 char *certificate_file;
221 char *key_file;
222 PL_CERT_KEY_PAIR cert_key_pairs[SSL_MAX_CERT_KEY_PAIRS];
223 int num_cert_key_pairs;
224
225 char *cipher_list;
226 char *ecdh_curve;
227 STACK_OF(X509_CRL) *crl_list;
228 char *password;
229 BOOL crl_required;
230 BOOL peer_cert_required;
231
232 PL_SSL_PROTOCOL min_protocol;
233 PL_SSL_PROTOCOL max_protocol;
234
235 /*
236 * Application defined handlers
237 */
238 PL_SSL_CALLBACK cb_cert_verify;
239 PL_SSL_CALLBACK cb_pem_passwd;
240 PL_SSL_CALLBACK cb_sni;
241 PL_SSL_CALLBACK cb_alpn_proto;
236242 #ifndef HAVE_X509_CHECK_HOST
237 int hostname_check_status;
238 #endif
239 unsigned char *alpn_protos;
240 size_t alpn_protos_len;
243 int hostname_check_status;
244 #endif
245 unsigned char *alpn_protos;
246 size_t alpn_protos_len;
241247 } PL_SSL;
242248
243 typedef struct ssl_instance {
244 PL_SSL *config;
245 SSL *ssl;
246 IOSTREAM *sread; /* wire streams */
247 IOSTREAM *swrite;
248 IOSTREAM *dread; /* data streams */
249 IOSTREAM *dwrite;
250 int close_needed;
251 BOOL fatal_alert;
249 typedef struct ssl_instance
250 { PL_SSL *config;
251 SSL *ssl;
252 IOSTREAM *sread; /* wire streams */
253 IOSTREAM *swrite;
254 IOSTREAM *dread; /* data streams */
255 IOSTREAM *dwrite;
256 int close_needed;
257 BOOL fatal_alert;
252258 } PL_SSL_INSTANCE;
253259
254260
256262 { RSA_MODE, EVP_MODE
257263 } crypt_mode_t;
258264
265
266 /*******************************
267 * ATOMIC *
268 *******************************/
269
270 #define ATOMIC_ADD(ptr, v) __atomic_add_fetch(ptr, v, __ATOMIC_SEQ_CST)
271 #define ATOMIC_SUB(ptr, v) __atomic_sub_fetch(ptr, v, __ATOMIC_SEQ_CST)
272 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
273 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
274 #define __COMPARE_AND_SWAP(at, from, to) \
275 __atomic_compare_exchange_n(at, &(from), to, FALSE, \
276 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
277
278 static inline int
279 COMPARE_AND_SWAP_PTR(void *at, void *from, void *to)
280 { void **ptr = at;
281
282 return __COMPARE_AND_SWAP(ptr, from, to);
283 }
284
285
286 /*******************************
287 * MANAGE STRUCT VALUES *
288 *******************************/
289
290 #define set_string(obj, field, str) \
291 attr_set_string(&((obj)->field), str)
292
293 static void
294 attr_set_string(char **where, const char *str)
295 { if ( *where )
296 free(*where);
297 if ( str )
298 *where = ssl_strdup(str);
299 }
300
301 static cacert_stack *
302 new_cacert_stack(void)
303 { cacert_stack *s = malloc(sizeof(*s));
304
305 if ( s )
306 { s->references = 1;
307 if ( !(s->cacerts=sk_X509_new_null()) )
308 { free(s);
309 s = NULL;
310 }
311 }
312
313 return s;
314 }
315
316 static cacert_stack *
317 dup_cacert_stack(cacert_stack *s)
318 { if ( s )
319 ATOMIC_INC(&s->references);
320
321 return s;
322 }
323
324 static void
325 free_cacert_stack(cacert_stack *s)
326 { if ( s && ATOMIC_DEC(&s->references) == 0 )
327 { sk_X509_pop_free(s->cacerts, X509_free);
328 free(s);
329 }
330 }
331
332 /*******************************
333 * GET TYPED TERM ARGUMENTS *
334 *******************************/
335
259336 static int
260337 get_char_arg(int a, term_t t, char **s)
261338 { term_t t2 = PL_new_term_ref();
262339
263340 _PL_get_arg(a, t, t2);
264 if ( !PL_get_chars(t2, s, CVT_ATOM|CVT_STRING|CVT_EXCEPTION) )
265 return FALSE;
266
267 return TRUE;
341 return PL_get_chars(t2, s, CVT_ATOM|CVT_STRING|CVT_EXCEPTION);
268342 }
269343
270344
273347 { term_t t2 = PL_new_term_ref();
274348
275349 _PL_get_arg(a, t, t2);
276 if ( !PL_get_bool_ex(t2, i) )
277 return FALSE;
278
279 return TRUE;
350 return PL_get_bool_ex(t2, i);
280351 }
281352
282353
285356 { term_t t2 = PL_new_term_ref();
286357
287358 _PL_get_arg(a, t, t2);
288 if ( !PL_get_file_name(t2, f, PL_FILE_EXIST) )
289 return FALSE;
290
291 return TRUE;
359 return PL_get_file_name(t2, f, PL_FILE_EXIST);
292360 }
293361
294362
295363 static int
296364 unify_bignum(term_t t, const BIGNUM *bn)
297 {
298 int rc;
365 { int rc;
366
299367 if ( bn )
300368 { char *hex = BN_bn2hex(bn);
301369
302370 rc = PL_unify_chars(t, PL_STRING|REP_ISO_LATIN_1, (size_t)-1, hex);
303371 OPENSSL_free(hex);
304372 } else
305 rc = PL_unify_atom(t, ATOM_minus);
373 { rc = PL_unify_atom(t, ATOM_minus);
374 }
306375
307376 return rc;
308377 }
342411
343412 if (time->type == V_ASN1_UTCTIME)
344413 { if ((length < 11) || (length > 17))
345 { ssl_deb(2, "Unable to parse time - expected either 11 or 17 chars, not %d", length);
414 { ssl_deb(2, "Unable to parse time - expected either 11 or 17 chars,"
415 " not %d", length);
346416 return FALSE;
347417 }
348418 /* Otherwise just get the first 10 chars - ignore seconds */
352422 length -= 10;
353423 } else
354424 { if (length < 13)
355 { ssl_deb(2, "Unable to parse time - expected at least 13 chars, not %d", length);
425 { ssl_deb(2, "Unable to parse time - expected at least 13 chars,"
426 " not %d", length);
356427 return FALSE;
357428 }
358429 /* Otherwise just get the first 12 chars - ignore seconds */
379450
380451 /* If not UTC, calculate offset */
381452 if (*source == 'Z')
382 lSecondsFromUTC = 0;
383 else
453 { lSecondsFromUTC = 0;
454 } else
384455 { if ( length < 6 || (*source != '+' && source[5] != '-') )
385456 { ssl_deb(2, "Unable to parse time. Missing UTC offset");
386457 return FALSE;
401472 time_tm.tm_year += 100; /* according to RFC 2459 */
402473 time_tm.tm_wday = 0;
403474 time_tm.tm_yday = 0;
404 time_tm.tm_isdst = 0; /* No DST adjustment requested, though mktime might do it anyway */
475 time_tm.tm_isdst = 0; /* No DST adjustment requested, though */
476 /* mktime might do it anyway */
405477
406478 #ifdef HAVE_TIMEGM
407479 result = timegm(&time_tm);
413485 }
414486 #else
415487 result = mktime(&time_tm);
416 /* mktime assumes that the time_tm contains information for localtime. Convert back to UTC: */
488 /* mktime assumes that the time_tm contains information for localtime. */
489 /* Convert back to UTC: */
417490 if ((time_t)-1 != result)
418491 { result += lSecondsFromUTC; /* Add in the UTC offset of the original value */
419492 result -= timezone; /* Adjust for localtime */
429502 static const EVP_MD *
430503 algorithm_to_type(const ASN1_OBJECT* algorithm, int *nid)
431504 { *nid = OBJ_obj2nid(algorithm);
432 /* Annoyingly, EVP_get_digestbynid doesnt work for some of these algorithms. Instead check for
433 them explicitly and set the digest manually
505 /* Annoyingly, EVP_get_digestbynid doesnt work for some of these
506 algorithms. Instead check for them explicitly and set the digest manually
434507 */
435508 switch (*nid)
436509 { case NID_ecdsa_with_SHA1:
451524 #if defined(HAVE_X509_DIGEST) && defined(HAVE_X509_CRL_DIGEST)
452525
453526 static int
454 hash_X509_digest_wrapper(const void *data, const EVP_MD *type, unsigned char* md, unsigned int *l)
455 {
456 return X509_digest((X509 *) data, type, md, l);
457 }
458
459 static int
460 hash_X509_crl_digest_wrapper(const void *data, const EVP_MD *type, unsigned char* md, unsigned int *l)
461 {
462 return X509_CRL_digest((X509_CRL *) data, type, md, l);
527 hash_X509_digest_wrapper(const void *data, const EVP_MD *type,
528 unsigned char* md, unsigned int *l)
529 { return X509_digest((X509 *) data, type, md, l);
530 }
531
532 static int
533 hash_X509_crl_digest_wrapper(const void *data, const EVP_MD *type,
534 unsigned char* md, unsigned int *l)
535 { return X509_CRL_digest((X509_CRL *) data, type, md, l);
463536 }
464537
465538 static int
466539 unify_hash(term_t hash, const ASN1_OBJECT* algorithm,
467 int (*data_to_digest)(const void*, const EVP_MD *, unsigned char*, unsigned int*),
540 int (*data_to_digest)(const void*, const EVP_MD *,
541 unsigned char*, unsigned int*),
468542 void *data)
469 {
470 int nid;
543 { int nid;
471544 const EVP_MD *type = algorithm_to_type(algorithm, &nid);
472545 unsigned char digest[EVP_MAX_MD_SIZE];
473546 unsigned int digest_length;
474547
475 if (type == NULL)
548 if ( type == NULL )
476549 return PL_unify_term(hash,
477550 PL_FUNCTOR, FUNCTOR_unsupported_hash_algorithm1,
478551 PL_INT, nid);
479552
480 if (!data_to_digest(data, type, digest, &digest_length))
553 if ( !data_to_digest(data, type, digest, &digest_length) )
481554 return FALSE;
482555
483556 return unify_bytes_hex(hash, digest_length, digest);
485558
486559 #else
487560
488 static int i2d_X509_CRL_INFO_wrapper(void* i, unsigned char** d)
489 {
490 return i2d_X509_CRL_INFO(i, d);
491 }
492
493 static int i2d_X509_CINF_wrapper(void* i, unsigned char** d)
494 {
495 return i2d_X509_CINF(i, d);
561 static int
562 i2d_X509_CRL_INFO_wrapper(void* i, unsigned char** d)
563 { return i2d_X509_CRL_INFO(i, d);
564 }
565
566 static int
567 i2d_X509_CINF_wrapper(void* i, unsigned char** d)
568 { return i2d_X509_CINF(i, d);
496569 }
497570
498571
509582 unsigned char* p;
510583 /* Generate hash */
511584
512 if (type == NULL)
585 if ( type == NULL )
513586 return PL_unify_term(hash,
514587 PL_FUNCTOR, FUNCTOR_unsupported_hash_algorithm1,
515588 PL_INT, nid);
516589
517590 digestible_length=i2d(data,NULL);
518591 digest_buffer = PL_malloc(digestible_length);
519 if (digest_buffer == NULL)
592 if ( digest_buffer == NULL )
520593 return PL_resource_error("memory");
521594
522595 /* i2d_X509_CINF will change the value of p. We need to pass in a copy */
551624 term_t list = PL_copy_term_ref(term);
552625 term_t item = PL_new_term_ref();
553626
554 if (name == NULL)
555 return PL_unify_term(term,
556 PL_CHARS, "<null>");
627 if ( name == NULL )
628 return PL_unify_term(term, PL_CHARS, "<null>");
629
557630 for (ni = 0; ni < X509_NAME_entry_count(name); ni++)
558631 { X509_NAME_ENTRY* e = X509_NAME_get_entry(name, ni);
559632 ASN1_STRING* entry_data = X509_NAME_ENTRY_get_data(e);
564637 return PL_resource_error("memory");
565638
566639 rc = ( PL_unify_list(list, item, list) &&
567 PL_unify_term(item,
568 PL_FUNCTOR, FUNCTOR_equals2,
569 PL_CHARS, OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(e))),
570 PL_UTF8_CHARS, utf8_data)
640 PL_unify_term(
641 item,
642 PL_FUNCTOR, FUNCTOR_equals2,
643 PL_CHARS, OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(e))),
644 PL_UTF8_CHARS, utf8_data)
571645 );
572646 OPENSSL_free(utf8_data);
573647 if ( !rc )
574648 return FALSE;
575649 }
650
576651 return PL_unify_nil(list);
577652 }
578653
584659 #ifndef HAVE_X509_CRL_GET0_SIGNATURE
585660 /* Avoid conflict if the prototype is there, but the function is not */
586661 #define X509_CRL_get0_signature my_X509_CRL_get0_signature
662
587663 static void
588 X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, const X509_ALGOR **palg)
589 {
590 *psig = crl->signature;
664 X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
665 const X509_ALGOR **palg)
666 { *psig = crl->signature;
591667 *palg = crl->sig_alg;
592668 }
593669 #endif
595671 #ifndef HAVE_X509_GET0_SIGNATURE
596672 /* Avoid conflict if the prototype is there, but the function is not */
597673 #define X509_get0_signature my_X509_get0_signature
674
598675 static void
599 X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, const X509 *data)
676 X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg,
677 const X509 *data)
600678 {
601679 *psig = data->signature;
602680 *palg = data->sig_alg;
606684
607685 static int
608686 unify_crl(term_t term, X509_CRL* crl)
609 {
610 const ASN1_BIT_STRING *psig;
687 { const ASN1_BIT_STRING *psig;
611688 const X509_ALGOR *palg;
612689 STACK_OF(X509_REVOKED) *revoked = X509_CRL_get_REVOKED(crl);
613690 int i;
633710 i2a_ASN1_INTEGER(mem, (ASN1_BIT_STRING *) psig);
634711 if (!(unify_name(issuer, X509_CRL_get_issuer(crl)) &&
635712 #ifdef HAVE_X509_CRL_DIGEST
636 unify_hash(hash, palg->algorithm, hash_X509_crl_digest_wrapper, crl) &&
713 unify_hash(hash, palg->algorithm, hash_X509_crl_digest_wrapper, crl) &&
637714 #else
638715 unify_hash(hash, palg->algorithm, i2d_X509_CRL_INFO_wrapper, crl->crl) &&
639716 #endif
651728 PL_TERM, next_update,
652729 PL_FUNCTOR, FUNCTOR_revocations1,
653730 PL_TERM, revocations)))
654 {
655 return FALSE;
656 }
731 { return FALSE;
732 }
733
657734 for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
658 { X509_REVOKED *r = sk_X509_REVOKED_value(revoked, i);
659 (void)BIO_reset(mem);
660 i2a_ASN1_INTEGER(mem, X509_REVOKED_get0_serialNumber(r));
661 result &= (((n = BIO_get_mem_data(mem, &p)) > 0) &&
662 PL_unify_list(list, item, list) &&
663 (revocation_date = PL_new_term_ref()) &&
664 unify_asn1_time(revocation_date, X509_REVOKED_get0_revocationDate(r)) &&
665 PL_unify_term(item,
666 PL_FUNCTOR, FUNCTOR_revoked2,
667 PL_NCHARS, (size_t)n, p,
668 PL_TERM, revocation_date));
669 if (BIO_reset(mem) != 1)
670 {
671 BIO_free(mem);
672 // The only reason I can imagine this would fail is out of memory
673 return PL_resource_error("memory");
674 }
675 }
735 { X509_REVOKED *r = sk_X509_REVOKED_value(revoked, i);
736
737 (void)BIO_reset(mem);
738 i2a_ASN1_INTEGER(mem, X509_REVOKED_get0_serialNumber(r));
739 result &= (((n = BIO_get_mem_data(mem, &p)) > 0) &&
740 PL_unify_list(list, item, list) &&
741 (revocation_date = PL_new_term_ref()) &&
742 unify_asn1_time(revocation_date, X509_REVOKED_get0_revocationDate(r)) &&
743 PL_unify_term(item,
744 PL_FUNCTOR, FUNCTOR_revoked2,
745 PL_NCHARS, (size_t)n, p,
746 PL_TERM, revocation_date));
747 if ( BIO_reset(mem) != 1 )
748 { BIO_free(mem);
749 // The only reason I can imagine this would fail is out of memory
750 return PL_resource_error("memory");
751 }
752 }
753
676754 BIO_free(mem);
677755 return result && PL_unify_nil(list);
678756 }
715793 #ifndef OPENSSL_NO_EC
716794 static int
717795 unify_ec(term_t item, EC_KEY *key)
718 {
719 unsigned char *buf = NULL;
796 { unsigned char *buf = NULL;
720797 int rc, publen;
721798 term_t privkey, pubkey;
722799
12311308 { GET0SIG_CONST_T ASN1_BIT_STRING *psig;
12321309 GET0SIG_CONST_T X509_ALGOR *palg;
12331310 const char *salgorithm;
1234
1311
12351312 X509_get0_signature(&psig, &palg, cert);
12361313 if ((salgorithm = OBJ_nid2sn(OBJ_obj2nid(palg->algorithm))) != NULL)
12371314 { return PL_unify_chars(Field, PL_ATOM|REP_UTF8, strlen(salgorithm), salgorithm);
12431320 fetch_hash(term_t Field, X509* cert)
12441321 { GET0SIG_CONST_T ASN1_BIT_STRING *psig;
12451322 GET0SIG_CONST_T X509_ALGOR *palg;
1246
1323
12471324 X509_get0_signature(&psig, &palg, cert);
12481325 #ifdef HAVE_X509_DIGEST
12491326 return unify_hash(Field, palg->algorithm, hash_X509_digest_wrapper, cert);
12841361 {"signature", fetch_signature},
12851362 {"signature_algorithm", fetch_signature_algorithm},
12861363 {"hash", fetch_hash},
1287 #ifdef HAVE_I2D_RE_X509_TBS
1364 #ifdef HAVE_I2D_RE_X509_TBS
12881365 {"to_be_signed", fetch_to_be_signed},
12891366 #endif
12901367 {NULL, NULL}};
18851962 assert(config->magic == SSL_CONFIG_MAGIC);
18861963 config->magic = 0;
18871964 free(config->host);
1888 if (config->cacerts)
1889 sk_X509_pop_free(config->cacerts, X509_free);
1965 free_cacert_stack(config->cacerts);
18901966 free(config->certificate_file);
18911967 free(config->key_file);
18921968 free(config->cipher_list);
19522028 }
19532029
19542030 static int
1955 ssl_config_dup ( CRYPTO_EX_DATA * to
1956 ,
2031 ssl_config_dup(CRYPTO_EX_DATA *to,
19572032 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
1958 CRYPTO_EX_DATA * from
2033 CRYPTO_EX_DATA *from,
19592034 #else
1960 const CRYPTO_EX_DATA * from
1961 #endif
1962 , void * pl_ssl
1963 , int parent_ctx_idx
1964 , long argl
1965 , void *argp
1966 )
1967 {
1968 return 1;
2035 const CRYPTO_EX_DATA *from,
2036 #endif
2037 void *pl_ssl,
2038 int parent_ctx_idx,
2039 long argl,
2040 void *argp)
2041 { return 1;
19692042 }
19702043
19712044 static void
1972 ssl_config_free( void * ctx
1973 , void * pl_ssl
1974 , CRYPTO_EX_DATA * parent_ctx
1975 , int parent_ctx_idx
1976 , long argl
1977 , void *argp
1978 )
1979 {
1980 PL_SSL *config = NULL;
1981
1982 ssl_deb(1, "calling ssl_config_free()\n");
1983 if ((config = SSL_CTX_get_ex_data(ctx, ctx_idx)) != NULL) {
1984 assert(config->magic == SSL_CONFIG_MAGIC);
1985 ssl_free(config);
1986 }
1987 }
1988
1989
1990 static int
1991 ssl_cb_cert_verify(int preverify_ok, X509_STORE_CTX *ctx)
2045 ssl_config_free(void *ctx,
2046 void *pl_ssl,
2047 CRYPTO_EX_DATA *parent_ctx,
2048 int parent_ctx_idx,
2049 long argl,
2050 void *argp)
2051 { PL_SSL *config = NULL;
2052
2053 ssl_deb(1, "calling ssl_config_free()\n");
2054 if ( (config=SSL_CTX_get_ex_data(ctx, ctx_idx)))
2055 { assert(config->magic == SSL_CONFIG_MAGIC);
2056 ssl_free(config);
2057 }
2058 }
2059
2060
19922061 /*
19932062 * Function handling certificate verification
19942063 */
1995 {
1996 SSL * ssl = NULL;
1997 PL_SSL * config = NULL;
1998 /*
1999 * Get our config data
2000 */
2001 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2002 config = SSL_get_ex_data(ssl, ssl_idx);
2003
2004
2005
2006 ssl_deb(1, " ---- INIT Handling certificate verification\n");
2007 ssl_deb(1, " Certificate preverified %sok\n",
2008 preverify_ok ? "" : "NOT ");
2064
2065 static int
2066 ssl_cb_cert_verify(int preverify_ok, X509_STORE_CTX *ctx)
2067 { SSL *ssl = NULL;
2068 PL_SSL *config = NULL;
2069 /*
2070 * Get our config data
2071 */
2072 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2073 config = SSL_get_ex_data(ssl, ssl_idx);
2074
2075 ssl_deb(1, " ---- INIT Handling certificate verification\n");
2076 ssl_deb(1, " Certificate preverified %sok\n", preverify_ok ? "" : "NOT ");
20092077 #ifndef HAVE_X509_CHECK_HOST
20102078 /* If OpenSSL does not have X509_check_host() then the hostname has not yet been verified.
20112079 Note that we only want to check the hostname of the FIRST certificate. There appears to be no easy way of
22032271 return preverify_ok;
22042272 }
22052273
2206 static int
2207 ssl_cb_pem_passwd(char *buf, int size, int rwflag, void *userdata)
22082274 /*
22092275 * We're called since the OpenSSL library needs a password to access
22102276 * the private key. The method to require the password is defined in
22122278 * Fill the supplied buffer with the password and return its length
22132279 * or 0 on failure.
22142280 */
2215 {
2216 PL_SSL *config = (PL_SSL *) userdata;
2217 char *passwd = NULL;
2218 int len = 0;
2219
2220 if (config->cb_pem_passwd.goal) {
2221 /*
2222 * Callback installed
2223 */
2224 passwd = pl_pem_passwd_hook(config, buf, size);
2225 } else
2226 if (config->password) {
2227 /*
2228 * Password defined
2229 */
2230 passwd = config->password;
2231 }
2232
2233 if (passwd) {
2234 if ((len = (int)strlen(passwd)) < size) {
2235 strcpy(buf, passwd);
2236 } else {
2237 len = 0;
2238 }
2239 }
2240
2241 return len;
2281
2282 static int
2283 ssl_cb_pem_passwd(char *buf, int size, int rwflag, void *userdata)
2284 { PL_SSL *config = userdata;
2285 char *passwd = NULL;
2286 int len = 0;
2287
2288 if ( config->cb_pem_passwd.goal )
2289 { passwd = pl_pem_passwd_hook(config, buf, size);
2290 } else if (config->password)
2291 { passwd = config->password;
2292 }
2293
2294 if ( passwd )
2295 { if ( (len = (int)strlen(passwd)) < size )
2296 strcpy(buf, passwd);
2297 else
2298 len = 0;
2299 }
2300
2301 return len;
22422302 }
22432303
22442304
22452305 #ifndef OPENSSL_NO_TLSEXT
22462306 static int
22472307 ssl_cb_sni(SSL *s, int *ad, void *arg)
2248 {
2249 PL_SSL *config = (PL_SSL *) arg,
2250 *new_config = NULL;
2308 { PL_SSL *config = arg;
2309 PL_SSL *new_config = NULL;
22512310 const char *servername;
22522311
2253 if ( (servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name)) != NULL )
2312 if ( (servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name)) )
22542313 new_config = pl_sni_hook(config, servername);
22552314
22562315 if ( new_config == NULL &&
23332392 { char errmsg[1024];
23342393
23352394 ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
2336
23372395 Sdprintf("%s\n", errmsg);
23382396 }
23392397
23402398
2341 static PL_SSL *
2342 ssl_init(PL_SSL_ROLE role, const SSL_METHOD *ssl_method)
23432399 /*
23442400 * Allocate the holder for our parameters which will specify the
23452401 * configuration parameters and any other statefull parameter.
23472403 * Define method for SSL layer depending on whether we're server or client.
23482404 * Create SSL context.
23492405 */
2350 {
2351 PL_SSL * config = NULL;
2352 SSL_CTX *ssl_ctx = NULL;
2353
2354 ssl_ctx = SSL_CTX_new(ssl_method);
2355 if (!ssl_ctx) {
2356 ERR_print_errors_pl();
2357 } else {
2358 long ctx_mode = 0L;
2359
2360 if ((config = SSL_CTX_get_ex_data(ssl_ctx, ctx_idx)) == NULL) {
2361 ssl_err("Cannot read back application data\n");
2362 SSL_CTX_free(ssl_ctx);
2363 return NULL;
2364 }
2365 assert(config->magic == SSL_CONFIG_MAGIC);
2366 config->ctx = ssl_ctx;
2367 config->role = role;
2368 config->peer_cert_required = (role != PL_SSL_SERVER);
2369
2370 /*
2371 * Set SSL_{read,write} behaviour when a renegotiation takes place
2372 * in a blocking transport layer.
2373 */
2374 ctx_mode = SSL_CTX_get_mode(ssl_ctx);
2375 ctx_mode |= SSL_MODE_AUTO_RETRY;
2376 ctx_mode = SSL_CTX_set_mode(ssl_ctx, ctx_mode);
2406
2407 static PL_SSL *
2408 ssl_init(PL_SSL_ROLE role, const SSL_METHOD *ssl_method)
2409 { PL_SSL *config = NULL;
2410 SSL_CTX *ssl_ctx = NULL;
2411
2412 ssl_ctx = SSL_CTX_new(ssl_method);
2413 if ( !ssl_ctx )
2414 { ERR_print_errors_pl();
2415 } else
2416 { long ctx_mode = 0L;
2417
2418 if ( !(config=SSL_CTX_get_ex_data(ssl_ctx, ctx_idx)) )
2419 { ssl_err("Cannot read back application data\n");
2420 SSL_CTX_free(ssl_ctx);
2421 return NULL;
23772422 }
23782423
2379 ssl_deb(1, "Initialized\n");
2380
2381 return config;
2424 assert(config->magic == SSL_CONFIG_MAGIC);
2425 config->ctx = ssl_ctx;
2426 config->role = role;
2427 config->peer_cert_required = (role != PL_SSL_SERVER);
2428
2429 /*
2430 * Set SSL_{read,write} behaviour when a renegotiation takes place
2431 * in a blocking transport layer.
2432 */
2433 ctx_mode = SSL_CTX_get_mode(ssl_ctx);
2434 ctx_mode |= SSL_MODE_AUTO_RETRY;
2435 ctx_mode = SSL_CTX_set_mode(ssl_ctx, ctx_mode);
2436 }
2437
2438 ssl_deb(1, "Initialized\n");
2439
2440 return config;
23822441 }
23832442
23842443
24842543 const unsigned char *der;
24852544 unsigned long cert_data_length;
24862545 X509 *x509 = NULL;
2487
2546
24882547 cert_data = SecCertificateCopyData((SecCertificateRef)cert);
24892548 der = CFDataGetBytePtr(cert_data);
24902549 cert_data_length = CFDataGetLength(cert_data);
25512610 ssl_init_verify_locations(PL_SSL *config)
25522611 { if ( config->cacerts )
25532612 { X509_STORE *store = X509_STORE_new();
2613
25542614 if ( store )
25552615 { int index = 0;
2556 while (index < sk_X509_num(config->cacerts))
2557 { X509_STORE_add_cert(store, sk_X509_value(config->cacerts, index++));
2616 STACK_OF(X509) *cacerts = config->cacerts->cacerts;
2617
2618 while( index < sk_X509_num(cacerts) )
2619 { X509_STORE_add_cert(store, sk_X509_value(cacerts, index++));
25582620 }
25592621 SSL_CTX_set_cert_store(config->ctx, store);
25602622 }
2561 ssl_deb(1, "certificate authority(s) installed from individual certificates\n");
2562 }
2623 ssl_deb(1, "certificate authority(s) installed from certificates\n");
2624 }
2625
25632626 if ( config->crl_list )
25642627 { X509_STORE *store = SSL_CTX_get_cert_store(config->ctx);
25652628 int i = 0;
2629
25662630 while (i < sk_X509_CRL_num(config->crl_list))
25672631 { X509_STORE_add_crl(store, sk_X509_CRL_value(config->crl_list, i));
2568 /*
2569 Sdprintf("Added a CRL...\n");
2570 BIO * bio = BIO_new_fp(stdout, BIO_NOCLOSE);
2571 X509_CRL_print(bio, sk_X509_CRL_value(config->crl_list, i));
2572 BIO_free(bio);
2573 */
25742632 i++;
25752633 }
25762634 }
2577
25782635 }
25792636
25802637 /* The following keys were generated with:
32273284 { atom_t name;
32283285 size_t arity;
32293286
3230 if ( !PL_get_name_arity(head, &name, &arity) )
3287 if ( !(PL_get_name_arity(head, &name, &arity) && arity == 1) )
32313288 return PL_type_error("ssl_option", head);
32323289
3233 if ( name == ATOM_cipher_list && arity == 1 )
3290 if ( name == ATOM_cipher_list )
32343291 { char *s;
32353292
32363293 if ( !get_char_arg(1, head, &s) )
32373294 return FALSE;
32383295
3239 if (conf->cipher_list) free(conf->cipher_list);
3240 conf->cipher_list = ssl_strdup(s);
3241 } else if ( name == ATOM_ecdh_curve && arity == 1 )
3296 set_string(conf, cipher_list, s);
3297 } else if ( name == ATOM_ecdh_curve )
32423298 { char *s;
32433299
32443300 if ( !get_char_arg(1, head, &s) )
32453301 return FALSE;
32463302
3247 if (conf->ecdh_curve) free(conf->ecdh_curve);
3248 conf->ecdh_curve = ssl_strdup(s);
3249 } else if ( name == ATOM_host && arity == 1 )
3303 set_string(conf, ecdh_curve, s);
3304 } else if ( name == ATOM_host )
32503305 { char *s;
32513306
32523307 if ( !get_char_arg(1, head, &s) )
32533308 return FALSE;
32543309
3255 if (conf->host) free(conf->host);
3256 conf->host = ssl_strdup(s);
3257 } else if ( name == ATOM_peer_cert && arity == 1 )
3310 set_string(conf, host, s);
3311 } else if ( name == ATOM_peer_cert )
32583312 { int val;
32593313
32603314 if ( !get_bool_arg(1, head, &val) )
32613315 return FALSE;
32623316
32633317 conf->peer_cert_required = val;
3264 } else if ( name == ATOM_cert_verify_hook && arity == 1 )
3318 } else if ( name == ATOM_cert_verify_hook )
32653319 { term_t cb = PL_new_term_ref();
32663320 _PL_get_arg(1, head, cb);
32673321
32703324
32713325 conf->cb_cert_verify.goal = PL_record(cb);
32723326 conf->cb_cert_verify.module = module;
3273 } else if ( name == ATOM_close_parent && arity == 1 )
3327 } else if ( name == ATOM_close_parent )
32743328 { int val;
32753329
32763330 if ( !get_bool_arg(1, head, &val) )
32773331 return FALSE;
32783332
32793333 conf->close_parent = val;
3280 } else if ( name == ATOM_disable_ssl_methods && arity == 1 )
3334 } else if ( name == ATOM_disable_ssl_methods )
32813335 { term_t opt_head = PL_new_term_ref();
32823336 term_t opt_tail = PL_new_term_ref();
32833337 long options = 0;
33123366
33133367 if ( (isset=(SSL_CTX_set_options(conf->ctx, options)&options)) != options )
33143368 ssl_deb(1, "SSL_CTX_set_options 0x%lx only set 0x%lx\n", options, isset);
3315 } else if ( name == ATOM_min_protocol_version && arity == 1 )
3369 } else if ( name == ATOM_min_protocol_version )
33163370 { term_t val = PL_new_term_ref();
33173371 int version;
33183372
33223376 return FALSE;
33233377 conf->min_protocol.is_set = TRUE;
33243378 conf->min_protocol.version = version;
3325 } else if ( name == ATOM_max_protocol_version && arity == 1 )
3379 } else if ( name == ATOM_max_protocol_version )
33263380 { term_t val = PL_new_term_ref();
33273381 int version;
33283382
33423396
33433397 conf->cb_sni.goal = PL_record(cb);
33443398 conf->cb_sni.module = module;
3345 } else if ( name == ATOM_close_notify && arity == 1 )
3399 } else if ( name == ATOM_close_notify )
33463400 { int val;
33473401
33483402 if ( !get_bool_arg(1, head, &val) )
33493403 return FALSE;
33503404
33513405 conf->close_notify = val;
3352 } else if ( name == ATOM_alpn_protocols && arity == 1 )
3406 } else if ( name == ATOM_alpn_protocols )
33533407 { term_t protos_tail = PL_new_term_ref();
33543408 term_t protos_head = PL_new_term_ref();
33553409 _PL_get_arg(1, head, protos_tail);
33803434 }
33813435 conf->alpn_protos = protos_vec;
33823436 conf->alpn_protos_len = current_size;
3383 } else if ( name == ATOM_alpn_protocol_hook && arity == 1 &&
3437 } else if ( name == ATOM_alpn_protocol_hook &&
33843438 conf->role == PL_SSL_SERVER )
33853439 { term_t cb = PL_new_term_ref();
33863440 _PL_get_arg(1, head, cb);
34113465 set_malleable_options(conf);
34123466 }
34133467
3468
3469 static foreign_t
3470 pl_ssl_property(term_t config, term_t prop)
3471 { PL_SSL *conf;
3472 atom_t name;
3473 size_t arity;
3474
3475 if ( !get_conf(config, &conf) )
3476 return FALSE;
3477
3478 if ( PL_get_name_arity(prop, &name, &arity) && arity == 1 )
3479 { term_t arg = PL_new_term_ref();
3480
3481 _PL_get_arg(1, prop, arg);
3482 if ( name == ATOM_close_parent )
3483 return PL_unify_bool(arg, conf->close_parent);
3484
3485 return FALSE;
3486 }
3487
3488 return PL_type_error("ssl_property", prop);
3489 }
3490
3491
3492 static const SSL_METHOD *
3493 get_ssl_method(term_t method)
3494 { const SSL_METHOD *ssl_method = NULL;
3495 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3496 atom_t method_name;
3497 #endif
3498
3499 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3500 if ( !method )
3501 method_name = ATOM_sslv23;
3502 else if ( !PL_get_atom(method, &method_name) )
3503 return PL_domain_error("ssl_method", method);
3504
3505 if ( method_name == ATOM_sslv23 )
3506 ssl_method = SSLv23_method();
3507 #ifndef OPENSSL_NO_SSL2
3508 else if ( method_name == ATOM_sslv2 )
3509 ssl_method = SSLv2_method();
3510 #endif
3511 #ifndef OPENSSL_NO_SSL3_METHOD
3512 else if ( method_name == ATOM_sslv3 )
3513 ssl_method = SSLv3_method();
3514 #endif
3515 #ifdef SSL_OP_NO_TLSv1
3516 else if ( method_name == ATOM_tlsv1 )
3517 ssl_method = TLSv1_method();
3518 #endif
3519 #ifdef SSL_OP_NO_TLSv1_1
3520 else if ( method_name == ATOM_tlsv1_1 )
3521 ssl_method = TLSv1_1_method();
3522 #endif
3523 #ifdef SSL_OP_NO_TLSv1_2
3524 else if ( method_name == ATOM_tlsv1_2 )
3525 ssl_method = TLSv1_2_method();
3526 #endif
3527 else
3528 return PL_domain_error("ssl_method", method);
3529 #else
3530 ssl_method = TLS_method(); /* In OpenSSL >= 1.1.0, always use TLS_method() */
3531 #endif
3532
3533 return ssl_method;
3534 }
3535
3536
3537 static cacert_stack *root_cacert_stack = NULL;
3538
3539 static int
3540 add_system_root_certificates(cacert_stack *stack)
3541 { STACK_OF(X509) *system_certs = system_root_certificates();
3542
3543 if ( system_certs )
3544 { int index = 0;
3545
3546 while( index < sk_X509_num(system_certs) )
3547 { sk_X509_push(stack->cacerts,
3548 X509_dup(sk_X509_value(system_certs, index++)));
3549 }
3550 }
3551
3552 return TRUE;
3553 }
3554
3555
3556 static int
3557 get_cacerts_roots_only(term_t term, cacert_stack **stackp)
3558 { term_t tail = PL_copy_term_ref(term);
3559 term_t head = PL_new_term_ref();
3560
3561 if ( PL_get_list(tail, head, tail) && PL_get_nil(tail) &&
3562 PL_is_functor(head, FUNCTOR_system1) )
3563 { atom_t a;
3564
3565 _PL_get_arg(1, head, head);
3566 if ( PL_get_atom(head, &a) && a == ATOM_root_certificates )
3567 { if ( root_cacert_stack )
3568 { *stackp = dup_cacert_stack(root_cacert_stack);
3569 return TRUE;
3570 } else
3571 { cacert_stack *stack;
3572
3573 if ( !(stack=new_cacert_stack()) ||
3574 !add_system_root_certificates(stack) )
3575 return FALSE;
3576 if ( COMPARE_AND_SWAP_PTR(&root_cacert_stack, NULL, stack) )
3577 { (void)dup_cacert_stack(root_cacert_stack);
3578 } else
3579 { free_cacert_stack(stack);
3580 }
3581
3582 *stackp = dup_cacert_stack(root_cacert_stack);
3583 return TRUE;
3584 }
3585 }
3586 }
3587
3588 return FALSE;
3589 }
3590
3591
3592 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3593 Create a cacert_stack from a Prolog list of certificate sources. The
3594 certificates are all duplicated using X509_dup() such that they can be
3595 freed uniformely when the stack is freed.
3596 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3597
3598 static int
3599 get_cacerts(term_t CATail, cacert_stack **stackp)
3600 { term_t CAHead;
3601 cacert_stack *stack;
3602
3603 if ( get_cacerts_roots_only(CATail, stackp) )
3604 return TRUE;
3605
3606 if ( !(CAHead = PL_new_term_ref()) )
3607 return FALSE;
3608
3609 if ( !(stack=new_cacert_stack()) )
3610 { PL_resource_error("memory");
3611 return FALSE;
3612 }
3613
3614 while( PL_get_list_ex(CATail, CAHead, CATail) )
3615 { X509* cert = NULL;
3616
3617 if ( PL_is_functor(CAHead, FUNCTOR_certificate1) )
3618 { _PL_get_arg(1, CAHead, CAHead);
3619
3620 if ( !get_certificate_blob(CAHead, &cert) )
3621 { error:
3622 free_cacert_stack(stack);
3623 return FALSE;
3624 }
3625 sk_X509_push(stack->cacerts, X509_dup(cert));
3626 } else if ( PL_is_functor(CAHead, FUNCTOR_file1) )
3627 { char *file;
3628
3629 _PL_get_arg(1, CAHead, CAHead);
3630
3631 if ( !PL_get_file_name(CAHead, &file, PL_FILE_EXIST) ||
3632 !load_certificates_from_file(file, stack->cacerts))
3633 goto error;
3634 } else if ( PL_is_functor(CAHead, FUNCTOR_system1) )
3635 { atom_t a;
3636
3637 _PL_get_arg(1, CAHead, CAHead);
3638
3639 if ( !PL_get_atom_ex(CAHead, &a) )
3640 goto error;
3641
3642 if ( a == ATOM_root_certificates )
3643 { if ( !add_system_root_certificates(stack) )
3644 goto error;
3645 }
3646 }
3647 }
3648
3649 if ( !PL_get_nil_ex(CATail) )
3650 goto error;
3651
3652 *stackp = stack;
3653 return TRUE;
3654 }
3655
3656
3657
34143658 static foreign_t
34153659 pl_ssl_context(term_t role, term_t config, term_t options, term_t method)
34163660 { atom_t a;
34193663 term_t tail;
34203664 term_t head = PL_new_term_ref();
34213665 module_t module = NULL;
3422 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3423 atom_t method_name;
3424 #endif
3425 const SSL_METHOD *ssl_method = NULL;
3666 const SSL_METHOD *ssl_method;
34263667
34273668 if ( !PL_strip_module(options, &module, options) )
34283669 return FALSE;
34373678 else
34383679 return PL_domain_error("ssl_role", role);
34393680
3440 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3441 if (!PL_get_atom(method, &method_name))
3442 return PL_domain_error("ssl_method", method);
3443 if (method_name == ATOM_sslv23)
3444 ssl_method = SSLv23_method();
3445 #ifndef OPENSSL_NO_SSL2
3446 else if (method_name == ATOM_sslv2)
3447 ssl_method = SSLv2_method();
3448 #endif
3449 #ifndef OPENSSL_NO_SSL3_METHOD
3450 else if (method_name == ATOM_sslv3)
3451 ssl_method = SSLv3_method();
3452 #endif
3453 #ifdef SSL_OP_NO_TLSv1
3454 else if (method_name == ATOM_tlsv1)
3455 ssl_method = TLSv1_method();
3456 #endif
3457 #ifdef SSL_OP_NO_TLSv1_1
3458 else if (method_name == ATOM_tlsv1_1)
3459 ssl_method = TLSv1_1_method();
3460 #endif
3461 #ifdef SSL_OP_NO_TLSv1_2
3462 else if (method_name == ATOM_tlsv1_2)
3463 ssl_method = TLSv1_2_method();
3464 #endif
3465 else
3466 return PL_domain_error("ssl_method", method);
3467 #else
3468 ssl_method = TLS_method(); /* In OpenSSL >= 1.1.0, always use TLS_method() */
3469 #endif
3681 if ( !(ssl_method = get_ssl_method(method)) )
3682 return FALSE;
34703683
34713684 if ( !(conf = ssl_init(r, ssl_method)) )
34723685 return PL_resource_error("memory");
3686
34733687 while( PL_get_list(tail, head, tail) )
34743688 { atom_t name;
34753689 size_t arity;
34763690
3477 if ( !PL_get_name_arity(head, &name, &arity) )
3691 if ( !(PL_get_name_arity(head, &name, &arity) && arity == 1) )
34783692 return PL_type_error("ssl_option", head);
34793693
3480 if ( name == ATOM_password && arity == 1 )
3694 if ( name == ATOM_password )
34813695 { char *s;
34823696
34833697 if ( !get_char_arg(1, head, &s) )
34843698 return FALSE;
34853699
3486 if (conf->password) free(conf->password);
3487 conf->password = ssl_strdup(s);
3488 } else if ( name == ATOM_require_crl && arity == 1 )
3700 set_string(conf, password, s);
3701 } else if ( name == ATOM_require_crl )
34893702 { int val;
34903703
34913704 if ( !get_bool_arg(1, head, &val) )
34923705 return FALSE;
34933706
34943707 conf->crl_required = val;
3495 } else if ( name == ATOM_crl && arity == 1 )
3708 } else if ( name == ATOM_crl )
34963709 { STACK_OF(X509_CRL) *crls = sk_X509_CRL_new_null();
34973710 term_t list_head = PL_new_term_ref();
34983711 term_t list_tail = PL_new_term_ref();
3712
34993713 _PL_get_arg(1, head, list_tail);
35003714 while( PL_get_list(list_tail, list_head, list_tail) )
35013715 { atom_t crl_name;
35123726 if (conf->crl_list)
35133727 sk_X509_CRL_pop_free(conf->crl_list, X509_CRL_free);
35143728 conf->crl_list = crls;
3515 } else if ( name == ATOM_certificate_file && arity == 1 )
3729 } else if ( name == ATOM_certificate_file )
35163730 { char *file;
35173731
35183732 if ( !get_file_arg(1, head, &file) )
35193733 return FALSE;
35203734
3521 if (conf->certificate_file) free(conf->certificate_file);
3522 conf->certificate_file = ssl_strdup(file);
3523 } else if ( name == ATOM_cacerts && arity == 1 )
3524 { term_t CATail = PL_new_term_ref();
3525 term_t CAHead = PL_new_term_ref();
3526 _PL_get_arg(1, head, CATail);
3527 if (conf->cacerts)
3528 sk_X509_pop_free(conf->cacerts, X509_free);
3529 conf->cacerts = sk_X509_new_null();
3530 while (PL_get_list_ex(CATail, CAHead, CATail))
3531 { X509* cert = NULL;
3532 if (PL_is_functor(CAHead, FUNCTOR_certificate1))
3533 { _PL_get_arg(1, CAHead, CAHead);
3534 if (!get_certificate_blob(CAHead, &cert))
3535 { sk_X509_pop_free(conf->cacerts, X509_free);
3536 conf->cacerts = NULL;
3537 return FALSE;
3538 }
3539 /* Duplicate the certificate here so that if it is freed by AGC the
3540 certificate is still valid in conf->cacerts.
3541 The duplicates will be cleaned up when the conf is freed
3542 */
3543 sk_X509_push(conf->cacerts, X509_dup(cert));
3544 }
3545 else if (PL_is_functor(CAHead, FUNCTOR_file1))
3546 { char *file;
3547 _PL_get_arg(1, CAHead, CAHead);
3548 /* These certificate(s) will be cleaned up when the conf is freed */
3549 if ( !PL_get_file_name(CAHead, &file, PL_FILE_EXIST) || !load_certificates_from_file(file, conf->cacerts))
3550 { sk_X509_pop_free(conf->cacerts, X509_free);
3551 conf->cacerts = NULL;
3552 return FALSE;
3553 }
3554 }
3555 else if (PL_is_functor(CAHead, FUNCTOR_system1))
3556 { _PL_get_arg(1, CAHead, CAHead);
3557 atom_t a;
3558 if ( !PL_get_atom_ex(CAHead, &a) )
3559 return FALSE;
3560 if ( a == ATOM_root_certificates )
3561 { STACK_OF(X509) *system_certs = system_root_certificates();
3562 if ( system_certs )
3563 { int index = 0;
3564 /* We make a copy of all the system certs here since we later free all the
3565 certificates and do not want to free the ones in the system_root_certificates
3566 stack. The duplicates will be cleaned up when the conf is freed
3567 */
3568 while (index < sk_X509_num(system_certs))
3569 { sk_X509_push(conf->cacerts, X509_dup(sk_X509_value(system_certs, index++)));
3570 }
3571 }
3572 }
3573 }
3735 set_string(conf, certificate_file, file);
3736 } else if ( name == ATOM_cacerts )
3737 { term_t arg = PL_new_term_ref();
3738 cacert_stack *stack;
3739
3740 _PL_get_arg(1, head, arg);
3741 if ( get_cacerts(arg, &stack) )
3742 { free_cacert_stack(conf->cacerts);
3743 conf->cacerts = stack;
35743744 }
3575 if (!PL_get_nil_ex(CATail))
3576 { sk_X509_pop_free(conf->cacerts, X509_free);
3577 conf->cacerts = NULL;
3578 return FALSE;
3579 }
3580 } else if ( name == ATOM_certificate_file && arity == 1 )
3745 } else if ( name == ATOM_certificate_file )
35813746 { char *file;
35823747
35833748 if ( !get_file_arg(1, head, &file) )
35843749 return FALSE;
35853750
3586 if (conf->certificate_file) free(conf->certificate_file);
3587 conf->certificate_file = ssl_strdup(file);
3588 } else if ( name == ATOM_certificate_key_pairs && arity == 1 )
3751 set_string(conf, certificate_file, file);
3752 } else if ( name == ATOM_certificate_key_pairs )
35893753 { term_t cert_head = PL_new_term_ref();
35903754 term_t cert_tail = PL_new_term_ref();
35913755 _PL_get_arg(1, head, cert_tail);
36153779 }
36163780 if ( !PL_get_nil_ex(cert_tail) )
36173781 return FALSE;
3618 } else if ( name == ATOM_key_file && arity == 1 )
3782 } else if ( name == ATOM_key_file )
36193783 { char *file;
36203784
36213785 if ( !get_file_arg(1, head, &file) )
36223786 return FALSE;
36233787
3624 if (conf->key_file) free(conf->key_file);
3625 conf->key_file = ssl_strdup(file);
3626 } else if ( name == ATOM_pem_password_hook && arity == 1 )
3788 set_string(conf, key_file, file);
3789 } else if ( name == ATOM_pem_password_hook )
36273790 { term_t cb = PL_new_term_ref();
36283791 _PL_get_arg(1, head, cb);
36293792 conf->cb_pem_passwd.goal = PL_record(cb);
37883951 }
37893952 }
37903953
3791 /* This is used to avoid casting a function pointer. The second argument of sk_X509_deep_copy
3792 expects a function with a const argument
3793 */
3794 static X509 *x509dup(const X509 *cx)
3795 { X509 *x = (X509 *)cx;
3796 return X509_dup(x);
3797 }
3798
37993954 static foreign_t
3800 pl_ssl_init_from_context(term_t term_old, term_t term_new)
3801 {
3802 PL_SSL *old, *new;
3955 pl_ssl_copy_context(term_t term_old, term_t term_new)
3956 { PL_SSL *old, *new;
38033957 int idx;
3804
3805 if ( !get_conf(term_old, &old) ||
3806 !get_conf(term_new, &new) )
3958 const SSL_METHOD *ssl_method;
3959
3960 if ( !PL_is_variable(term_new) )
3961 return PL_uninstantiation_error(term_new);
3962
3963 if ( !get_conf(term_old, &old) )
38073964 return FALSE;
38083965
3966 if ( !(ssl_method = get_ssl_method(0)) )
3967 return FALSE;
3968 if ( !(new = ssl_init(old->role, ssl_method)) )
3969 return PL_resource_error("memory");
3970 if ( !unify_conf(term_new, new) )
3971 return FALSE; /* TBD: cleanup */
3972
38093973 new->role = old->role;
3810
3811 new->password = ssl_strdup(old->password);
3812
38133974 new->close_parent = old->close_parent;
38143975 new->close_notify = old->close_notify;
3815 new->host = ssl_strdup(old->host);
3816 new->cacerts = old->cacerts?sk_X509_deep_copy(old->cacerts, x509dup, X509_free):NULL;
3817 new->certificate_file = ssl_strdup(old->certificate_file);
3818 new->key_file = ssl_strdup(old->key_file);
38193976 new->min_protocol = old->min_protocol;
38203977 new->max_protocol = old->max_protocol;
38213978 new->peer_cert_required = old->peer_cert_required;
3822 new->cipher_list = ssl_strdup(old->cipher_list);
3823 new->ecdh_curve = ssl_strdup(old->ecdh_curve);
3979
3980 set_string(new, password, old->password);
3981 set_string(new, host, old->host);
3982 set_string(new, certificate_file, old->certificate_file);
3983 set_string(new, key_file, old->key_file);
3984 set_string(new, cipher_list, old->cipher_list);
3985 set_string(new, ecdh_curve, old->ecdh_curve);
3986
3987 new->cacerts = dup_cacert_stack(old->cacerts);
38243988
38253989 #ifndef HAVE_X509_CHECK_HOST
38263990 new->hostname_check_status = old->hostname_check_status;
38273991 #endif
38283992
3829 if (old->crl_list)
3993 if ( old->crl_list )
38303994 new->crl_list = sk_X509_CRL_dup(old->crl_list);
38313995 new->crl_required = old->crl_required;
38323996
38333997 ssl_copy_callback(old->cb_cert_verify, &new->cb_cert_verify);
3834 ssl_copy_callback(old->cb_pem_passwd, &new->cb_pem_passwd);
3835 ssl_copy_callback(old->cb_sni, &new->cb_sni);
3836 ssl_copy_callback(old->cb_alpn_proto, &new->cb_alpn_proto);
3837
3838 for (idx = 0; idx < old->num_cert_key_pairs; idx++)
3998 ssl_copy_callback(old->cb_pem_passwd, &new->cb_pem_passwd);
3999 ssl_copy_callback(old->cb_sni, &new->cb_sni);
4000 ssl_copy_callback(old->cb_alpn_proto, &new->cb_alpn_proto);
4001
4002 for(idx = 0; idx < old->num_cert_key_pairs; idx++)
38394003 { new->cert_key_pairs[idx].certificate = ssl_strdup(old->cert_key_pairs[idx].certificate);
38404004 new->cert_key_pairs[idx].key = ssl_strdup(old->cert_key_pairs[idx].key);
38414005 new->num_cert_key_pairs++;
38424006 }
38434007
3844 if ( old->alpn_protos ) {
3845 unsigned char *protos_copy = malloc(old->alpn_protos_len * sizeof(unsigned char));
4008 if ( old->alpn_protos )
4009 { unsigned char *protos_copy = malloc(old->alpn_protos_len *
4010 sizeof(unsigned char));
38464011 if ( protos_copy == NULL )
38474012 return PL_resource_error("memory");
38484013 memcpy(old->alpn_protos, protos_copy, old->alpn_protos_len);
42434408 FUNCTOR_certificate1 = PL_new_functor(PL_new_atom("certificate"), 1);
42444409 FUNCTOR_file1 = PL_new_functor(PL_new_atom("file"), 1);
42454410 PL_register_foreign("_ssl_context", 4, pl_ssl_context, 0);
4246 PL_register_foreign("_ssl_init_from_context",
4247 2, pl_ssl_init_from_context, 0);
4411 PL_register_foreign("ssl_copy_context", 2, pl_ssl_copy_context, 0);
42484412 PL_register_foreign("ssl_negotiate", 5, pl_ssl_negotiate, 0);
42494413 PL_register_foreign("_ssl_add_certificate_key",
42504414 3, pl_ssl_add_certificate_key, 0);
42514415 PL_register_foreign("_ssl_set_options", 2, pl_ssl_set_options, 0);
4416 PL_register_foreign("ssl_property", 2, pl_ssl_property, 0);
42524417 PL_register_foreign("ssl_debug", 1, pl_ssl_debug, 0);
42534418 PL_register_foreign("ssl_session", 2, pl_ssl_session, 0);
42544419 PL_register_foreign("ssl_peer_certificate",
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2013-2018, University of Amsterdam
5 Copyright (c) 2013-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
3737 [ test_ssl/0
3838 ]).
3939
40 :- asserta(user:file_search_path(library, '.')).
41 :- asserta(user:file_search_path(library, '../clib')).
42 :- asserta(user:file_search_path(library, '..')).
43 :- asserta(user:file_search_path(library, '../plunit')).
44 :- asserta(user:file_search_path(library, '../sgml')).
45 :- asserta(user:file_search_path(foreign, '../clib')).
46 :- asserta(user:file_search_path(foreign, '.')).
47 :- asserta(user:file_search_path(foreign, '../http')).
48 :- asserta(user:file_search_path(foreign, '../sgml')).
49 :- prolog_load_context(directory, D),
50 asserta(user:file_search_path(library, D)).
51
5240 :- use_module(library(plunit)).
5341 :- use_module(library(ssl)).
5442 :- use_module(library(crypto)).
5644 :- use_module(library(error)).
5745 :- use_module(library(readutil)).
5846 :- use_module(library(socket)).
59 :- use_module(library(https)).
47 :- use_module(https).
6048
6149 %:- debug(connection).
6250 %:- debug(certificate).
237225
238226 :- begin_tests(ssl_server).
239227
228 % This test creates a server and client and tests the following
229 % sequence:
230 %
231 % - Client sends "Hello world" and reads the reply with a 1 sec
232 % timeout.
233 % - Server reads "Hello world", _waits_ 1.5 sec before echoing it.
234 % - Client gets a timeout and retries the read. Second try should
235 % read "Hello world"
236 % - Client sends "bye", going through the same cycle as above.
237 % (JW: Why a second time?)
238 % - Client closes connection.
239 % - Server reads 'end_of_file' and closes the connection.
240
240241 test(server) :-
241242 make_server(SSL, Socket),
242243 thread_create(server_loop(SSL, Socket), Id, []),
246247 report_join_status(Status)
247248 ; format(user_error, 'Client error:~n', []),
248249 print_message(error, E),
250 thread_signal(Id, abort),
249251 thread_join(Id, Status),
250252 report_join_status(Status),
251253 fail
253255 ).
254256
255257 report_join_status(true).
258 report_join_status('$aborted'). % we killed the server.
256259 report_join_status(false) :-
257260 print_message(error, goal_failed(server_loop(_))).
258261 report_join_status(exception(Term)) :-
285288 certificate_file('tests/test_certs/server-cert.pem'),
286289 key_file('tests/test_certs/server-key.pem'),
287290 cert_verify_hook(get_cert_verify),
288 % password('apenoot1'),
289291 pem_password_hook(get_server_pwd)
290292 ]),
291 % Port = 1111,
292293 tcp_socket(Socket),
293294 tcp_setopt(Socket, reuseaddr),
294295 tcp_bind(Socket, localhost:Port),
317318 read_line_to_codes(In, Line),
318319 ( Line == end_of_file
319320 -> true
320 ; debug(data, 'SERVER: Got ~s~n', [Line]),
321 ; debug(data, 'SERVER: Got ~s (sleeping 1.5 sec)', [Line]),
321322 sleep(1.5),
322 debug(data, 'SERVER: writing ~s~n', [Line]),
323 debug(data, 'SERVER: writing ~s', [Line]),
323324 format(Out, '~s~n', [Line]),
324325 flush_output(Out),
325326 ( atom_codes(bye, Line)
360361 certificate_file('tests/test_certs/client-cert.pem'),
361362 key_file('tests/test_certs/client-key.pem'),
362363 close_parent(true),
363 % password('apenoot2'),
364364 pem_password_hook(get_client_pwd)
365365 ]),
366366 client_loop(SSL).
382382 call_cleanup(close(In), close(Out)).
383383
384384 write_server(Message, In, Out) :-
385 debug(data, 'CLIENT: writing: ~q~n', [Message]),
385 debug(data, 'CLIENT: writing: ~q', [Message]),
386386 write(Out, Message), nl(Out),
387387 flush_output(Out),
388388 sleep(0.1),
389 debug(data, 'CLIENT: attempting to read reply (timeout 1 sec)', []),
389390 catch(read_from_server(In, Message),
390391 E,
391 debug(data, 'CLIENT: exception: ~q~n', [E])),
392 debug(data, 'CLIENT: exception: ~q', [E])),
392393 ( var(E)
393394 -> true
394 ; read_from_server(In, Message)
395 ; debug(data, 'CLIENT: retrying read reply (timeout 1 sec)', []),
396 read_from_server(In, Message)
395397 ).
396398
397399 read_from_server(In, Message) :-
398 debug(data, 'CLIENT: attempting to read reply from stream~n', []),
399400 read_line_to_codes(In, Line),
400401 ( Line == end_of_file
401402 -> true
402403 ; atom_codes(Reply, Line),
403 debug(data, 'CLIENT: Got ~q~n', [Reply]),
404 debug(data, 'CLIENT: Got ~q', [Reply]),
404405 ( Reply == Message
405406 -> true
406407 ; format(user_error, 'CLIENT: ERROR: Sent ~q, Got ~q~n',
305305 atom_codes(RawSignatureValue, RawSignatureCodes),
306306 delete_newlines(RawSignatureCodes, SignatureCodes),
307307 string_codes(SignatureValue, SignatureCodes),
308 memberchk(element(ns(_, NSRef):'SignedInfo', SignedInfoAttributes, SignedInfo), Signature),
309 SignedData = element(ns(_, NSRef):'SignedInfo', SignedInfoAttributes, SignedInfo),
308 memberchk(element(ns(Prefix, NSRef):'SignedInfo', SignedInfoAttributes, SignedInfo), Signature),
309 SignedData = element(ns(Prefix, NSRef):'SignedInfo', SignedInfoAttributes, SignedInfo),
310310 memberchk(element(ns(_, NSRef):'CanonicalizationMethod', CanonicalizationMethodAttributes, _), SignedInfo),
311311 memberchk('Algorithm'=CanonicalizationMethod, CanonicalizationMethodAttributes),
312312 forall(memberchk(element(ns(_, NSRef):'Reference', ReferenceAttributes, Reference), SignedInfo),
+0
-18
packages/tipc/README less more
0 # Transparent Inter-Process Communications (TIPC) Sockets.
1
2 TIPC provides a framework for inter-process communication between
3 federations of trusted peers that are cooperating as a unit. It was
4 developed by Ericsson AB, as a means to provide for communications
5 between Common Control Systems processes and Network Element peers in
6 telephone switching systems, sometimes operating at arm's length on
7 different line cards or mainframes. Delegation of responsibility in this
8 way is one of the fundamental precepts of the Erlang programming system,
9 also developed at Ericsson. TIPC represents a more generalized version
10 of the same behavioral design pattern.
11
12 This document was produced using PlDoc, with sources found in tipc.pl
13 and tipc_overview.md.
14
15 @author: Jeffrey Rosenwald (JeffRose@acm.org)
16 @license: BSD-2
17 @compat: Linux only
0 # Transparent Inter-Process Communications (TIPC) Sockets.
1
2 TIPC provides a framework for inter-process communication between
3 federations of trusted peers that are cooperating as a unit. It was
4 developed by Ericsson AB, as a means to provide for communications
5 between Common Control Systems processes and Network Element peers in
6 telephone switching systems, sometimes operating at arm's length on
7 different line cards or mainframes. Delegation of responsibility in this
8 way is one of the fundamental precepts of the Erlang programming system,
9 also developed at Ericsson. TIPC represents a more generalized version
10 of the same behavioral design pattern.
11
12 This document was produced using PlDoc, with sources found in tipc.pl
13 and tipc_overview.md.
14
15 @author: Jeffrey Rosenwald (JeffRose@acm.org)
16 @license: BSD-2
17 @compat: Linux only
+0
-238
packages/tipc/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
22 Author: Jeffrey Rosenwald
33 E-mail: jeffrose@acm.org
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2009-2013, Jeffrey Rosenwald
5 Copyright (c) 2009-2020, Jeffrey Rosenwald
66 All rights reserved.
77
88 Redistribution and use in source and binary forms, with or without
5757 tipc_service_exists/2, % +Address +Timeout
5858 tipc_initialize/0 %
5959 ]).
60 :- use_module(library(apply)).
61 :- use_module(library(lists)).
62 :- use_module(library(shlib)).
60 :- autoload(library(apply),[maplist/3]).
61 :- autoload(library(lists),[member/2]).
62
6363 :- use_foreign_library(foreign(tipc)).
6464
6565 :- multifile tipc_stack_initialize/0.
3535 [ tipc_host_to_address/2, % ?Host, ?Address
3636 tipc_initialize/0
3737 ]).
38 :- use_module(library(tipc/tipc),[tipc_initialize/0]).
3839
3940 /** <module> A TIPC Broadcast Bridge
4041
233234 @compat Linux only
234235 */
235236
236 :- use_module(tipc).
237 :- use_module(library(broadcast)).
238 :- use_module(library(time)).
239 :- use_module(library(unix)).
237 :- autoload(tipc,
238 [ tipc_get_name/2,
239 tipc_send/4,
240 tipc_socket/2,
241 tipc_close_socket/1,
242 tipc_setopt/2,
243 tipc_bind/3,
244 tipc_receive/4
245 ]).
246 :- autoload(library(broadcast),
247 [broadcast_request/1,broadcast/1,listen/3,unlisten/1]).
248 :- autoload(library(debug),[assertion/1]).
249 :- autoload(library(time),
250 [call_with_time_limit/2,alarm/3,remove_alarm/1]).
240251
241252 :- require([ thread_self/1
242253 , forall/2
5757 tipc_linda_server/0, %
5858 tipc_initialize/0
5959 ]).
60
61 :- use_module(library(tipc/tipc_broadcast)).
62 :- use_module(library(unix)).
63
64 :- require([ broadcast/1
65 , broadcast_request/1
66 , throw/1
67 , member/2
68 , must_be/2
69 , catch/3
70 , flag/3
71 , listen/3
72 , setup_call_cleanup/3
73 , strip_module/3
74 ]).
75
60 :- use_module(library(tipc/tipc),[tipc_initialize/0]).
61 :- autoload(library(broadcast),
62 [listen/3,broadcast_request/1,broadcast/1,unlisten/3]).
63 :- autoload(library(debug),[assertion/1]).
64 :- autoload(library(error),[must_be/2]).
65 :- autoload(library(lists),[member/2]).
7666
7767 /** <module> A Process Communication Interface
7868
3939 tipc_paxos_on_change/2, % ?Term, +Goal
4040 tipc_initialize/0
4141 ]).
42 :- use_module(library(tipc/tipc_broadcast)).
43 :- use_module(library(paxos)).
42 :- use_module(library(tipc/tipc_broadcast), [tipc_initialize/0]).
43 :- autoload(library(paxos),[paxos_set/2,paxos_get/2,paxos_on_change/2]).
4444
4545 /** <module> Paxos on TIPC
4646
+0
-41
packages/windows/README less more
0 This directory contains two examples of foreign-language extensions.
1
2 # dlltest.dll
3 Simple code illustrating very basic functionality of the
4 interface. Load it using:
5
6 ?- load_foreign_library(dlltest).
7
8 It defines the following predicates:
9
10 say_hello(+Text)
11 Shows a simple Windows message-box containing
12 Text.
13 mclock(-MilliSeconds)
14 Return the number of milli-seconds elapsed since
15 the library was loaded.
16 rlc_color(+Which, +R, +G, +B)
17 Set the color of the plwin window. Which is one
18 of {window, text, highlight, highlighttext}, RGB
19 are integers between 0 and 255 for the color
20 components.
21
22 In addition, it illustrates how to hook into a Prolog abort.
23
24 # plregtry.dll
25 Defines predicates to access the Windows registry. It is a much
26 more elaborate example, and also a useful library. Its not
27 documented, but with some knowledge of the Windows API it should
28 be fairly easy to figure out how it works.
29
30 The .dsp files are Microsoft Visual C++ 5.0 project files. Basically, to
31 compile them:
32
33 * Ensure the compile has the SWI-Prolog include directory
34 in the search-path for header-files.
35
36 * Ensure the compiler has the SWI-Prolog lib directory in
37 the search-path for libraries.
38
39 * Ensure WIN32 is a defined symbol (-DWIN32). MSVC normally
40 defines this for you.
0 # Foreign language demo for Windows
1
2 This directory contains two examples of foreign-language extensions.
3
4 - dlltest.dll
5 Simple code illustrating very basic functionality of the
6 interface. Load it using:
7
8 ?- load_foreign_library(dlltest).
9
10 It defines the following predicates:
11
12 - say_hello(+Text)
13 Shows a simple Windows message-box containing Text.
14 - mclock(-MilliSeconds)
15 Return the number of milli-seconds elapsed since the library was loaded.
16 - rlc_color(+Which, +R, +G, +B)
17 Set the color of the plwin window. Which is one of {window, text,
18 highlight, highlighttext}, RGB are integers between 0 and 255 for
19 the color components.
20
21 In addition, it illustrates how to hook into a Prolog abort.
22
23 - plregtry.dll
24 Defines predicates to access the Windows registry. It is a much
25 more elaborate example, and also a useful library. Its not
26 documented, but with some knowledge of the Windows API it should
27 be fairly easy to figure out how it works.
+0
-238
packages/windows/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2011-2013, University of Amsterdam
5 Copyright (c) 2011-2020, University of Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
5253 % +IfNotRunning
5354 shell_register_prolog/1 % +Extension
5455 ]).
56 :- autoload(library(lists),[member/2]).
5557
5658 :- use_foreign_library(foreign(plregtry)). % load plregtry.ddl
5759
+0
-11
packages/windows/testenv less more
0 #!/bin/sh
1
2 # PLARCH is passed from packages/configure
3
4 case $PLARCH in
5 *-win32|*-win64)
6 exit 0
7 ;;
8 *)
9 exit 1
10 esac
4949 ]).
5050
5151 :- dynamic
52 autoload/2.
53 :- public
5254 autoload/2.
5355
5456 %! pce_autoload(+ClassName, +FileSpec)
6464 attribute/3, % ClassName, Attribute, Value
6565 verbose/0,
6666 recording/2. % items recorded
67 :- public
68 attribute/3,
69 compiling/2.
6770
6871 :- if(exists_source(library(quintus))).
6972 :- use_module(library(quintus), [genarg/3]).
22 Author: Jan Wielemaker and Anjo Anjewierden
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org/projects/xpce/
5 Copyright (c) 1985-2011, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
3636 :- require([ send/2,
3737 get/3
3838 ]).
39 :- public
40 property/1.
3941
4042 /*******************************
4143 * PROPERTIES *
6969 :- autoload(library(shlib),[load_foreign_library/1]).
7070 :- autoload(library(swi_compatibility),[pce_info/1]).
7171 :- autoload(library(system),[unlock_predicate/1]).
72
73 :- public
74 in_pce_thread_sync2/2.
7275
7376 :- meta_predicate
7477 send_class(+, +, :),
22 Author: Jan Wielemaker and Anjo Anjewierden
33 E-mail: J.Wielemaker@cs.vu.nl
44 WWW: http://www.swi.psy.uva.nl/projects/xpce/
5 Copyright (c) 1985-2013, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
5253 manpce/1,
5354 prolog_ide/1,
5455 spypce/1,
56 trace/1,
5557 tracepce/1,
5658 atomic_list_concat/2,
5759 breakpoint_property/2,
10151017 tracepce((Class-Name)).
10161018 do_trace((Head :- _Body), M, Spec) :-
10171019 prolog_debug_spec(M, Head, Spec),
1018 user:trace(Spec).
1020 @(trace(Spec), user).
10191021 do_trace(Head, M, Spec) :-
10201022 prolog_debug_spec(M, Head, Spec),
1021 user:trace(Spec).
1023 @(trace(Spec), user).
10221024
10231025 prolog_debug_spec(M, Head, Spec) :-
10241026 catch(functor(Head, Name, Arity), _, fail),
127127 },
128128 dlist(Codes, Tail),
129129 make_message(T).
130 make_message([ansi(_Attrs, Fmt, Args)|T]) -->
131 !,
132 { format(codes(Codes, Tail), Fmt, Args)
133 },
134 dlist(Codes, Tail),
135 make_message(T).
136 make_message([Skip|T]) -->
137 { action_skip(Skip) },
138 !,
139 make_message(T).
130140 make_message([Fmt|T]) -->
131141 make_message([Fmt-[]|T]).
142
143 action_skip(at_same_line).
144 action_skip(flush).
145 action_skip(begin(_Level, _Ctx)).
146 action_skip(end(_Ctx)).
132147
133148 dlist(Codes, Tail, Codes, Tail).
134149
9393 ).
9494
9595
96
9796 % gzip: can we write (and read back) a compressed file
9897
98 :- multifile user:file_search_path/1.
99 user:file_search_path(test_tmp_dir, '.').
100
101 tmp_output(Base, File) :-
102 absolute_file_name(test_tmp_dir(Base),
103 File,
104 [ access(write)
105 ]).
106
99107 test(gzip_ascii,
100 [ cleanup(delete_file('plunit-tmp.gz'))
101 ]) :-
102 numlist(0, 127, ReferenceCodes),
103 gzopen('plunit-tmp.gz', write, ZOut, [type(text), encoding(ascii)]),
104 set_stream(ZOut, newline(posix)),
105 format(ZOut, '~s', [ReferenceCodes]),
106 close(ZOut),
107 gzopen('plunit-tmp.gz', read, ZIn, [type(text)]),
108 [ setup(tmp_output('plunit-tmp.gz', Tmp)),
109 cleanup(delete_file(Tmp))
110 ]) :-
111 numlist(0, 127, ReferenceCodes),
112 gzopen(Tmp, write, ZOut, [type(text), encoding(ascii)]),
113 set_stream(ZOut, newline(posix)),
114 format(ZOut, '~s', [ReferenceCodes]),
115 close(ZOut),
116 gzopen(Tmp, read, ZIn, [type(text)]),
108117 set_stream(ZIn, newline(posix)),
109118 call_cleanup(read_stream_to_codes(ZIn, Codes), close(ZIn)),
110119 Codes = ReferenceCodes.
111120
112121 test(gzip_utf8,
113 [ cleanup(delete_file('plunit-tmp.gz'))
122 [ setup(tmp_output('plunit-tmp.gz', Tmp)),
123 cleanup(delete_file(Tmp))
114124 ]) :-
115125 numlist(0, 2047, ReferenceCodes),
116 gzopen('plunit-tmp.gz', write, ZOut, [type(text), encoding(utf8)]),
117 set_stream(ZOut, newline(posix)),
118 format(ZOut, '~s', [ReferenceCodes]),
119 close(ZOut),
120 gzopen('plunit-tmp.gz', read, ZIn, [type(text), encoding(utf8)]),
126 gzopen(Tmp, write, ZOut, [type(text), encoding(utf8)]),
127 set_stream(ZOut, newline(posix)),
128 format(ZOut, '~s', [ReferenceCodes]),
129 close(ZOut),
130 gzopen(Tmp, read, ZIn, [type(text), encoding(utf8)]),
121131 set_stream(ZIn, newline(posix)),
122132 call_cleanup(read_stream_to_codes(ZIn, Codes), close(ZIn)),
123133 Codes = ReferenceCodes.
124134
125135 test(gzip_binary,
126 [ cleanup(delete_file('plunit-tmp.gz'))
136 [ setup(tmp_output('plunit-tmp.gz', Tmp)),
137 cleanup(delete_file(Tmp))
127138 ]) :-
128139 numlist(0, 255, ReferenceCodes),
129 gzopen('plunit-tmp.gz', write, ZOut, [type(binary)]),
130 set_stream(ZOut, newline(posix)),
131 format(ZOut, '~s', [ReferenceCodes]),
132 close(ZOut),
133 gzopen('plunit-tmp.gz', read, ZIn, [type(binary)]),
140 gzopen(Tmp, write, ZOut, [type(binary)]),
141 set_stream(ZOut, newline(posix)),
142 format(ZOut, '~s', [ReferenceCodes]),
143 close(ZOut),
144 gzopen(Tmp, read, ZIn, [type(binary)]),
134145 set_stream(ZIn, newline(posix)),
135146 call_cleanup(read_stream_to_codes(ZIn, Codes), close(ZIn)),
136147 Codes = ReferenceCodes.
137148
138149 test(gzip_empty,
139 [ cleanup(delete_file('plunit-tmp.gz'))
140 ]) :-
141 gzopen('plunit-tmp.gz', write, ZOut),
142 close(ZOut),
143 gzopen('plunit-tmp.gz', read, ZIn, [type(text)]),
150 [ setup(tmp_output('plunit-tmp.gz', Tmp)),
151 cleanup(delete_file(Tmp))
152 ]) :-
153 gzopen(Tmp, write, ZOut),
154 close(ZOut),
155 gzopen(Tmp, read, ZIn, [type(text)]),
144156 call_cleanup(read_stream_to_codes(ZIn, Codes1), close(ZIn)),
145157 Codes1 = [].
146158
147159 test(gzip_multipart,
148 [ cleanup(delete_file('plunit-tmp.gz'))
149 ]) :-
150 gzopen('plunit-tmp.gz', write, ZOut1),
160 [ setup(tmp_output('plunit-tmp.gz', Tmp)),
161 cleanup(delete_file(Tmp))
162 ]) :-
163 gzopen(Tmp, write, ZOut1),
151164 format(ZOut1, 'Part1\n', []),
152165 close(ZOut1),
153 gzopen('plunit-tmp.gz', append, ZOut2),
166 gzopen(Tmp, append, ZOut2),
154167 format(ZOut2, 'Part2\n', []),
155168 close(ZOut2),
156 gzopen('plunit-tmp.gz', read, ZIn),
169 gzopen(Tmp, read, ZIn),
157170 call_cleanup(read_stream_to_codes(ZIn, Codes), close(ZIn)),
158171 atom_codes('Part1\nPart2\n', Codes).
159172
162175 % deflate: test read/write of deflate format
163176
164177 test(deflate_ascii,
165 [ cleanup(delete_file('plunit-tmp.z'))
166 ]) :-
167 numlist(0, 127, ReferenceCodes),
168 open('plunit-tmp.z', write, Out, [type(text), encoding(ascii)]),
178 [ setup(tmp_output('plunit-tmp.z', Tmp)),
179 cleanup(delete_file(Tmp))
180 ]) :-
181 numlist(0, 127, ReferenceCodes),
182 open(Tmp, write, Out, [type(text), encoding(ascii)]),
169183 zopen(Out, ZOut, []),
170184 set_stream(ZOut, newline(posix)),
171185 format(ZOut, '~s', [ReferenceCodes]),
172186 close(ZOut),
173 open('plunit-tmp.z', read, In, [type(text), encoding(ascii)]),
187 open(Tmp, read, In, [type(text), encoding(ascii)]),
174188 zopen(In, ZIn, []),
175189 set_stream(ZIn, newline(posix)),
176190 read_stream_to_codes(ZIn, Codes),
178192 Codes == ReferenceCodes.
179193
180194 test(deflate_utf8,
181 [ cleanup(delete_file('plunit-tmp.z'))
195 [ setup(tmp_output('plunit-tmp.z', Tmp)),
196 cleanup(delete_file(Tmp))
182197 ]) :-
183198 numlist(0, 2047, ReferenceCodes),
184 open('plunit-tmp.z', write, Out, [type(text), encoding(utf8)]),
199 open(Tmp, write, Out, [type(text), encoding(utf8)]),
185200 zopen(Out, ZOut, []),
186201 set_stream(ZOut, newline(posix)),
187202 format(ZOut, '~s', [ReferenceCodes]),
188203 close(ZOut),
189 open('plunit-tmp.z', read, In, [type(text), encoding(utf8)]),
204 open(Tmp, read, In, [type(text), encoding(utf8)]),
190205 zopen(In, ZIn, []),
191206 set_stream(ZIn, newline(posix)),
192207 read_stream_to_codes(ZIn, Codes),
194209 Codes == ReferenceCodes.
195210
196211 test(deflate_binary,
197 [ cleanup(delete_file('plunit-tmp.z'))
212 [ setup(tmp_output('plunit-tmp.z', Tmp)),
213 cleanup(delete_file(Tmp))
198214 ]) :-
199215 numlist(0, 255, ReferenceCodes),
200 open('plunit-tmp.z', write, Out, [type(binary)]),
216 open(Tmp, write, Out, [type(binary)]),
201217 zopen(Out, ZOut, []),
202218 format(ZOut, '~s', [ReferenceCodes]),
203219 close(ZOut),
204 open('plunit-tmp.z', read, In, [type(binary)]),
220 open(Tmp, read, In, [type(binary)]),
205221 zopen(In, ZIn, []),
206222 read_stream_to_codes(ZIn, Codes),
207223 close(ZIn),
208224 Codes == ReferenceCodes.
209225
210226 test(deflate_empty,
211 [ cleanup(delete_file('plunit-tmp.z'))
212 ]) :-
213 open('plunit-tmp.z', write, Out),
227 [ setup(tmp_output('plunit-tmp.z', Tmp)),
228 cleanup(delete_file(Tmp))
229 ]) :-
230 open(Tmp, write, Out),
214231 zopen(Out, ZOut, []),
215232 close(ZOut),
216 open('plunit-tmp.z', read, In),
233 open(Tmp, read, In),
217234 zopen(In, ZIn, []),
218235 read_stream_to_codes(ZIn, Codes),
219236 close(ZIn),
220237 Codes == [].
221238
222 test(deflate_low_compression) :-
223 numlist(0, 127, ReferenceCodes),
224 open('plunit-tmp.z', write, Out),
239 test(deflate_low_compression,
240 [ setup(tmp_output('plunit-tmp.z', Tmp)),
241 cleanup(delete_file(Tmp))
242 ]) :-
243 numlist(0, 127, ReferenceCodes),
244 open(Tmp, write, Out),
225245 zopen(Out, ZOut, [level(0)]),
226246 set_stream(ZOut, newline(posix)),
227247 format(ZOut, '~s', [ReferenceCodes]),
228248 close(ZOut),
229 open('plunit-tmp.z', read, In),
230 zopen(In, ZIn, []),
231 set_stream(ZIn, newline(posix)),
232 read_stream_to_codes(ZIn, Codes),
233 close(ZIn),
234 Codes == ReferenceCodes.
235
236 test(deflate_high_compression) :-
237 numlist(0, 127, ReferenceCodes),
238 open('plunit-tmp.z', write, Out),
249 open(Tmp, read, In),
250 zopen(In, ZIn, []),
251 set_stream(ZIn, newline(posix)),
252 read_stream_to_codes(ZIn, Codes),
253 close(ZIn),
254 Codes == ReferenceCodes.
255
256 test(deflate_high_compression,
257 [ setup(tmp_output('plunit-tmp.z', Tmp)),
258 cleanup(delete_file(Tmp))
259 ]) :-
260 numlist(0, 127, ReferenceCodes),
261 open(Tmp, write, Out),
239262 zopen(Out, ZOut, [level(9)]),
240263 set_stream(ZOut, newline(posix)),
241264 format(ZOut, '~s', [ReferenceCodes]),
242265 close(ZOut),
243 open('plunit-tmp.z', read, In),
266 open(Tmp, read, In),
244267 zopen(In, ZIn, []),
245268 set_stream(ZIn, newline(posix)),
246269 read_stream_to_codes(ZIn, Codes),
248271 Codes == ReferenceCodes.
249272
250273 test(deflate_multipart,
251 [ cleanup(delete_file('plunit-tmp.z'))
252 ]) :-
253 open('plunit-tmp.z', write, Out),
274 [ setup(tmp_output('plunit-tmp.z', Tmp)),
275 cleanup(delete_file(Tmp))
276 ]) :-
277 open(Tmp, write, Out),
254278 zopen(Out, ZOut1, [close_parent(false)]),
255279 format(ZOut1, 'Part1\n', []),
256280 close(ZOut1),
257281 zopen(Out, ZOut2, []),
258282 format(ZOut2, 'Part2\n', []),
259283 close(ZOut2),
260 open('plunit-tmp.z', read, In),
284 open(Tmp, read, In),
261285 zopen(In, ZIn, [multi_part(true)]),
262286 read_stream_to_codes(ZIn, Codes),
263287 close(ZIn),
1717
1818 printf "Adding Macport dylibs to modules in $moduledir\n"
1919
20 changeset="$(echo $moduledir/*)"
20 changeset="$(echo $moduledir/*) $app/Contents/MacOS/swipl"
2121 while [ ! -z "$changeset" ]; do
2222 newchanges=
2323 for f in $changeset; do
6161 A atanh "atanh"
6262 A atom "atom"
6363 A atom_garbage_collection "atom_garbage_collection"
64 A atom_space "atom_space"
6465 A atomic "atomic"
6566 A atoms "atoms"
6667 A att "att"
335336 A full "full"
336337 A fullstop "fullstop"
337338 A functor_name "functor_name"
339 A functor_space "functor_space"
338340 A functors "functors"
339341 A fx "fx"
340342 A fy "fy"
372374 A hide_childs "hide_childs"
373375 A history_depth "history_depth"
374376 A id "id"
377 A idg_affected_count "idg_affected_count"
378 A idg_dependent_count "idg_dependent_count"
379 A idg_size "idg_size"
375380 A ifthen "->"
376381 A ignore "ignore"
377382 A ignore_ops "ignore_ops"
689694 A shared_table_space "shared_table_space"
690695 A shell "shell"
691696 A shift_time "shift_time"
697 A short "short"
692698 A sign "sign"
693699 A signal "signal"
694700 A signal_handler "signal_handler"
787793 A thread_property "thread_property"
788794 A threads "threads"
789795 A threads_created "threads_created"
796 A threads_peak "threads_peak"
790797 A trienode "trienode"
791798 A tripwire "tripwire"
792799 A throw "throw"
322322 if(HAVE_LIBRT)
323323 set(LIBSWIPL_LIBRARIES ${LIBSWIPL_LIBRARIES} rt)
324324 endif()
325 if(HAVE_LIBATOMIC)
326 set(LIBSWIPL_LIBRARIES ${LIBSWIPL_LIBRARIES} atomic)
327 endif()
328 if(LIBTCMALLOC_LIBRARIES)
329 set(SWIPL_LIBRARIES ${LIBTCMALLOC_LIBRARIES} ${SWIPL_LIBRARIES})
330 endif()
325331
326332 # build swipl
327333 add_executable(swipl ${SWIPL_SRC})
328 target_link_libraries(swipl libswipl)
334 target_link_libraries(swipl ${SWIPL_LIBRARIES} libswipl)
329335 target_c_stack(swipl 4000000)
330336
331337 # build the library
472478 COMMAND ${PROG_SWIPL} -f none --no-packs -q ${CMAKE_CURRENT_SOURCE_DIR}/test.pl --no-core ${test})
473479 endforeach()
474480
475 if(INSTALL_TESTS)
476 #Copy core tests to the installation
481 # Use a function to scope CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
482 function(install_tests)
483 set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Tests)
477484 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Tests
478485 DESTINATION ${INSTALL_TESTS_DIR})
479486 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test.pl
480487 DESTINATION ${INSTALL_TESTS_DIR}/)
488 endfunction()
489
490 if(INSTALL_TESTS)
491 install_tests()
481492 endif()
482493
483494 # Populate parms.h, making the compilation environment known to Prolog
6767 /* PLVERSION_TAG: a string, normally "", but for example "rc1" */
6868
6969 #ifndef PLVERSION
70 #define PLVERSION 80126
70 #define PLVERSION 80128
7171 #endif
7272 #ifndef PLVERSION_TAG
7373 #define PLVERSION_TAG ""
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2009-2019, University of Amsterdam
5 Copyright (c) 2009-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
3838 test_clause_gc/1
3939 ]).
4040
41 %% test_clause_gc
41 %! test_clause_gc
4242 %
43 % This test runs a loop that builds a list and for each iteration
44 % runs clause/2 on a term that contains all relevant programing
45 % constructs. The idea is to trigger GC and shifts at different
46 % parts of this process.
43 % This test runs a loop that builds a list and for each iteration runs
44 % clause/2 on a term that contains all relevant programing constructs.
45 % The idea is to trigger GC and shifts at different parts of this
46 % process.
4747
4848 test_clause_gc :-
49 setup_call_cleanup(( current_prolog_flag(stack_limit, SavedLimit),
50 set_prolog_flag(stack_limit, 2_000_000),
51 gspace(Cells),
52 MaxLen is max(10000, (Cells//4)//3)),
53 test_clause_gc(MaxLen),
54 set_prolog_flag(stack_limit, SavedLimit)).
49 setup_call_cleanup(( current_prolog_flag(stack_limit, SavedLimit),
50 set_prolog_flag(stack_limit, 2_000_000),
51 gspace(Cells),
52 MaxLen is max(10000, (Cells//4)//3)),
53 test_clause_gc(MaxLen),
54 set_prolog_flag(stack_limit, SavedLimit)).
5555
5656 test_clause_gc(N) :-
57 run(N, L),
58 is_list(L). % avoid L from being GC'ed
57 catch(run(N, L), error(resource_error(stack), _), L=[]),
58 is_list(L). % avoid L from being GC'ed
5959
6060 run(N, L) :-
61 functor(H, cl, 8),
62 clause(H, B),
63 run(N, H, B, L).
61 functor(H, cl, 8),
62 clause(H, B),
63 run(N, H, B, L).
6464
6565 run(N, H, B, [x|L]) :-
66 succ(N2, N), !,
67 functor(H2, cl, 8),
68 clause(H2, B2),
69 H =@= H2,
70 B =@= B2,
71 run(N2, H, B, L).
66 succ(N2, N), !,
67 functor(H2, cl, 8),
68 clause(H2, B2),
69 H =@= H2,
70 B =@= B2,
71 run(N2, H, B, L).
7272 run(_, _, _, []).
7373
7474 :- dynamic cl/8. % make sure we can use clause/2
9696 *******************************/
9797
9898 gspace(Cells) :-
99 current_prolog_flag(stack_limit, Limit),
100 statistics(globalused, Used),
101 current_prolog_flag(address_bits, Wlen),
102 Cells is (Limit-Used)//(Wlen//8).
99 garbage_collect,
100 current_prolog_flag(stack_limit, Limit),
101 statistics(globalused, GUsed),
102 statistics(localused, LUsed),
103 statistics(trailused, TUsed),
104 Used is GUsed+LUsed+TUsed,
105 current_prolog_flag(address_bits, Wlen),
106 Cells is (Limit-Used)//(Wlen//8).
0 /* Part of SWI-Prolog
1
2 Author: Jan Wielemaker
3 E-mail: J.Wielemaker@vu.nl
4 WWW: http://www.swi-prolog.org
5 Copyright (c) 2020, University of Amsterdam
6 VU University Amsterdam
7 CWI, Amsterdam
8 All rights reserved.
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 :- module(test_thread_property,
37 [ test_thread_property/0
38 ]).
39 :- use_module(library(aggregate)).
40 :- use_module(library(debug)).
41
42 :- thread_local p/1, q/1.
43
44 %! test_thread_property
45 %
46 % Tests asynchronous polling for thread properties while (notably)
47 % threads terminate. Currently only checks the new size(Bytes)
48 % property.
49
50 test_thread_property :-
51 test_thread_property(100).
52
53 test_thread_property(N) :-
54 thread_create(create_threads(N), Id, []),
55 thread_create(poll_threads, Id2, []),
56 thread_join(Id),
57 thread_send_message(Id2, done),
58 thread_join(Id2).
59
60 create_threads(N) :-
61 forall(between(1, N, _),
62 ( thread_create(tmain, Id, [detached(true)]),
63 catch(( thread_send_message(Id, hello(world)),
64 thread_send_message(Id, done)),
65 E,
66 print_message(warning, E)),
67 wait_drain
68 )).
69
70 wait_drain :-
71 ( statistics(threads, N),
72 N < 10
73 -> true
74 ; sleep(0.01),
75 wait_drain
76 ).
77
78 tmain :-
79 forall(between(1, 100, I),
80 ( assert(p(I)),
81 assert(q(I)))).
82
83 poll_threads :-
84 thread_self(Me),
85 thread_get_message(Me, done, [timeout(0)]),
86 !.
87 poll_threads :-
88 aggregate_all(sum(S),
89 thread_property(_, size(S)),
90 Sum),
91 debug(thread(size), 'Sum = ~D', [Sum]),
92 poll_threads.
93
3434 :- module(thr_local_1,
3535 [ thr_local_1/0
3636 ]).
37 :- use_module(library(apply)).
3738
38 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
39 /** <module> Test thread local predicates
40
3941 This test validates the operation of thread-local dynamic predicates. It
40 creates 5 threads asserting the 1000 facts 1...1000 and checks they can
42 creates 5 threads asserting the 1000 facts 1...1000 and checks they can
4143 be retracted in the proper order.
42 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45 This test is a little overly complicated because a previous version was
46 broken and we want to stay close to the previous example. One __can
47 not__ to the following:
48
49 - Create a thread using a `_` id (anonymous) and not detached and
50 expects we can safely keep it running and join it by making the
51 thread tell a join-thread that it is done.
52
53 The reason for this is that atom-gc collects the handle and, if the
54 thread still runs it _detaches_ it, so we can not join it. If it is
55 already completed the garbage collector will join it, assuming that if
56 nobody knows about this thread is it is safe the reclaim it.
57 */
4358
4459 :- thread_local
4560 foo/1.
4863 thr_local_1(5, 1000).
4964
5065 thr_local_1(Threads, Asserts) :-
66 thread_create(acg_loop, Agc, []),
5167 thread_create(join(Threads), Id, []),
52 forall(between(1, Threads, _),
53 thread_create(test_foo(Asserts), _,
54 [ at_exit(done(Id))
55 ])),
56 join_ok(Id).
68 length(Ids, Threads),
69 maplist(create_test_foo_thread(Asserts, Id), Ids),
70 join_ok(Id),
71 is_list(Ids), % avoid GC
72 thread_send_message(Agc, done),
73 join_ok(Agc).
74
75 acg_loop :-
76 garbage_collect_atoms,
77 ( thread_peek_message(done)
78 -> true
79 ; sleep(0.001),
80 acg_loop
81 ).
5782
5883 join(Times) :-
84 thread_self(Me),
85 debug(thread(local), 'Waiting thread = ~p', [Me]),
5986 forall(between(1, Times, _),
6087 ( thread_get_message(done(Done)),
6188 join_ok(Done)
6289 )).
6390
6491 join_ok(Id) :-
92 debug(thread(local), 'Joining ~p ...', [Id]),
6593 thread_join(Id, Return),
94 debug(thread(local), ' ... ~p', [Return]),
6695 ( Return == true
6796 -> true
6897 ; format('~N~p returned ~p~n', [Id, Return]),
6998 fail
7099 ).
71100
101
102 create_test_foo_thread(Asserts, ReportTo, Id) :-
103 thread_create(test_foo(Asserts), Id,
104 [ at_exit(done(ReportTo))
105 ]).
72106
73107 test_foo(N) :-
74108 forall(between(0, N, X),
112146
113147 done(Report) :-
114148 thread_self(Me),
149 debug(thread(local), 'Signalling ~p that me (~p) is done', [Report, Me]),
115150 thread_send_message(Report, done(Me)).
4242 % Similar to thread_agc_findall.pl, but without using findall.
4343
4444 thread_agc :-
45 protocol(x),
4645 thread_agc(4, 10000).
4746
4847 thread_agc(Threads, Count) :-
215215 #cmakedefine HAVE_ZUTIL_H @HAVE_ZUTIL_H@
216216 #cmakedefine HAVE__BUILTIN_CLZ @HAVE__BUILTIN_CLZ@
217217 #cmakedefine HAVE__BUILTIN_POPCOUNT @HAVE__BUILTIN_POPCOUNT@
218 #cmakedefine HAVE__SYNC_SYNCHRONIZE @HAVE__SYNC_SYNCHRONIZE@
219 #cmakedefine HAVE___SYNC_ADD_AND_FETCH_8 @HAVE___SYNC_ADD_AND_FETCH_8@
218 #cmakedefine HAVE_GCC_ATOMIC @HAVE_GCC_ATOMIC@
219 #cmakedefine HAVE_GCC_ATOMIC_8 @HAVE_GCC_ATOMIC_8@
220220 #cmakedefine HAVE__NSGETENVIRON @HAVE__NSGETENVIRON@
221221 #cmakedefine LD_SYMBOL_PREFIX @LD_SYMBOL_PREFIX@
222222 #cmakedefine LINUX_CPUCLOCKS @LINUX_CPUCLOCKS@
265265 #cmakedefine VOID_UNSETENV @VOID_UNSETENV@
266266 #cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
267267 #cmakedefine _LARGE_FILES @_LARGE_FILES@
268 #cmakedefine _LARGEFILE_SOURCE @_LARGEFILE_SOURCE@
268269 #cmakedefine _POSIX_PTHREAD_SEMANTICS @_POSIX_PTHREAD_SEMANTICS@
269270 #cmakedefine _THREAD_SAFE @_THREAD_SAFE@
270271 #cmakedefine inline @inline@
271272 #cmakedefine pid_t @pid_t@
272273 #cmakedefine size_t @size_t@
273274 #cmakedefine vfork @vfork@
275 #cmakedefine HAVE_TCMALLOC_EXTENSION_C_H @HAVE_TCMALLOC_EXTENSION_C_H@
274276
275277 #cmakedefine HAVE_PTHREAD_GETCPUCLOCKID
276278 #cmakedefine HAVE_F_SETLKW
4848 sz *= 2;
4949
5050 if ( b->base == b->static_buffer )
51 { if ( !(new = malloc(sz)) )
51 { sz = tmp_nalloc(sz);
52 if ( !(new = tmp_malloc(sz)) )
5253 return FALSE;
5354
5455 memcpy(new, b->static_buffer, osz);
5556 } else
56 { if ( !(new = realloc(b->base, sz)) )
57 { sz = tmp_nrealloc(b->base, sz);
58 if ( !(new = tmp_realloc(b->base, sz)) )
5759 return FALSE;
5860 }
5961
8789
8890 if ( !b->base )
8991 initBuffer(b);
92 else
93 emptyBuffer(b);
9094
91 emptyBuffer(b);
9295 return b;
9396 }
9497
3434 #ifndef BUFFER_H_INCLUDED
3535 #define BUFFER_H_INCLUDED
3636
37 #define STATIC_BUFFER_SIZE (512)
37 #define STATIC_BUFFER_SIZE (512)
38 #define BUFFER_DISCARD_ABOVE (4096)
3839
3940 typedef struct
4041 { char * base; /* allocated base */
108109 #define initBuffer(b) ((b)->base = (b)->top = (b)->static_buffer, \
109110 (b)->max = (b)->base + \
110111 sizeof((b)->static_buffer))
111 #define emptyBuffer(b) ((b)->top = (b)->base)
112 #define emptyBuffer(b) emptyBuffer_((Buffer)(b), \
113 sizeof((b)->static_buffer))
112114 #define isEmptyBuffer(b) ((b)->top == (b)->base)
113115 #define popBuffer(b,type) \
114116 ((b)->top -= sizeof(type), *(type*)(b)->top)
115117 #define popBufferP(b,type) \
116118 ((b)->top -= sizeof(type), (type*)(b)->top)
119 #define discardBuffer(b) discardBuffer_((Buffer)(b))
117120
118 #define discardBuffer(b) \
119 do \
120 { if ( (b)->base && (b)->base != (b)->static_buffer ) \
121 { free((b)->base); \
122 (b)->base = (b)->static_buffer; \
123 } \
124 } while(0)
121 static inline void
122 discardBuffer_(Buffer b)
123 { if ( b->base && b->base != b->static_buffer )
124 tmp_free(b->base);
125 }
125126
127 static inline void
128 emptyBuffer_(Buffer b, size_t emptysize)
129 { if ( b->max - b->base < BUFFER_DISCARD_ABOVE )
130 { b->top = b->base;
131 } else
132 { discardBuffer(b);
133 b->base = b->top = b->static_buffer,
134 b->max = b->base + emptysize;
135 }
136 }
126137
127138 /*******************************
128139 * FUNCTIONS *
174174 ctx->alias_head = ctx->alias_tail = NULL;
175175 ctx->filename = NULL_ATOM;
176176 ctx->flags = 0;
177 if ( COMPARE_AND_SWAP(&s->context, NULL, ctx) )
177 if ( COMPARE_AND_SWAP_PTR(&s->context, NULL, ctx) )
178178 addNewHTable(streamContext, s, ctx);
179179 else
180180 freeHeap(ctx, sizeof(*ctx));
284284 PL_LOCK(L_FILE);
285285 unaliasStream(s, NULL_ATOM);
286286 ctx = s->context;
287 if ( ctx && COMPARE_AND_SWAP(&s->context, ctx, NULL) )
287 if ( ctx && COMPARE_AND_SWAP_PTR(&s->context, ctx, NULL) )
288288 { deleteHTable(streamContext, s);
289289 if ( ctx->filename != NULL_ATOM )
290290 { PL_unregister_atom(ctx->filename);
463463 }
464464 #endif
465465
466 return 0;
466 return heapUsed(); /* from pl-alloc.c */
467467 }
468468
469469
475475 struct rlimit limit;
476476
477477 if ( getrlimit(RLIMIT_DATA, &limit) == 0 )
478 return limit.rlim_cur - used;
478 { if ( limit.rlim_cur == RLIM_INFINITY )
479 return (uintptr_t)-1;
480 else
481 return limit.rlim_cur - used;
482 }
479483 #endif
480484
481485 return 0L;
914914 else if ( k == ATOM_shared_table_space )
915915 { if ( !GD->tabling.node_pool )
916916 { alloc_pool *pool = new_alloc_pool("shared_table_space", i);
917 if ( pool && !COMPARE_AND_SWAP(&GD->tabling.node_pool, NULL, pool) )
917 if ( pool && !COMPARE_AND_SWAP_PTR(&GD->tabling.node_pool, NULL, pool) )
918918 free_alloc_pool(pool);
919919 } else
920920 GD->tabling.node_pool->limit = (size_t)i;
14271427 setPrologFlag("dialect", FT_ATOM|FF_READONLY, "swi");
14281428 if ( systemDefaults.home )
14291429 setPrologFlag("home", FT_ATOM|FF_READONLY, systemDefaults.home);
1430 #ifdef PLSHAREDHOME
1431 setPrologFlag("shared_home", FT_ATOM|FF_READONLY, PLSHAREDHOME);
1432 #endif
14301433 if ( GD->paths.executable )
14311434 setPrologFlag("executable", FT_ATOM|FF_READONLY, GD->paths.executable);
14321435 #if defined(HAVE_GETPID) || defined(EMULATE_GETPID)
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2017, University of Amsterdam
6 VU University Amsterdam
7 CWI, Amsterdam
5 Copyright (c) 2017-2020, University of Amsterdam
6 VU University Amsterdam
7 CWI, Amsterdam
88 All rights reserved.
99
1010 Redistribution and use in source and binary forms, with or without
3939 #include "SWI-Stream.h"
4040
4141 #ifdef O_PLMT
42 #define ATOMIC_ADD(ptr, v) __sync_add_and_fetch(ptr, v)
43 #define ATOMIC_SUB(ptr, v) __sync_sub_and_fetch(ptr, v)
44 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
45 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
42 #define ATOMIC_ADD(ptr, v) __atomic_add_fetch(ptr, v, __ATOMIC_SEQ_CST)
43 #define ATOMIC_SUB(ptr, v) __atomic_sub_fetch(ptr, v, __ATOMIC_SEQ_CST)
44 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
45 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
4646 #else
47 #define ATOMIC_ADD(ptr, v) (*ptr += v)
48 #define ATOMIC_SUB(ptr, v) (*ptr -= v)
49 #define ATOMIC_INC(ptr) (++(*ptr))
50 #define ATOMIC_DEC(ptr) (--(*ptr))
47 #define ATOMIC_ADD(ptr, v) (*ptr += v)
48 #define ATOMIC_SUB(ptr, v) (*ptr -= v)
49 #define ATOMIC_INC(ptr) (++(*ptr))
50 #define ATOMIC_DEC(ptr) (--(*ptr))
5151 #endif
5252
5353
118118 }
119119
120120 static inline int htable_cas_name(KVS kvs, int idx, void *exp, void *name)
121 { return COMPARE_AND_SWAP(&kvs->entries[idx].name, exp, name);
121 { return COMPARE_AND_SWAP_PTR(&kvs->entries[idx].name, exp, name);
122122 }
123123
124124 static inline int htable_cas_value(KVS kvs, int idx, void *exp, void *value)
125 { return COMPARE_AND_SWAP(&kvs->entries[idx].value, exp, value);
125 { return COMPARE_AND_SWAP_PTR(&kvs->entries[idx].value, exp, value);
126126 }
127127
128128 static inline int htable_cas_new_kvs(KVS kvs, KVS new_kvs)
129 { return COMPARE_AND_SWAP(&kvs->next, NULL, new_kvs);
129 { return COMPARE_AND_SWAP_PTR(&kvs->next, NULL, new_kvs);
130130 }
131131
132132 static inline int htable_cas_cleanup(Table ht, int exp, int cleanup)
133 { return COMPARE_AND_SWAP(&ht->cleanup, exp, cleanup);
133 { return COMPARE_AND_SWAP_INT(&ht->cleanup, exp, cleanup);
134134 }
135135
136136
0 #define PLHOME "@PLHOME@"
1 #define PLARCH "@PLARCH@"
2 #define C_CC "@C_CC@"
3 #define C_CXX "@C_CXX@"
4 #define C_CFLAGS "@C_CFLAGS@"
5 #cmakedefine SO_EXT "@SO_EXT@"
6 #cmakedefine SO_PATH "@SO_PATH@"
7 #cmakedefine C_LIBDIR "@SWIPL_RELATIVE_LIBDIR@"
8 #cmakedefine C_LIBPLSO "@C_LIBPLSO@"
9 #define C_LIBS ""
10 #define C_PLLIB "-lswipl"
11 #define C_LDFLAGS ""
0 #define PLHOME "@PLHOME@"
1 #cmakedefine PLSHAREDHOME "@PLSHAREDHOME@"
2 #define PLARCH "@PLARCH@"
3 #define C_CC "@C_CC@"
4 #define C_CXX "@C_CXX@"
5 #define C_CFLAGS "@C_CFLAGS@"
6 #cmakedefine SO_EXT "@SO_EXT@"
7 #cmakedefine SO_PATH "@SO_PATH@"
8 #cmakedefine C_LIBDIR "@SWIPL_RELATIVE_LIBDIR@"
9 #cmakedefine C_LIBPLSO "@C_LIBPLSO@"
10 #define C_LIBS ""
11 #define C_PLLIB "-lswipl"
12 #define C_LDFLAGS ""
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2018, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
3636 #include "pl-incl.h"
3737 #include "os/pl-cstack.h"
3838 #include "pl-dict.h"
39 #ifdef HAVE_SYS_MMAN_H
40 #define MMAP_STACK 1
41 #include <sys/mman.h>
42 #include <unistd.h>
43 #endif
3944
4045 #undef LD
4146 #define LD LOCAL_LD
199204 do
200205 { o = *list;
201206 c->next = o;
202 } while( !COMPARE_AND_SWAP(list, o, c) );
207 } while( !COMPARE_AND_SWAP_PTR(list, o, c) );
203208 }
204209
205210 void
209214
210215 while ( c )
211216 { if ( c->generation < generation )
212 { while ( !COMPARE_AND_SWAP(p, c, c->next) )
217 { while ( !COMPARE_AND_SWAP_PTR(p, c, c->next) )
213218 { p = &(*p)->next;
214219 }
215220 (*c->unalloc)(c->object);
715720 { Word *newbase;
716721 size_t newsize = nextStackSize((Stack)&LD->stacks.argument, 1);
717722
718 if ( newsize && (newbase = stack_realloc(aBase, newsize)) )
723 if ( newsize &&
724 (newsize = stack_nalloc(newsize)) &&
725 (newbase = stack_realloc(aBase, newsize)) )
719726 { intptr_t as = newbase - aBase;
720727
721728 if ( as )
13741381 initHBase();
13751382 }
13761383
1384 /*******************************
1385 * MMAP STACKS *
1386 *******************************/
1387
1388 #ifdef MMAP_STACK
1389 #define MMAP_THRESHOLD 32768
1390
1391 typedef struct
1392 { size_t size; /* Size (including header) */
1393 int mmapped; /* Is mmapped? */
1394 double data[1]; /* ensure alignment */
1395 } map_region;
1396
1397 #define SA_OFFSET offsetof(map_region, data)
1398
1399 static size_t
1400 pgsize(void)
1401 { static size_t sz = 0;
1402
1403 if ( !sz )
1404 sz = sysconf(_SC_PAGESIZE);
1405
1406 return sz;
1407 }
1408
1409 static inline size_t
1410 roundpgsize(size_t sz)
1411 { size_t r = pgsize();
1412
1413 return ((sz+r-1)/r)*r;
1414 }
1415
1416 size_t
1417 tmp_nalloc(size_t req)
1418 { if ( req < MMAP_THRESHOLD-SA_OFFSET )
1419 return req;
1420
1421 return roundpgsize(req+SA_OFFSET)-SA_OFFSET;
1422 }
1423
1424 size_t
1425 tmp_nrealloc(void *mem, size_t req)
1426 { if ( mem )
1427 { map_region *reg = (map_region *)((char*)mem-SA_OFFSET);
1428
1429 if ( !reg->mmapped && req < MMAP_THRESHOLD-SA_OFFSET )
1430 return req;
1431
1432 return roundpgsize(req+SA_OFFSET)-SA_OFFSET;
1433 }
1434
1435 return tmp_nalloc(req);
1436 }
1437
1438
1439 size_t
1440 tmp_malloc_size(void *mem)
1441 { if ( mem )
1442 { map_region *reg = (map_region *)((char*)mem-SA_OFFSET);
1443 return reg->size-SA_OFFSET;
1444 }
1445
1446 return 0;
1447 }
1448
1449 void *
1450 tmp_malloc(size_t req)
1451 { map_region *reg;
1452 int mmapped;
1453
1454 req += SA_OFFSET;
1455 if ( req < MMAP_THRESHOLD )
1456 { reg = malloc(req);
1457 mmapped = FALSE;
1458 } else
1459 { req = roundpgsize(req);
1460
1461 reg = mmap(NULL, req,
1462 (PROT_READ|PROT_WRITE),
1463 (MAP_PRIVATE|MAP_ANONYMOUS),
1464 -1, 0);
1465 if ( reg == MAP_FAILED )
1466 reg = NULL;
1467 mmapped = TRUE;
1468 }
1469
1470 if ( reg )
1471 { reg->size = req;
1472 reg->mmapped = mmapped;
1473 #ifdef O_DEBUG
1474 memset(reg->data, 0xFB, req-SA_OFFSET);
1475 #endif
1476
1477 return reg->data;
1478 }
1479
1480 return NULL;
1481 }
1482
1483
1484 void *
1485 tmp_realloc(void *mem, size_t req)
1486 { if ( mem )
1487 { map_region *reg = (map_region *)((char*)mem-SA_OFFSET);
1488
1489 req += SA_OFFSET;
1490 if ( !reg->mmapped )
1491 { if ( req < MMAP_THRESHOLD )
1492 { map_region *nw = realloc(reg, req);
1493 if ( nw )
1494 { nw->size = req;
1495 return nw->data;
1496 }
1497 return NULL;
1498 } else /* malloc --> mmap */
1499 { void *nw = tmp_malloc(req-SA_OFFSET);
1500 if ( nw )
1501 { size_t copy = reg->size;
1502
1503 if ( copy > req )
1504 copy = req;
1505
1506 memcpy(nw, mem, copy-SA_OFFSET);
1507 free(reg);
1508 }
1509 return nw;
1510 }
1511 } else
1512 { req = roundpgsize(req);
1513
1514 if ( reg->size != req )
1515 { if ( reg->size > req )
1516 { size_t trunk = reg->size-req;
1517
1518 munmap((char*)reg+req, trunk);
1519 reg->size = req;
1520
1521 return reg->data;
1522 } else
1523 { void *ra = tmp_malloc(req);
1524
1525 if ( ra )
1526 { memcpy(ra, mem, reg->size-SA_OFFSET);
1527 #ifdef O_DEBUG
1528 memset((char*)ra+reg->size-SA_OFFSET, 0xFB,
1529 req-(reg->size-SA_OFFSET));
1530 #endif
1531 tmp_free(mem);
1532 }
1533
1534 return ra;
1535 }
1536 } else
1537 { return mem;
1538 }
1539 }
1540 } else
1541 { return tmp_malloc(req);
1542 }
1543 }
1544
1545
1546 void
1547 tmp_free(void *mem)
1548 { if ( mem )
1549 { map_region *reg = (map_region *)((char*)mem-SA_OFFSET);
1550
1551 if ( reg->mmapped )
1552 munmap(reg, reg->size);
1553 else
1554 free(reg);
1555 }
1556 }
1557
1558 #else /*MMAP_STACK*/
1559
1560 size_t
1561 tmp_nalloc(size_t req)
1562 { return req;
1563 }
1564
1565 size_t
1566 tmp_nrealloc(void *mem, size_t req)
1567 { (void)mem;
1568
1569 return req;
1570 }
1571
1572 size_t
1573 tmp_malloc_size(void *mem)
1574 { if ( mem )
1575 { size_t *sp = mem;
1576 return sp[-1];
1577 }
1578
1579 return 0;
1580 }
1581
1582 void *
1583 tmp_malloc(size_t size)
1584 { void *mem = malloc(size+sizeof(size_t));
1585
1586 if ( mem )
1587 { size_t *sp = mem;
1588 *sp++ = size;
1589 #ifdef O_DEBUG
1590 memset(sp, 0xFB, size);
1591 #endif
1592
1593 return sp;
1594 }
1595
1596 return NULL;
1597 }
1598
1599 void *
1600 tmp_realloc(void *old, size_t size)
1601 { size_t *sp = old;
1602 size_t osize = *--sp;
1603 void *mem;
1604
1605 #ifdef O_DEBUG
1606 if ( (mem = tmp_malloc(size)) )
1607 { memcpy(mem, old, (size>osize?osize:size));
1608 tmp_free(old);
1609 return mem;
1610 }
1611 #else
1612 (void)osize;
1613 if ( (mem = realloc(sp, size+sizeof(size_t))) )
1614 { sp = mem;
1615 *sp++ = size;
1616 return sp;
1617 }
1618 #endif
1619
1620 return NULL;
1621 }
1622
1623 void
1624 tmp_free(void *mem)
1625 { size_t *sp = mem;
1626 size_t osize = *--sp;
1627
1628 #ifdef O_DEBUG
1629 memset(sp, 0xFB, osize+sizeof(size_t));
1630 #else
1631 (void)osize;
1632 #endif
1633 free(sp);
1634 }
1635
1636 #endif /*MMAP_STACK*/
1637
1638 void *
1639 stack_malloc(size_t size)
1640 { void *ptr = tmp_malloc(size);
1641
1642 if ( ptr )
1643 ATOMIC_ADD(&GD->statistics.stack_space, tmp_malloc_size(ptr));
1644
1645 return ptr;
1646 }
1647
1648 void *
1649 stack_realloc(void *mem, size_t size)
1650 { size_t osize = tmp_malloc_size(mem);
1651 void *ptr = tmp_realloc(mem, size);
1652
1653 if ( ptr )
1654 { size = tmp_malloc_size(ptr);
1655
1656 if ( osize > size )
1657 ATOMIC_SUB(&GD->statistics.stack_space, osize-size);
1658 else
1659 ATOMIC_ADD(&GD->statistics.stack_space, size-osize);
1660 }
1661
1662 return ptr;
1663 }
1664
1665 void
1666 stack_free(void *mem)
1667 { size_t size = tmp_malloc_size(mem);
1668
1669 ATOMIC_SUB(&GD->statistics.stack_space, size);
1670 tmp_free(mem);
1671 }
1672
1673 size_t
1674 stack_nalloc(size_t req)
1675 { return tmp_nalloc(req);
1676 }
1677
1678 size_t
1679 stack_nrealloc(void *mem, size_t req)
1680 { return tmp_nrealloc(mem, req);
1681 }
1682
1683
1684 /*******************************
1685 * TCMALLOC *
1686 *******************************/
1687
1688 static int (*fMallocExtension_GetNumericProperty)(const char *, size_t *);
1689 static int (*fMallocExtension_SetNumericProperty)(const char *, size_t);
1690 static void (*fMallocExtension_MarkThreadIdle)(void) = NULL;
1691 static void (*fMallocExtension_MarkThreadTemporarilyIdle)(void) = NULL;
1692 static void (*fMallocExtension_MarkThreadBusy)(void) = NULL;
1693
1694 static const char* tcmalloc_properties[] =
1695 { "generic.current_allocated_bytes",
1696 "generic.heap_size",
1697 "tcmalloc.max_total_thread_cache_bytes",
1698 "tcmalloc.current_total_thread_cache_bytes",
1699 "tcmalloc.central_cache_free_bytes",
1700 "tcmalloc.transfer_cache_free_bytes",
1701 "tcmalloc.thread_cache_free_bytes",
1702 "tcmalloc.pageheap_free_bytes",
1703 "tcmalloc.pageheap_unmapped_bytes",
1704 NULL
1705 };
1706
1707 static foreign_t
1708 malloc_property(term_t prop, control_t handle)
1709 { GET_LD
1710 const char **pname;
1711
1712 switch( PL_foreign_control(handle) )
1713 { case PL_FIRST_CALL:
1714 { atom_t name;
1715 size_t arity;
1716
1717 if ( PL_get_name_arity(prop, &name, &arity) && arity == 1 )
1718 { const char *s = PL_atom_nchars(name, NULL);
1719
1720 if ( s )
1721 { pname = tcmalloc_properties;
1722
1723 for(; *pname; pname++)
1724 { if ( streq(s, *pname) )
1725 { size_t val;
1726
1727 if ( fMallocExtension_GetNumericProperty(*pname, &val) )
1728 { term_t a = PL_new_term_ref();
1729 _PL_get_arg(1, prop, a);
1730 return PL_unify_uint64(a, val);
1731 }
1732 }
1733 }
1734 }
1735
1736 return FALSE;
1737 } else if ( PL_is_variable(prop) )
1738 { pname = tcmalloc_properties;
1739 goto enumerate;
1740 }
1741 }
1742 case PL_REDO:
1743 { fid_t fid;
1744
1745 pname = PL_foreign_context_address(handle);
1746 enumerate:
1747
1748 fid = PL_open_foreign_frame();
1749 for(; *pname; pname++)
1750 { size_t val;
1751
1752 if ( fMallocExtension_GetNumericProperty(*pname, &val) )
1753 { if ( PL_unify_term(prop, PL_FUNCTOR_CHARS, *pname, 1,
1754 PL_INT64, val) )
1755 { PL_close_foreign_frame(fid);
1756 pname++;
1757 if ( *pname )
1758 PL_retry_address(pname);
1759 else
1760 return TRUE;
1761 }
1762 }
1763
1764 if ( PL_exception(0) )
1765 return FALSE;
1766 PL_rewind_foreign_frame(fid);
1767 }
1768 PL_close_foreign_frame(fid);
1769
1770 return FALSE;
1771 }
1772 case PL_CUTTED:
1773 { return TRUE;
1774 }
1775 default:
1776 { assert(0);
1777 return FALSE;
1778 }
1779 }
1780 }
1781
1782 static foreign_t
1783 set_malloc(term_t prop)
1784 { GET_LD
1785 atom_t name;
1786 size_t arity;
1787
1788 if ( PL_get_name_arity(prop, &name, &arity) && arity == 1 )
1789 { const char *s = PL_atom_nchars(name, NULL);
1790 term_t a = PL_new_term_ref();
1791 size_t val;
1792
1793 if ( !PL_get_arg(1, prop, a) ||
1794 !PL_get_size_ex(a, &val) )
1795 return FALSE;
1796
1797 if ( s )
1798 { const char **pname = tcmalloc_properties;
1799
1800 for(; *pname; pname++)
1801 { if ( streq(s, *pname) )
1802 { if ( fMallocExtension_SetNumericProperty(*pname, val) )
1803 return TRUE;
1804 else
1805 return PL_permission_error("set", "malloc_property", prop);
1806 }
1807 }
1808
1809 return PL_domain_error("malloc_property", prop);
1810 }
1811 }
1812
1813 return PL_type_error("malloc_property", prop);
1814 }
1815
1816
1817 size_t
1818 heapUsed(void)
1819 { size_t val;
1820
1821 if (fMallocExtension_GetNumericProperty &&
1822 fMallocExtension_GetNumericProperty("generic.current_allocated_bytes", &val))
1823 {
1824 #ifdef MMAP_STACK
1825 val += GD->statistics.stack_space;
1826 #endif
1827
1828 return val;
1829 }
1830
1831 return 0;
1832 }
1833
1834
1835 int
1836 initTCMalloc(void)
1837 { static int done = FALSE;
1838 int set = 0;
1839
1840 if ( done )
1841 return !!fMallocExtension_GetNumericProperty;
1842 done = TRUE;
1843
1844 if ( (fMallocExtension_GetNumericProperty =
1845 PL_dlsym(NULL, "MallocExtension_GetNumericProperty")) )
1846 { PL_register_foreign_in_module("system", "malloc_property", 1, malloc_property,
1847 PL_FA_NONDETERMINISTIC);
1848 set++;
1849 }
1850 if ( (fMallocExtension_SetNumericProperty =
1851 PL_dlsym(NULL, "MallocExtension_SetNumericProperty")) )
1852 { PL_register_foreign_in_module("system", "set_malloc", 1, set_malloc, 0);
1853 set++;
1854 }
1855
1856 fMallocExtension_MarkThreadIdle =
1857 PL_dlsym(NULL, "MallocExtension_MarkThreadIdle");
1858 fMallocExtension_MarkThreadTemporarilyIdle =
1859 PL_dlsym(NULL, "MallocExtension_MarkThreadTemporarilyIdle");
1860 fMallocExtension_MarkThreadBusy =
1861 PL_dlsym(NULL, "MallocExtension_MarkThreadBusy");
1862
1863 return set;
1864 }
1865
1866
1867 /** thread_idle(:Goal, +How)
1868 *
1869 */
1870
1871 static
1872 PRED_IMPL("thread_idle", 2, thread_idle, PL_FA_TRANSPARENT)
1873 { PRED_LD
1874 int rc;
1875 atom_t how;
1876
1877 if ( !PL_get_atom_ex(A2, &how) )
1878 return FALSE;
1879
1880 if ( how == ATOM_short )
1881 { trimStacks(TRUE PASS_LD);
1882 if ( fMallocExtension_MarkThreadTemporarilyIdle &&
1883 fMallocExtension_MarkThreadBusy )
1884 fMallocExtension_MarkThreadTemporarilyIdle();
1885 } else if ( how == ATOM_long )
1886 { LD->trim_stack_requested = TRUE;
1887 garbageCollect(GC_USER);
1888 LD->trim_stack_requested = FALSE;
1889 if ( fMallocExtension_MarkThreadIdle &&
1890 fMallocExtension_MarkThreadBusy )
1891 fMallocExtension_MarkThreadIdle();
1892 }
1893
1894 rc = callProlog(NULL, A1, PL_Q_PASS_EXCEPTION, NULL);
1895
1896 if ( fMallocExtension_MarkThreadBusy )
1897 fMallocExtension_MarkThreadBusy();
1898
1899 return rc;
1900 }
1901
1902
13771903
13781904 /*******************************
13791905 * PREDICATES *
13921918 #ifdef HAVE_BOEHM_GC
13931919 PRED_DEF("garbage_collect_heap", 0, garbage_collect_heap, 0)
13941920 #endif
1921 PRED_DEF("thread_idle", 2, thread_idle, PL_FA_TRANSPARENT)
13951922 EndPredDefs
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2012-2018, VU University Amsterdam
5 Copyright (c) 2012-2020, VU University Amsterdam
66 CWI, Amsterdam
77 All rights reserved.
88
9090 *******************************/
9191
9292 COMMON(void) initAlloc(void);
93 COMMON(int) initTCMalloc(void);
94 COMMON(size_t) heapUsed(void);
9395 #ifndef DMALLOC
9496 COMMON(void *) allocHeap(size_t n);
9597 COMMON(void *) allocHeapOrHalt(size_t n);
118120 COMMON(int) equalIndirect(word r1, word r2);
119121 COMMON(size_t) gsizeIndirectFromCode(Code PC);
120122 COMMON(word) globalIndirectFromCode(Code *PC);
123 COMMON(void *) tmp_malloc(size_t req);
124 COMMON(void *) tmp_realloc(void *mem, size_t req);
125 COMMON(void) tmp_free(void *mem);
126 COMMON(size_t) tmp_nalloc(size_t req);
127 COMMON(size_t) tmp_nrealloc(void *mem, size_t req);
128 COMMON(void *) stack_malloc(size_t req);
129 COMMON(void *) stack_realloc(void *mem, size_t req);
130 COMMON(void) stack_free(void *mem);
131 COMMON(size_t) stack_nalloc(size_t req);
132 COMMON(size_t) stack_nrealloc(void *mem, size_t req);
121133 #ifndef xmalloc
122134 COMMON(void *) xmalloc(size_t size);
123135 COMMON(void *) xrealloc(void *mem, size_t size);
20632063 { exp_nan = FALSE;
20642064 exp_sign = ar_sign_i(n2);
20652065 }
2066 r->type = V_INTEGER; // for all special cases
2066 r->type = V_INTEGER; /* for all special cases */
20672067
20682068 if ( exp_sign == 0 && !exp_nan ) /* test for X**0 */
20692069 { r->value.i = 1;
22142214 if ( mpz_sgn(r->value.mpz) == -1 && !(r_den & 1))
22152215 { mpz_clear(r->value.mpz);
22162216 r->type = V_FLOAT;
2217 r->value.f = NAN;
2217 r->value.f = const_nan;
22182218 return check_float(r);
22192219 }
22202220
22642264 if ( (mpq_sgn(r->value.mpq) == -1 ) && !(r_den & 1))
22652265 { mpq_clear(r->value.mpq);
22662266 r->type = V_FLOAT;
2267 r->value.f = NAN;
2267 r->value.f = const_nan;
22682268 return check_float(r);
22692269 }
22702270
22942294 assert(0);
22952295 }
22962296 case V_FLOAT:
2297 { if ( n1->value.f == 0.0 ) goto doreal; // general case of 0.0**X
2297 { if ( n1->value.f == 0.0 ) goto doreal; /* general case of 0.0**X */
22982298 if ( n1->value.f < 0 && !( r_den & 1 ))
2299 { r->value.f = NAN; /* negative base, even denominator */
2299 { r->value.f = const_nan; /* negative base, even denominator */
23002300 } else
23012301 {
23022302 doreal_mpq:
23322332
23332333 if ( n1->value.f == 0.0 && exp_sign == -1 )
23342334 return check_zero_div(zero_div_sign, r, "**", 2);
2335
2336 r->value.f = pow(n1->value.f, n2->value.f);
2335 if ( n1->value.f == 1.0 )
2336 r->value.f = 1.0; /* broken on e.g., mipsel */
2337 else
2338 r->value.f = pow(n1->value.f, n2->value.f);
23372339 r->type = V_FLOAT;
23382340
23392341 return check_float(r);
27092711 { r->value.f = nexttoward(n1->value.f, n2->value.f);
27102712 r->type = V_FLOAT;
27112713
2712 return TRUE;
2714 return check_float(r);
27132715 }
27142716 }
27152717
37563758
37573759 r->value.f = modf(n1->value.f, &ip);
37583760 r->type = V_FLOAT;
3759 }
3760 }
3761
3762 succeed;
3761 return check_float(r);
3762 }
3763 default:
3764 assert(0);
3765 return FALSE;
3766 }
37633767 }
37643768
37653769
37873791 (void)modf(n1->value.f, &ip);
37883792 r->value.f = ip;
37893793 r->type = V_FLOAT;
3790 succeed;
3794 return check_float(r);
37913795 }
37923796 }
37933797
44344438
44354439 static atom_t float_rounding_names[5] = {0};
44364440
4441 static double
4442 nan15(void)
4443 { number n;
4444 unsigned char *end;
4445
4446 if ( str_number((const unsigned char *)"1.5NaN", &end, &n, 0) == NUM_OK )
4447 { assert(isnan(n.value.f));
4448 return n.value.f;
4449 } else
4450 { assert(0);
4451 return NAN;
4452 }
4453 }
4454
4455
44374456 void
44384457 initArith(void)
44394458 { GET_LD
44434462 fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));
44444463 #endif
44454464
4446 const_nan = strtod("NaN", NULL);
4447 const_inf = strtod("Inf", NULL);
4448 const_neg_inf = strtod("-Inf", NULL);
4465 const_nan = nan15();
4466 const_inf = HUGE_VAL;
4467 const_neg_inf = -HUGE_VAL;
44494468
44504469 #ifdef O_GMP
44514470 LD->arith.rat.max_rational_size = (size_t)-1;
212212 if ( ATOM_REF_COUNT(nref) == 0 )
213213 return TRUE; /* reached max references */
214214
215 if ( COMPARE_AND_SWAP(&a->references, ref, nref) )
215 if ( COMPARE_AND_SWAP_UINT(&a->references, ref, nref) )
216216 { if ( ATOM_REF_COUNT(ref) == 0 )
217217 ATOMIC_DEC(&GD->atoms.unregistered);
218218 return TRUE;
421421 { newblock[i].type = ATOM_TYPE_INVALID;
422422 newblock[i].name = "<virgin>";
423423 }
424 if ( !COMPARE_AND_SWAP(&GD->atoms.array.blocks[idx],
424 if ( !COMPARE_AND_SWAP_PTR(&GD->atoms.array.blocks[idx],
425425 NULL, newblock-bs) )
426426 PL_free(newblock); /* done by someone else */
427427 }
452452 ref = a->references;
453453
454454 if ( ATOM_IS_FREE(ref) &&
455 COMPARE_AND_SWAP(&a->references, ref, ATOM_RESERVED_REFERENCE) )
455 COMPARE_AND_SWAP_UINT(&a->references, ref, ATOM_RESERVED_REFERENCE) )
456456 { assert(a->type == ATOM_TYPE_INVALID);
457457 GD->atoms.no_hole_before = index+1;
458458 a->atom = (index<<LMASK_BITS)|TAG_ATOM;
476476 ref = a->references;
477477
478478 if ( ATOM_IS_FREE(ref) &&
479 COMPARE_AND_SWAP(&a->references, ref, ATOM_RESERVED_REFERENCE) )
480 { COMPARE_AND_SWAP(&GD->atoms.highest, index, index+1);
479 COMPARE_AND_SWAP_UINT(&a->references, ref, ATOM_RESERVED_REFERENCE) )
480 { COMPARE_AND_SWAP_SIZE(&GD->atoms.highest, index, index+1);
481481 a->atom = (index<<LMASK_BITS)|TAG_ATOM;
482482
483483 return a;
610610 if ( true(type, PL_BLOB_UNIQUE) )
611611 { a->next = table[v];
612612 if ( !( !GD->atoms.rehashing && /* See (**) above */
613 COMPARE_AND_SWAP(&table[v], head, a) &&
613 COMPARE_AND_SWAP_PTR(&table[v], head, a) &&
614614 table == GD->atoms.table->table ) )
615615 { if ( false(type, PL_BLOB_NOCOPY) )
616616 PL_free(a->name);
827827 #define ATOM_PRE_DESTROY_REFERENCE \
828828 (ATOM_DESTROY_REFERENCE|ATOM_RESERVED_REFERENCE)
829829
830 if ( !COMPARE_AND_SWAP(&a->references, ref, ATOM_PRE_DESTROY_REFERENCE) )
830 if ( !COMPARE_AND_SWAP_UINT(&a->references, ref, ATOM_PRE_DESTROY_REFERENCE) )
831831 { return FALSE;
832832 }
833833
834834 if ( a->type->release )
835835 { if ( !(*a->type->release)(a->atom) )
836 { COMPARE_AND_SWAP(&a->references, ATOM_PRE_DESTROY_REFERENCE, ref);
836 { COMPARE_AND_SWAP_UINT(&a->references, ATOM_PRE_DESTROY_REFERENCE, ref);
837837 return FALSE;
838838 }
839839 } else if ( GD->atoms.gc_hook )
840840 { if ( !(*GD->atoms.gc_hook)(a->atom) )
841 { COMPARE_AND_SWAP(&a->references, ATOM_PRE_DESTROY_REFERENCE, ref);
841 { COMPARE_AND_SWAP_UINT(&a->references, ATOM_PRE_DESTROY_REFERENCE, ref);
842842 return FALSE; /* foreign hooks says `no' */
843843 }
844844 }
860860 ap = &table->table[a->hash_value & mask];
861861
862862 if ( *ap == a )
863 { if ( !COMPARE_AND_SWAP(&table->table[a->hash_value & mask], a, a->next) )
863 { if ( !COMPARE_AND_SWAP_PTR(&table->table[a->hash_value & mask], a, a->next) )
864864 { goto redo;
865865 }
866866 }
10201020 if ( GD->cleaning != CLN_NORMAL ) /* Cleaning up */
10211021 return TRUE;
10221022
1023 if ( !COMPARE_AND_SWAP(&GD->atoms.gc_active, FALSE, TRUE) )
1023 if ( !COMPARE_AND_SWAP_INT(&GD->atoms.gc_active, FALSE, TRUE) )
10241024 return TRUE;
10251025
10261026 if ( verbose )
11091109 unsigned int nref = ref+1;
11101110
11111111 if ( ATOM_REF_COUNT(nref) != 0 )
1112 { if ( COMPARE_AND_SWAP(&p->references, ref, nref) )
1112 { if ( COMPARE_AND_SWAP_UINT(&p->references, ref, nref) )
11131113 { if ( ATOM_REF_COUNT(nref) == 1 )
11141114 ATOMIC_DEC(&GD->atoms.unregistered);
11151115 return nref;
12081208
12091209 if ( ATOM_REF_COUNT(newref) == 0 )
12101210 newref |= ATOM_MARKED_REFERENCE;
1211 } while( !COMPARE_AND_SWAP(&p->references, oldref, newref) );
1211 } while( !COMPARE_AND_SWAP_UINT(&p->references, oldref, newref) );
12121212 refs = ATOM_REF_COUNT(newref);
12131213 #ifdef O_DEBUG_ATOMGC
12141214 if ( refs == 0 && atomLogFd && tracking(p) )
15051505 size_t index;
15061506 int idx;
15071507
1508 GD->atoms.builtin_array = PL_malloc(size * sizeof(struct atom));
15091508 GD->statistics.atoms = size;
15101509
15111510 for( sp = atoms, index = GD->atoms.highest; *sp; sp++, index++ )
21732172 }
21742173
21752174
2175 size_t
2176 atom_space(void)
2177 { size_t array = ((size_t)2<<MSB(GD->atoms.highest))*sizeof(struct atom);
2178 size_t index;
2179 int i, last=FALSE;
2180 size_t table = GD->atoms.table->buckets * sizeof(Atom);
2181 size_t data = 0;
2182
2183 for(index=1, i=0; !last; i++)
2184 { size_t upto = (size_t)2<<i;
2185 size_t high = GD->atoms.highest;
2186 Atom b = GD->atoms.array.blocks[i];
2187
2188 if ( upto >= high )
2189 { upto = high;
2190 last = TRUE;
2191 }
2192
2193 for(; index<upto; index++)
2194 { Atom a = b + index;
2195
2196 if ( ATOM_IS_VALID(a->references) )
2197 { data += a->length; /* TBD: malloc rounding? */
2198 }
2199 }
2200 }
2201
2202 return array+table+data;
2203 }
2204
2205
21762206 /*******************************
21772207 * PUBLISH PREDICATES *
21782208 *******************************/
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2014, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
5051 findall/3.
5152 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5253
53 #define FIRST_CHUNK_SIZE (64*sizeof(void*))
54 #define FIRST_CHUNK_SIZE (256*sizeof(void*))
5455
5556 typedef struct mem_chunk
5657 { struct mem_chunk *prev;
6061
6162 typedef struct mem_pool
6263 { mem_chunk *chunks;
64 size_t chunk_count;
6365 mem_chunk first;
6466 char first_data[FIRST_CHUNK_SIZE];
6567 } mem_pool;
6668
6769 static void
6870 init_mem_pool(mem_pool *mp)
69 { mp->chunks = &mp->first;
70 mp->first.size = FIRST_CHUNK_SIZE;
71 mp->first.used = 0;
71 { mp->chunks = &mp->first;
72 mp->chunk_count = 1;
73 mp->first.size = FIRST_CHUNK_SIZE;
74 mp->first.used = 0;
7275 }
7376
7477 #define ROUNDUP(n,m) (((n) + (m - 1)) & ~(m-1))
8184 { ptr = &((char *)(mp->chunks+1))[mp->chunks->used];
8285 mp->chunks->used += ROUNDUP(bytes, sizeof(void*));
8386 } else
84 { size_t chunksize = (bytes < 1000 ? 4000 : bytes);
85 mem_chunk *c = PL_malloc_atomic_unmanaged(chunksize+sizeof(mem_chunk));
86
87 if ( c )
88 { c->size = chunksize;
87 { size_t chunksize = tmp_nalloc(4000*((size_t)1<<mp->chunk_count++)+sizeof(mem_chunk));
88 mem_chunk *c;
89
90 if ( bytes > chunksize-sizeof(mem_chunk) )
91 chunksize = tmp_nalloc(bytes+sizeof(mem_chunk));
92
93 if ( (c=tmp_malloc(chunksize)) )
94 { c->size = chunksize-sizeof(mem_chunk);
8995 c->used = ROUNDUP(bytes, sizeof(void*));
9096 c->prev = mp->chunks;
9197 mp->chunks = c;
107113
108114 for(c=mp->chunks; c != &mp->first; c=p)
109115 { p = c->prev;
110 PL_free(c);
111 }
112 mp->chunks = &mp->first;
116 tmp_free(c);
117 }
118 mp->chunk_count = 1;
119 mp->chunks = &mp->first;
120 mp->first.used = 0;
113121 }
114122
115123
512512 PL_meta_predicate(PL_predicate("thread_create", 3, "system"), "0?+");
513513 PL_meta_predicate(PL_predicate("thread_signal", 2, "system"), "+0");
514514 #endif
515 PL_meta_predicate(PL_predicate("thread_idle", 2, "system"), "0+");
515516 PL_meta_predicate(PL_predicate("prolog_frame_attribute", 3, "system"), "++:");
516517 PL_meta_predicate(PL_predicate("compile_predicates", 1, "system"), ":");
517518 PL_meta_predicate(PL_predicate("op", 3, "system"), "++:");
8787 COMMON(int) createUndefSupervisor(Definition def);
8888 COMMON(Code) createSupervisor(Definition def);
8989 COMMON(int) setSupervisor(Definition def);
90 COMMON(size_t) sizeof_supervisor(Code base);
9091 COMMON(size_t) supervisorLength(Code base);
9192 COMMON(void) initSupervisors(void);
9293
107108 #ifdef O_DEBUG_ATOMGC
108109 COMMON(word) pl_track_atom(term_t which, term_t stream);
109110 #endif
111 COMMON(size_t) atom_space(void);
110112
111113 /* pl-bag.c */
112114 COMMON(void) markAtomsFindall(PL_local_data_t *ld);
172174 COMMON(int) checkClauseIndexSizes(Definition def, int nindexable);
173175 COMMON(void) checkClauseIndexes(Definition def);
174176 COMMON(void) listIndexGenerations(Definition def, gen_t gen);
177 COMMON(size_t) sizeofClauseIndexes(Definition def);
175178
176179 /* pl-dwim.c */
177180 COMMON(word) pl_dwim_match(term_t a1, term_t a2, term_t mm);
283286 COMMON(int) checkFunctors(void);
284287 COMMON(word) pl_current_functor(term_t name, term_t arity,
285288 control_t h);
289 COMMON(size_t) functor_space(void);
286290
287291 /* pl-gc.c */
288292 COMMON(int) considerGarbageCollect(Stack s);
515519 COMMON(void) ddi_add_access_gen(DirtyDefInfo ddi, gen_t access);
516520 COMMON(int) ddi_contains_gen(DirtyDefInfo ddi, gen_t access);
517521 COMMON(int) ddi_is_garbage(DirtyDefInfo ddi, gen_t start, Clause cl);
522 COMMON(size_t) sizeof_predicate(Definition def);
518523
519524 /* pl-srcfile.c */
520525
605610 COMMON(int) ensure_room_stack(Stack s, size_t n, int ex);
606611 COMMON(int) trim_stack(Stack s);
607612 COMMON(int) set_stack_limit(size_t limit);
608 COMMON(void *) stack_malloc(size_t size);
609 COMMON(void *) stack_realloc(void *old, size_t size);
610 COMMON(void) stack_free(void *mem);
611613 COMMON(const char *) signal_name(int sig);
612614
613615 /* pl-sys.c */
22 Author: Jan Wielemaker and Keri Harris
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2017, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
160161 f->arity = arity;
161162 f->flags = 0;
162163 f->next = table[v];
163 if ( !( COMPARE_AND_SWAP(&table[v], head, f) &&
164 if ( !( COMPARE_AND_SWAP_PTR(&table[v], head, f) &&
164165 !GD->functors.rehashing &&
165166 table == functorDefTable->table) )
166167 { PL_free(f);
522523 PL_UNLOCK(L_FUNCTOR);
523524 return FALSE;
524525 }
526
527
528 size_t
529 functor_space(void)
530 { size_t size = ((size_t)2<<MSB(GD->functors.highest))*sizeof(FunctorDef);
531
532 size += GD->functors.highest * sizeof(struct functorDef);
533
534 return size;
535 }
51325132 if ( t )
51335133 { void *nw;
51345134
5135 tsize = stack_nrealloc(tb, tsize);
51355136 if ( (nw = stack_realloc(tb, tsize)) )
51365137 { LD->shift_status.trail_shifts++;
51375138 tb = nw;
51505151 olsize = sizeStack(local);
51515152 assert(lb == addPointer(gb, ogsize));
51525153
5154 gsize = stack_nrealloc(gb, lsize + gsize)-lsize;
5155 g = (ogsize != gsize);
5156
51535157 if ( gsize < ogsize ) /* TBD: Only copy life-part */
51545158 memmove(addPointer(gb, gsize), lb, olsize);
51555159
51615165
51625166 gb = nw;
51635167 lb = addPointer(gb, gsize);
5164 if ( gsize > ogsize ) {
5165 size_t copy = olsize;
5166
5167 if ( lsize < olsize ) copy = lsize;
5168 if ( gsize > ogsize )
5169 { size_t copy = olsize;
5170
5171 if ( lsize < olsize )
5172 copy = lsize;
51685173 memmove(lb, addPointer(gb, ogsize), copy);
51695174 }
51705175 } else /* realloc failed; restore */
204204 { size_t highest; /* Highest atom index */
205205 atom_array array;
206206 AtomTable table; /* hash-table */
207 Atom builtin_array; /* Builtin atoms */
208207 int lookups; /* # atom lookups */
209208 int cmps; /* # string compares for lookup */
210209 int initialised; /* atoms have been initialised */
386385 PL_thread_info_t *free; /* Free threads */
387386 int highest_allocated; /* Highest with info struct */
388387 int thread_max; /* Size of threads array */
388 int highest_id; /* Highest Id of life thread */
389 int peak_id; /* Highest Id of any thread */
389390 PL_thread_info_t **threads; /* Pointers to thread-info */
390391 struct
391392 { pthread_mutex_t mutex;
10251025 #define setGenerationFrameVal(f, gen) \
10261026 do { (f)->generation = (gen); } while(0)
10271027 #endif
1028 #ifdef HAVE___SYNC_ADD_AND_FETCH_8
1028 #if defined(HAVE_GCC_ATOMIC_8) || SIZEOF_VOIDP == 8
10291029 typedef uint64_t ggen_t;
10301030 #else
10311031 #define ATOMIC_GENERATION_HACK 1
10331033 { uint32_t gen_l;
10341034 uint32_t gen_u;
10351035 } ggen_t;
1036 #endif /*HAVE___SYNC_ADD_AND_FETCH_8*/
1036 #endif /*HAVE_GCC_ATOMIC_8 || SIZEOF_VOIDP == 8*/
10371037 #else /*O_LOGICAL_UPDATE*/
10381038 #define global_generation() (0)
10391039 #define next_global_generation() (0)
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2018, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
25202520 if ( !clist->args )
25212521 { arg_info *ai = allocHeapOrHalt(ac*sizeof(*ai));
25222522 memset(ai, 0, ac*sizeof(*ai));
2523 if ( !COMPARE_AND_SWAP(&clist->args, NULL, ai) )
2523 if ( !COMPARE_AND_SWAP_PTR(&clist->args, NULL, ai) )
25242524 freeHeap(ai, ac*sizeof(*ai));
25252525 }
25262526
26902690 }
26912691
26922692
2693 size_t
2694 sizeofClauseIndexes(Definition def)
2695 { GET_LD
2696 ClauseIndex *cip;
2697 size_t size = 0;
2698
2699 acquire_def(def);
2700 if ( (cip=def->impl.clauses.clause_indexes) )
2701 { for(; *cip; cip++)
2702 { ClauseIndex ci = *cip;
2703
2704 if ( ISDEADCI(ci) )
2705 continue;
2706 size += sizeofClauseIndex(ci);
2707 }
2708 }
2709
2710 return size;
2711 }
2712
2713
26932714 static int
26942715 unify_clause_index(term_t t, ClauseIndex ci)
26952716 { GET_LD
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2016, VU University Amsterdam
5 Copyright (c) 2016-2020, VU University Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
193194 { indirect *h = reserve_indirect(tab, val PASS_LD);
194195
195196 h->next = buckets->buckets[ki];
196 if ( !COMPARE_AND_SWAP(&buckets->buckets[ki], head, h) ||
197 if ( !COMPARE_AND_SWAP_PTR(&buckets->buckets[ki], head, h) ||
197198 buckets != tab->table )
198199 { PL_free(h->data);
199200 h->references = 0;
216217 static int
217218 bump_ref(indirect *h, unsigned int refs)
218219 { for(;;)
219 { if ( COMPARE_AND_SWAP(&h->references, refs, refs+1) )
220 { if ( COMPARE_AND_SWAP_UINT(&h->references, refs, refs+1) )
220221 { return TRUE;
221222 } else
222223 { refs = h->references;
264265 unsigned int refs = a->references;
265266
266267 if ( INDIRECT_IS_FREE(refs) &&
267 COMPARE_AND_SWAP(&a->references, refs, INDIRECT_RESERVED_REFERENCE) )
268 COMPARE_AND_SWAP_UINT(&a->references, refs, INDIRECT_RESERVED_REFERENCE) )
268269 { tab->no_hole_before = index+1;
269270 return create_indirect(a, index, val PASS_LD);
270271 }
287288 refs = a->references;
288289
289290 if ( INDIRECT_IS_FREE(refs) &&
290 COMPARE_AND_SWAP(&a->references, refs, INDIRECT_RESERVED_REFERENCE) )
291 COMPARE_AND_SWAP_UINT(&a->references, refs, INDIRECT_RESERVED_REFERENCE) )
291292 { ATOMIC_INC(&tab->highest);
292293 return create_indirect(a, index, val PASS_LD);
293294 }
109109 #define MSB64(i) ((int)sizeof(long long)*8-1-__builtin_clzll(i))
110110 #endif
111111
112 #ifdef HAVE__SYNC_SYNCHRONIZE
113 #define MEMORY_BARRIER() __sync_synchronize()
112 #ifdef HAVE_GCC_ATOMIC
113 #define MEMORY_BARRIER() __atomic_thread_fence(__ATOMIC_SEQ_CST)
114114 #endif
115115
116116 #ifdef O_PLMT
117 #define ATOMIC_ADD(ptr, v) __sync_add_and_fetch(ptr, v)
118 #define ATOMIC_SUB(ptr, v) __sync_sub_and_fetch(ptr, v)
119 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
120 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
121 #define ATOMIC_OR(ptr, v) __sync_fetch_and_or(ptr, v)
122 #define ATOMIC_AND(ptr, v) __sync_fetch_and_and(ptr, v)
123 #define COMPARE_AND_SWAP(ptr,o,n) __sync_bool_compare_and_swap(ptr,o,n)
117 #define ATOMIC_ADD(ptr, v) __atomic_add_fetch(ptr, v, __ATOMIC_SEQ_CST)
118 #define ATOMIC_SUB(ptr, v) __atomic_sub_fetch(ptr, v, __ATOMIC_SEQ_CST)
119 #define ATOMIC_INC(ptr) ATOMIC_ADD(ptr, 1) /* ++(*ptr) */
120 #define ATOMIC_DEC(ptr) ATOMIC_SUB(ptr, 1) /* --(*ptr) */
121 #define ATOMIC_OR(ptr, v) __atomic_fetch_or(ptr, v, __ATOMIC_SEQ_CST)
122 #define ATOMIC_AND(ptr, v) __atomic_fetch_and(ptr, v, __ATOMIC_SEQ_CST)
123
124 #define __COMPARE_AND_SWAP(at, from, to) \
125 __atomic_compare_exchange_n(at, &(from), to, FALSE, \
126 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
127
128 static inline int
129 COMPARE_AND_SWAP_PTR(void *at, void *from, void *to)
130 { void **ptr = at;
131
132 return __COMPARE_AND_SWAP(ptr, from, to);
133 }
134
135 static inline int
136 COMPARE_AND_SWAP_INT64(int64_t *at, int64_t from, int64_t to)
137 { return __COMPARE_AND_SWAP(at, from, to);
138 }
139
140 static inline int
141 COMPARE_AND_SWAP_UINT64(uint64_t *at, uint64_t from, uint64_t to)
142 { return __COMPARE_AND_SWAP(at, from, to);
143 }
144
145 static inline int
146 COMPARE_AND_SWAP_INT(int *at, int from, int to)
147 { return __COMPARE_AND_SWAP(at, from, to);
148 }
149
150 static inline int
151 COMPARE_AND_SWAP_UINT(unsigned int *at, unsigned int from, unsigned int to)
152 { return __COMPARE_AND_SWAP(at, from, to);
153 }
154
155 static inline int
156 COMPARE_AND_SWAP_SIZE(size_t *at, size_t from, size_t to)
157 { return __COMPARE_AND_SWAP(at, from, to);
158 }
159
160 static inline int
161 COMPARE_AND_SWAP_WORD(word *at, word from, word to)
162 { return __COMPARE_AND_SWAP(at, from, to);
163 }
164
124165 #else
125166 #define ATOMIC_ADD(ptr, v) (*ptr += v)
126167 #define ATOMIC_SUB(ptr, v) (*ptr -= v)
129170 #define ATOMIC_OR(ptr, v) (*ptr |= v)
130171 #define ATOMIC_AND(ptr, v) (*ptr &= v)
131172 #define COMPARE_AND_SWAP(ptr,o,n) (*ptr == o ? (*ptr = n), 1 : 0)
173 #define COMPARE_AND_SWAP_PTR(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
174 #define COMPARE_AND_SWAP_INT64(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
175 #define COMPARE_AND_SWAP_UINT64(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
176 #define COMPARE_AND_SWAP_INT(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
177 #define COMPARE_AND_SWAP_UINT(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
178 #define COMPARE_AND_SWAP_SIZE(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
179 #define COMPARE_AND_SWAP_WORD(ptr,o,n) COMPARE_AND_SWAP(ptr,o,n)
132180 #endif
133181
134182 #ifndef HAVE_MSB
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2018, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
7474 #ifdef HAVE_DLOPEN /* sysvr4, elf binaries */
7575
7676 #ifdef HAVE_DLFCN_H
77 #define _GNU_SOURCE /* get RTLD_DEFAULT */
7778 #include <dlfcn.h>
7879 #endif
7980
149150
150151 void *
151152 PL_dlsym(void *handle, char *symbol)
152 { return dlsym(handle, symbol);
153 {
154 #ifdef RTLD_DEFAULT
155 if ( !handle )
156 handle = RTLD_DEFAULT;
157 #endif
158 return dlsym(handle, symbol);
153159 }
154160
155161 int
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2012, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
9192 }
9293 #endif
9394
95 /*******************************
96 * TCMALLOC *
97 *******************************/
98
99 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100 If we link the main program against an alternative malloc()
101 implementation we better ensure the main program depends on malloc(),
102 otherwise the linker may still decide to put the alternative malloc
103 library further down in the link dependencies. We should also ensure
104 this dependency is not optimized away.
105 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
106
107 void *_PL_tc_malloc_base;
108
109 static void
110 force_malloc_dependency(void)
111 { _PL_tc_malloc_base = malloc(1);
112 }
94113
95114 /*******************************
96115 * MAIN *
97116 *******************************/
98
99117
100118 int
101119 main(int argc, char **argv)
108126 #if O_ANSI_COLORS
109127 PL_w32_wrap_ansi_console(); /* decode ANSI color sequences (ESC[...m) */
110128 #endif
129
130 force_malloc_dependency();
111131
112132 if ( !PL_initialise(argc, argv) )
113133 PL_halt(1);
12811281 term_t list = PL_copy_term_ref(public);
12821282 int rval = TRUE;
12831283
1284 LOCKMODULE(module);
12851284 for_table(module->public, name, value,
12861285 { if ( !PL_unify_list(list, head, list) ||
12871286 !unify_functor(head, (functor_t)name, GP_NAMEARITY) )
12891288 break;
12901289 }
12911290 })
1292 UNLOCKMODULE(module);
12931291 if ( rval )
12941292 return PL_unify_nil(list);
12951293
12961294 fail;
12971295 }
1296
1297
1298 static size_t
1299 sizeof_module(Module m)
1300 { GET_LD
1301 size_t size = sizeof(*m);
1302
1303 if ( m->public) size += sizeofTable(m->public);
1304 if ( m->procedures) size += sizeofTable(m->procedures);
1305 if ( m->operators) size += sizeofTable(m->operators);
1306
1307 for_table(m->procedures, name, value,
1308 { Procedure proc = value;
1309 Definition def = proc->definition;
1310
1311 size += sizeof(*proc);
1312
1313 if ( def->module == m && false(def, P_FOREIGN) )
1314 { Definition def = getProcDefinition(proc);
1315 size += sizeof_predicate(def);
1316 }
1317 });
1318
1319 return size;
1320 }
1321
12981322
12991323
13001324 static
13291353 { return unify_export_list(a, m PASS_LD);
13301354 } else if ( pname == ATOM_class )
13311355 { return PL_unify_atom(a, m->class);
1356 } else if ( pname == ATOM_size )
1357 { return PL_unify_int64(a, sizeof_module(m));
13321358 } else if ( pname == ATOM_program_size )
13331359 { return PL_unify_int64(a, m->code_size);
13341360 } else if ( pname == ATOM_last_modified_generation )
14861512 if ( proc->definition == old )
14871513 { DEBUG(1, Sdprintf("Patched def of %s\n",
14881514 procedureName(proc)));
1515 shareDefinition(new);
14891516 proc->definition = new;
1517 if ( unshareDefinition(old) == 0 )
1518 lingerDefinition(old);
14901519 }
14911520 });
14921521
16101639
16111640 nproc->flags = pflags;
16121641 nproc->source_no = 0;
1642 shareDefinition(proc->definition);
16131643 nproc->definition = proc->definition;
1614 shareDefinition(proc->definition);
16151644
16161645 LOCKMODULE(destination);
16171646 old = addHTable(destination->procedures,
52135213 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
52145214
52155215 static size_t
5216 heapUsed(void)
5217 {
5218 #ifdef HAVE_BOEHM_GC
5219 return GC_get_heap_size();
5220 #else
5216 programSpace(void)
5217 { size_t allocated = heapUsed();
5218
5219 if ( allocated )
5220 return allocated - GD->statistics.stack_space;
5221
52215222 return 0;
5222 #endif
5223 }
5223 }
5224
52245225
52255226 static size_t
52265227 CStackSize(PL_local_data_t *ld)
53025303 v[1] = roomStack(trail);
53035304 vn = 2;
53045305 } else if ( key == ATOM_program )
5305 { v[0] = heapUsed();
5306 { v[0] = programSpace();
53065307 v[1] = 0;
53075308 vn = 2;
53085309 } else if ( key == ATOM_garbage_collection )
53905391 v->value.i = CStackSize(LD);
53915392 else if (key == ATOM_atoms) /* atoms */
53925393 v->value.i = GD->statistics.atoms;
5394 else if (key == ATOM_atom_space) /* atom_space */
5395 v->value.i = atom_space();
53935396 else if (key == ATOM_functors) /* functors */
53945397 v->value.i = GD->statistics.functors;
5398 else if (key == ATOM_functor_space) /* functor_space */
5399 v->value.i = functor_space();
53955400 else if (key == ATOM_predicates) /* predicates */
53965401 v->value.i = GD->statistics.predicates;
53975402 else if (key == ATOM_clauses) /* clauses */
54195424 v->value.i = GC_get_gc_no();
54205425 #endif
54215426 else if (key == ATOM_heapused) /* heap usage */
5422 v->value.i = heapUsed();
5427 v->value.i = programSpace();
54235428 #ifdef O_ATOMGC
54245429 else if (key == ATOM_agc)
54255430 v->value.i = GD->atoms.gc;
54675472 else if ( key == ATOM_thread_cputime )
54685473 { v->type = V_FLOAT;
54695474 v->value.f = GD->statistics.thread_cputime;
5470 }
5475 } else if ( key == ATOM_threads_peak )
5476 v->value.i = GD->thread.peak_id;
54715477 #endif
54725478 else if (key == ATOM_table_space_used)
54735479 { alloc_pool *pool;
140140 do
141141 { o = m->lingering;
142142 c->next = o;
143 } while( !COMPARE_AND_SWAP(&m->lingering, o, c) );
143 } while( !COMPARE_AND_SWAP_PTR(&m->lingering, o, c) );
144144
145145 DEBUG(MSG_PROC_COUNT, Sdprintf("Linger %s\n", predicateName(def)));
146146 ATOMIC_SUB(&m->code_size, sizeof(*def));
247247 }
248248 } else
249249 { proc = (Procedure) allocHeapOrHalt(sizeof(struct procedure));
250 shareDefinition(def);
250251 proc->definition = def;
251252 proc->flags = flags;
252253 proc->source_no = 0;
253254 addNewHTable(m->procedures, (void *)functor, proc);
254 shareDefinition(def);
255255 }
256256 UNLOCKMODULE(m);
257257
11351135 do
11361136 { o = GD->clauses.lingering;
11371137 cref->d.gnext = o;
1138 } while(!COMPARE_AND_SWAP(&GD->clauses.lingering, o, cref) );
1138 } while(!COMPARE_AND_SWAP_PTR(&GD->clauses.lingering, o, cref) );
11391139
11401140 ATOMIC_INC(&GD->clauses.lingering_count);
11411141 }
11481148 { ClauseRef cref;
11491149
11501150 if ( !(cref = GD->clauses.lingering) ||
1151 !COMPARE_AND_SWAP(&GD->clauses.lingering, cref, NULL) )
1151 !COMPARE_AND_SWAP_PTR(&GD->clauses.lingering, cref, NULL) )
11521152 return; /* no work or someone else doing it */
11531153 GD->clauses.lingering_count = 0;
11541154
11951195 static void
11961196 setLastModifiedPredicate(Definition def, gen_t gen)
11971197 { Module m = def->module;
1198 gen_t lmm;
11981199
11991200 def->last_modified = gen;
1200
1201 #ifdef HAVE___SYNC_ADD_AND_FETCH_8
1202 { gen_t lmm;
12031201
12041202 do
12051203 { lmm = m->last_modified;
12061204 } while ( lmm < gen &&
1207 !COMPARE_AND_SWAP(&m->last_modified, lmm, gen) );
1208 }
1209 #else
1210 LOCKMODULE(m);
1211 if ( m->last_modified < gen )
1212 m->last_modified = gen;
1213 UNLOCKMODULE(m);
1214 #endif
1205 !COMPARE_AND_SWAP_UINT64(&m->last_modified, lmm, gen) );
12151206 }
12161207
12171208
23932384 int rc = TRUE;
23942385
23952386 if ( GD->procedures.dirty->size > 0 &&
2396 COMPARE_AND_SWAP(&GD->clauses.cgc_active, FALSE, TRUE) )
2387 COMPARE_AND_SWAP_INT(&GD->clauses.cgc_active, FALSE, TRUE) )
23972388 { size_t removed = 0;
23982389 size_t erased_pending = GD->clauses.erased_size;
23992390 double gct, t0 = ThreadCPUTime(LD, CPU_USER);
26052596 /* done the job for us. */
26062597 LOCKMODULE(m);
26072598 if ( (odef=proc->definition) != def ) /* Nope, we must link the def */
2608 { proc->definition = def;
2609 shareDefinition(def);
2599 { shareDefinition(def);
2600 proc->definition = def;
26102601
26112602 if ( unshareDefinition(odef) == 0 )
26122603 {
32003191
32013192 static size_t
32023193 num_visible_clauses(Definition def, atom_t key)
3203 { GET_LD;
3194 { GET_LD
32043195
32053196 if ( LD->gen_reload != GEN_INVALID )
32063197 { ClauseRef c;
32223213 return def->impl.clauses.number_of_clauses;
32233214 else
32243215 return def->impl.clauses.number_of_rules;
3216 }
3217
3218
3219 size_t
3220 sizeof_predicate(Definition def)
3221 { GET_LD
3222 size_t size = sizeof(*def);
3223
3224 size += sizeof_supervisor(def->codes);
3225
3226 if ( false(def, P_FOREIGN) )
3227 { ClauseRef c;
3228
3229 acquire_def(def);
3230 for(c = def->impl.clauses.first_clause; c; c = c->next)
3231 { Clause cl = c->value.clause;
3232
3233 size += sizeofClause(cl->code_size);
3234 size += SIZEOF_CREF_CLAUSE;
3235 }
3236 release_def(def);
3237
3238 size += sizeofClauseIndexes(def);
3239 }
3240
3241 return size;
32253242 }
32263243
32273244
33203337 if ( def->impl.clauses.number_of_clauses == 0 && false(def, P_DYNAMIC) )
33213338 fail;
33223339 return PL_unify_integer(value, num_visible_clauses(def, key));
3340 } else if ( key == ATOM_size )
3341 { def = getProcDefinition(proc);
3342 return PL_unify_integer(value, sizeof_predicate(def));
33233343 } else if ( tbl_is_predicate_attribute(key) )
33243344 { size_t sz_value;
33253345
24972497
24982498 static cucharp
24992499 float_tag(cucharp in, cucharp tag)
2500 { while(*in == *tag)
2500 { while(*in && *in == *tag)
25012501 in++, tag++;
25022502
25032503 if ( !*tag )
25042504 { int c;
25052505
2506 utf8_get_uchar(in, &c);
2507 if ( !PlIdContW(c) )
2508 return in;
2506 if ( *in )
2507 { utf8_get_uchar(in, &c);
2508 if ( PlIdContW(c) )
2509 return NULL;
2510 }
2511
2512 return in;
25092513 }
25102514
25112515 return NULL;
25262530
25272531 if ( (s=float_tag(*in, (cucharp)"Inf")) )
25282532 { if ( *start == '-' )
2529 value->value.f = strtod("-Inf", NULL);
2533 value->value.f = -HUGE_VAL;
25302534 else
2531 value->value.f = strtod("Inf", NULL);
2535 value->value.f = HUGE_VAL;
25322536 } else if ( (s=float_tag(*in, (cucharp)"NaN")) &&
25332537 starts_1dot(start) )
25342538 { char *e;
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2007-2013, University of Amsterdam
5 Copyright (c) 2007-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
6061
6162 return TRUE;
6263 } else
63 { segchunk *chunk = PL_malloc(SEGSTACK_CHUNKSIZE);
64 { size_t chunksize = tmp_nalloc((size_t)1024<<stack->chunk_count++);
65 segchunk *chunk = tmp_malloc(chunksize);
6466
6567 if ( !chunk )
6668 return FALSE; /* out of memory */
6769
6870 chunk->allocated = TRUE;
69 chunk->size = SEGSTACK_CHUNKSIZE;
71 chunk->size = chunksize;
7072 chunk->next = NULL;
7173 chunk->previous = stack->last;
7274 chunk->top = CHUNK_DATA(chunk); /* async scanning */
127129 { stack->last = chunk->previous;
128130 stack->last->next = NULL;
129131 if ( chunk->allocated )
130 PL_free(chunk);
132 tmp_free(chunk);
131133
132134 chunk = stack->last;
133135 stack->base = CHUNK_DATA(chunk);
134136 stack->max = addPointer(chunk, chunk->size);
135137 stack->top = chunk->top;
138 stack->chunk_count--;
136139 goto again;
137140 }
138141 }
170173 { if ( chunk->previous )
171174 { segchunk *del = chunk;
172175
176 stack->chunk_count--;
173177 stack->last = chunk->previous;
174178 stack->last->next = NULL;
175179 chunk = stack->last;
179183 stack->max = addPointer(chunk, chunk->size);
180184
181185 if ( del->allocated )
182 PL_free(del);
186 tmp_free(del);
183187
184188 goto again;
185189 }
244248 { segchunk *c = s->first;
245249 segchunk *n;
246250
247 if ( !c->allocated ) /* statically allocated first chunk */
251 if ( !c->allocated ) /* statically allocated first chunk */
248252 { n = c->next;
249253
250254 c->next = NULL;
251255 s->last = c;
252256 s->base = s->top = c->top;
253257 s->max = addPointer(c, c->size);
258 s->chunk_count = 1;
254259
255260 for(c=n; c; c = n)
256261 { n = c->next;
257 PL_free(c);
262 tmp_free(c);
258263 }
259264 } else /* all dynamic chunks */
260265 { for(; c; c = n)
261266 { n = c->next;
262 PL_free(c);
267 tmp_free(c);
263268 }
264269 memset(s, 0, sizeof(*s));
265270 }
3535 #ifndef PL_SEGSTACK_H_INCLUDED
3636 #define PL_SEGSTACK_H_INCLUDED
3737
38 #define SEGSTACK_CHUNKSIZE (1*1024)
39
4038 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4139 The segchunk struct has its data attached to its back. The data field
4240 itself is typed double to ensure that the data is properly aligned to
5957 typedef struct
6058 { size_t unit_size;
6159 /* below clean using memset() */
60 int chunk_count;
6261 segchunk *first;
6362 segchunk *last;
6463 char *base;
169168 assert(len > sizeof(*chunk));
170169 assert(unit_size%sizeof(void*) == 0);
171170 #endif
172 chunk->size = len;
173 stack->base = stack->top = chunk->top = CHUNK_DATA(chunk);
174 stack->last = stack->first = chunk;
175 stack->max = addPointer(chunk, len);
176 chunk->allocated = 0;
177 chunk->next = NULL;
178 chunk->previous = NULL;
171 chunk->size = len;
172 stack->base = stack->top = chunk->top = CHUNK_DATA(chunk);
173 stack->last = stack->first = chunk;
174 stack->max = addPointer(chunk, len);
175 stack->chunk_count = 1;
176 chunk->allocated = 0;
177 chunk->next = NULL;
178 chunk->previous = NULL;
179179 } else
180180 { memset(&stack->first, 0, sizeof(*stack)-offsetof(segstack,first));
181181 }
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2019, University of Amsterdam
5 Copyright (c) 1985-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
123123 initFlags();
124124 DEBUG(1, Sdprintf("Foreign Predicates ...\n"));
125125 initBuildIns();
126 DEBUG(1, Sdprintf("TCMalloc binding ...\n"));
127 initTCMalloc();
126128 DEBUG(1, Sdprintf("Operators ...\n"));
127129 initOperators();
128130 DEBUG(1, Sdprintf("GMP ...\n"));
14331435 size_t iglobal = nextStackSizeAbove(minglobal-1);
14341436 size_t ilocal = nextStackSizeAbove(minlocal-1);
14351437
1438 itrail = stack_nalloc(itrail);
1439 minarg = stack_nalloc(minarg);
1440 iglobal = stack_nalloc(iglobal+ilocal)-ilocal;
1441
14361442 gBase = NULL;
14371443 tBase = NULL;
14381444 aBase = NULL;
14481454 return FALSE;
14491455 }
14501456
1451 lBase = (LocalFrame) addPointer(gBase, iglobal);
1457 lBase = (LocalFrame) addPointer(gBase, iglobal);
14521458
14531459 init_stack((Stack)&LD->stacks.global,
14541460 "global", iglobal, 512*SIZEOF_VOIDP, TRUE);
14831489 aTop = NULL;
14841490 aBase = NULL;
14851491 }
1486 }
1487
1488
1489 void *
1490 stack_malloc(size_t size)
1491 { void *mem = malloc(size+sizeof(size_t));
1492
1493 if ( mem )
1494 { size_t *sp = mem;
1495 *sp++ = size;
1496 #ifdef SECURE_GC
1497 memset(sp, 0xFB, size);
1498 #endif
1499 ATOMIC_ADD(&GD->statistics.stack_space, size);
1500
1501 return sp;
1502 }
1503
1504 return NULL;
1505 }
1506
1507 void *
1508 stack_realloc(void *old, size_t size)
1509 { size_t *sp = old;
1510 size_t osize = *--sp;
1511 void *mem;
1512
1513 #ifdef SECURE_GC
1514 if ( (mem = stack_malloc(size)) )
1515 { memcpy(mem, old, (size>osize?osize:size));
1516 stack_free(old);
1517 return mem;
1518 }
1519 #else
1520 if ( (mem = realloc(sp, size+sizeof(size_t))) )
1521 { sp = mem;
1522 *sp++ = size;
1523 if ( size > osize )
1524 ATOMIC_ADD(&GD->statistics.stack_space, size-osize);
1525 else
1526 ATOMIC_SUB(&GD->statistics.stack_space, osize-size);
1527 return sp;
1528 }
1529 #endif
1530
1531 return NULL;
1532 }
1533
1534 void
1535 stack_free(void *mem)
1536 { size_t *sp = mem;
1537 size_t osize = *--sp;
1538
1539 ATOMIC_SUB(&GD->statistics.stack_space, osize);
1540
1541 #ifdef SECURE_GC
1542 memset(sp, 0xFB, osize+sizeof(size_t));
1543 #endif
1544 free(sp);
15451492 }
15461493
15471494
441441 }
442442 }
443443
444 /* returns 0 for shared static supervisors
445 */
446
447 size_t
448 sizeof_supervisor(Code base)
449 { size_t size = (size_t)base[-1];
450
451 return size*sizeof(code);
452 }
453
444454
445455 /*******************************
446456 * INIT *
164164 #ifdef O_DEBUG
165165 int mytid = PL_thread_self();
166166 assert(mytid == atrie->tid);
167 int rc = COMPARE_AND_SWAP(&atrie->tid, mytid, 0);
167 int rc = COMPARE_AND_SWAP_INT(&atrie->tid, mytid, 0);
168168 assert(rc);
169169 #else
170170 atrie->tid = 0;
175175 take_trie(trie *atrie, int tid)
176176 { assert(atrie->data.worklist != WL_DYNAMIC);
177177 #ifdef O_DEBUG
178 int rc = COMPARE_AND_SWAP(&atrie->tid, 0, tid);
178 int rc = COMPARE_AND_SWAP_INT(&atrie->tid, 0, tid);
179179 assert(rc);
180180 #else
181181 atrie->tid = tid;
20662066 if ( !(pool = GD->tabling.node_pool) )
20672067 { if ( (pool = new_alloc_pool("shared_table_space",
20682068 GD->options.sharedTableSpace)) )
2069 { if ( !COMPARE_AND_SWAP(&GD->tabling.node_pool, NULL, pool) )
2069 { if ( !COMPARE_AND_SWAP_PTR(&GD->tabling.node_pool, NULL, pool) )
20702070 { free_alloc_pool(pool);
20712071 pool = GD->tabling.node_pool;
20722072 }
20942094 t->release_node = release_variant_table_node;
20952095 symb = trie_symbol(t);
20962096
2097 if ( COMPARE_AND_SWAP(tp, NULL, t) )
2097 if ( COMPARE_AND_SWAP_PTR(tp, NULL, t) )
20982098 { if ( shared )
20992099 { set(t, TRIE_ISSHARED);
21002100 acquire_trie(t); /* bit misuse */
22992299 #ifdef O_PLMT
23002300 if ( shared )
23012301 { set(atrie, TRIE_ISSHARED);
2302 if ( COMPARE_AND_SWAP(&node->value, 0, symb) )
2302 if ( COMPARE_AND_SWAP_WORD(&node->value, 0, symb) )
23032303 { set(node, TN_PRIMARY);
23042304 ATOMIC_INC(&variants->value_count);
23052305 } else
53505350 if ( !(t=child->affected) )
53515351 { t = newHTable(4);
53525352 t->free_symbol = idg_free_affected;
5353 if ( !COMPARE_AND_SWAP(&child->affected, NULL, t) )
5353 if ( !COMPARE_AND_SWAP_PTR(&child->affected, NULL, t) )
53545354 destroyHTable(t);
53555355 }
53565356 addHTable(t, parent, child);
53585358 if ( !(t=parent->dependent) )
53595359 { t = newHTable(4);
53605360 t->free_symbol = idg_free_dependent;
5361 if ( !COMPARE_AND_SWAP(&parent->dependent, NULL, t) )
5361 if ( !COMPARE_AND_SWAP_PTR(&parent->dependent, NULL, t) )
53625362 destroyHTable(t);
53635363 }
53645364 addHTable(t, child, parent);
53825382 if ( true(def, P_INCREMENTAL) )
53835383 { idg_node *n = idg_new(atrie);
53845384
5385 if ( !COMPARE_AND_SWAP(&atrie->data.IDG, NULL, n) )
5385 if ( !COMPARE_AND_SWAP_PTR(&atrie->data.IDG, NULL, n) )
53865386 idg_destroy(n);
53875387 }
53885388 }
55215521 assert(!atrie->data.worklist || atrie->data.worklist == WL_GROUND);
55225522 atrie->data.worklist = WL_DYNAMIC;
55235523 n = idg_new(atrie);
5524 if ( !COMPARE_AND_SWAP(&atrie->data.IDG, NULL, n) )
5524 if ( !COMPARE_AND_SWAP_PTR(&atrie->data.IDG, NULL, n) )
55255525 idg_destroy(n);
55265526 }
55275527
62536253 { p = allocHeapOrHalt(sizeof(*p));
62546254
62556255 clear_table_props(p);
6256 if ( !COMPARE_AND_SWAP(&def->tabling, NULL, p) )
6256 if ( !COMPARE_AND_SWAP_PTR(&def->tabling, NULL, p) )
62576257 { p = def->tabling;
62586258 freeHeap(p, sizeof(*p));
62596259 }
65866586
65876587 if ( !(ta=GD->tabling.waiting) )
65886588 { ta = new_trie_array();
6589 if ( !COMPARE_AND_SWAP(&GD->tabling.waiting, NULL, ta) )
6589 if ( !COMPARE_AND_SWAP_PTR(&GD->tabling.waiting, NULL, ta) )
65906590 { freeHeap(ta, sizeof(*ta));
65916591 ta = GD->tabling.waiting;
65926592 }
66016601 outOfCore();
66026602
66036603 memset(newblock, 0, bs*sizeof(trie*));
6604 if ( !COMPARE_AND_SWAP(&ta->blocks[idx], NULL, newblock-bs) )
6604 if ( !COMPARE_AND_SWAP_PTR(&ta->blocks[idx], NULL, newblock-bs) )
66056605 PL_free(newblock);
66066606 }
66076607 }
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1999-2019, University of Amsterdam,
5 Copyright (c) 1999-2020, University of Amsterdam,
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
237237 *******************************/
238238
239239 static Table threadTable; /* name --> reference symbol */
240 static int thread_highest_id; /* Highest handed thread-id */
241240 static int threads_ready = FALSE; /* Prolog threads available */
242241 static Table queueTable; /* name --> queue */
243242 static simpleMutex queueTable_mutex; /* GC synchronization */
446445 static void destroy_message_queue(message_queue *queue);
447446 static void destroy_thread_message_queue(message_queue *queue);
448447 static void init_message_queue(message_queue *queue, size_t max_size);
448 static size_t sizeof_message_queue(message_queue *queue);
449 static size_t sizeof_local_definitions(PL_local_data_t *ld);
449450 static void freeThreadSignals(PL_local_data_t *ld);
450451 static thread_handle *create_thread_handle(PL_thread_info_t *info);
451452 static void free_thread_info(PL_thread_info_t *info);
633634 rc2 = callEventHook(PLEV_THREAD_EXIT, info);
634635 if ( (!rc1 || !rc2) && exception_term )
635636 { Sdprintf("Event hook \"thread_finished\" left an exception\n");
636 PL_write_term(Serror, exception_term, 1200, PL_WRT_QUOTED|PL_WRT_NEWLINE);
637 PL_write_term(Serror, exception_term, 1200,
638 PL_WRT_QUOTED|PL_WRT_NEWLINE);
637639 PL_clear_exception();
638640 }
639641 info->in_exit_hooks = FALSE;
775777 }
776778 set_system_thread_id(info);
777779
778 for(i=2; i<=thread_highest_id; i++)
780 for(i=2; i<=GD->thread.highest_id; i++)
779781 { if ( (info=GD->thread.threads[i]) )
780782 { if ( info->status != PL_THREAD_UNUSED )
781783 { freePrologThread(info->thread_data, TRUE);
783785 }
784786 }
785787 }
786 thread_highest_id = 1;
788 GD->thread.highest_id = 1;
787789
788790 GD->statistics.thread_cputime = 0.0;
789791 GD->statistics.threads_created = 1;
863865 memset(info, 0, sizeof(*info));
864866 info->pl_tid = 1;
865867 info->debug = TRUE;
866 thread_highest_id = 1;
868 GD->thread.highest_id = 1;
867869 info->thread_data = &PL_local_data;
868870 info->status = PL_THREAD_RUNNING;
869871 PL_local_data.thread.info = info;
945947
946948 sem_init(sem_canceled_ptr, USYNC_THREAD, 0);
947949
948 for(i=1; i<= thread_highest_id; i++)
950 for(i=1; i<= GD->thread.highest_id; i++)
949951 { PL_thread_info_t *info = GD->thread.threads[i];
950952
951953 if ( info && info->thread_data && i != me )
10161018 term_t tail = PL_copy_term_ref(running);
10171019
10181020 rc = TRUE;
1019 for(i = 1; i <= thread_highest_id; i++)
1021 for(i = 1; i <= GD->thread.highest_id; i++)
10201022 { PL_thread_info_t *info = GD->thread.threads[i];
10211023
10221024 if ( info && info->thread_data && i != me )
11141116
11151117 if ( tid == 0 )
11161118 tid = PL_thread_self();
1117 if ( tid < 1 || tid > thread_highest_id )
1119 if ( tid < 1 || tid > GD->thread.highest_id )
11181120 return FALSE;
11191121
11201122 info = GD->thread.threads[tid];
12011203
12021204 do
12031205 { h = gced_threads;
1204 } while ( h && !COMPARE_AND_SWAP(&gced_threads, h, h->next_free) );
1206 } while ( h && !COMPARE_AND_SWAP_PTR(&gced_threads, h, h->next_free) );
12051207
12061208 if ( h )
12071209 { if ( GD->cleaning == CLN_NORMAL )
12441246 do
12451247 { h = gced_threads;
12461248 ref->next_free = h;
1247 } while( !COMPARE_AND_SWAP(&gced_threads, h, ref) );
1249 } while( !COMPARE_AND_SWAP_PTR(&gced_threads, h, ref) );
12481250
12491251 start_thread_gc_thread();
12501252 }
13571359
13581360 do
13591361 { info = GD->thread.free;
1360 } while ( info && !COMPARE_AND_SWAP(&GD->thread.free, info, info->next_free) );
1362 } while ( info && !COMPARE_AND_SWAP_PTR(&GD->thread.free, info, info->next_free) );
13611363
13621364 if ( info )
13631365 { int i = info->pl_tid;
13741376 i = info->pl_tid = ++GD->thread.highest_allocated;
13751377 if ( i == GD->thread.thread_max )
13761378 resizeThreadMax();
1379 if ( i > GD->thread.peak_id )
1380 GD->thread.peak_id = i;
13771381
13781382 assert(GD->thread.threads[i] == NULL);
13791383 GD->thread.threads[i] = info;
13901394 info->debug = TRUE;
13911395
13921396 do
1393 { mx = thread_highest_id;
1397 { mx = GD->thread.highest_id;
13941398 } while ( info->pl_tid > mx &&
1395 !COMPARE_AND_SWAP(&thread_highest_id, mx, info->pl_tid) );
1399 !COMPARE_AND_SWAP_INT(&GD->thread.highest_id, mx, info->pl_tid) );
13961400
13971401 ATOMIC_INC(&GD->statistics.threads_created);
13981402
14161420 int
14171421 PL_unify_thread_id(term_t t, int i)
14181422 { if ( i < 1 ||
1419 i > thread_highest_id ||
1423 i > GD->thread.highest_id ||
14201424 GD->thread.threads[i]->status == PL_THREAD_UNUSED ||
14211425 GD->thread.threads[i]->status == PL_THREAD_RESERVED )
14221426 return -1; /* error */
14561460 return FALSE; /* illegal signal */
14571461
14581462 PL_LOCK(L_THREAD);
1459 for(i = 1; i <= thread_highest_id; i++)
1463 for(i = 1; i <= GD->thread.highest_id; i++)
14601464 { PL_thread_info_t *info = GD->thread.threads[i];
14611465
14621466 if ( info && info->w32id == id && info->thread_data )
15101514
15111515 int
15121516 PL_thread_raise(int tid, int sig)
1513 { if ( tid >= 1 && tid <= thread_highest_id )
1517 { if ( tid >= 1 && tid <= GD->thread.highest_id )
15141518 { PL_thread_info_t *info = GD->thread.threads[tid];
15151519
15161520 if ( info &&
15701574
15711575 for( ; mask ; mask <<= 1, sig++ )
15721576 { if ( LD->signal.pending[i] & mask )
1573 { __sync_and_and_fetch(&LD->signal.pending[i], ~mask);
1577 { __atomic_and_fetch(&LD->signal.pending[i], ~mask, __ATOMIC_SEQ_CST);
15741578
15751579 if ( sig == SIG_THREAD_SIGNAL )
15761580 { dispatch_signal(sig, TRUE);
21502154 }
21512155
21522156 if ( i < 1 ||
2153 i > thread_highest_id ||
2157 i > GD->thread.highest_id ||
21542158 THREAD_STATUS_INVALID(GD->thread.threads[i]->status) )
21552159 { goto no_thread;
21562160 }
23482352 info->goal = NULL;
23492353 PL_UNLOCK(L_THREAD);
23502354
2351 if ( info->pl_tid == thread_highest_id )
2355 if ( info->pl_tid == GD->thread.highest_id )
23522356 { int i;
23532357
23542358 for(i=info->pl_tid-1; i>1; i--)
23582362 }
23592363
23602364 /* do not update if alloc_thread() did */
2361 COMPARE_AND_SWAP(&thread_highest_id, info->pl_tid, i);
2365 COMPARE_AND_SWAP_INT(&GD->thread.highest_id, info->pl_tid, i);
23622366 }
23632367
23642368 do
23652369 { freelist = GD->thread.free;
23662370 info->next_free = freelist;
2367 } while( !COMPARE_AND_SWAP(&GD->thread.free, freelist, info) );
2371 } while( !COMPARE_AND_SWAP_PTR(&GD->thread.free, freelist, info) );
23682372
23692373 if ( rec_rv ) PL_erase(rec_rv);
23702374 if ( rec_g ) PL_erase(rec_g);
24372441
24382442 status = info->status;
24392443 if ( !THREAD_STATUS_INVALID(status) &&
2440 COMPARE_AND_SWAP(&info->status, status, PL_THREAD_JOINED) )
2444 COMPARE_AND_SWAP_INT((int*)&info->status, (int)status, (int)PL_THREAD_JOINED) )
24412445 { rval = unify_thread_status(retcode, info, status, FALSE);
24422446
24432447 free_thread_info(info);
25212525 }
25222526
25232527
2528 static size_t
2529 sizeof_thread(PL_thread_info_t *info)
2530 { size_t size = sizeof(*info);
2531 struct PL_local_data *ld = info->thread_data;
2532
2533 if ( info->status != PL_THREAD_RUNNING )
2534 return 0;
2535
2536 if ( ld )
2537 { size += sizeof(*ld);
2538 size += sizeStackP(&ld->stacks.global) + ld->stacks.global.spare;
2539 size += sizeStackP(&ld->stacks.local) + ld->stacks.local.spare;
2540 size += sizeStackP(&ld->stacks.trail) + ld->stacks.trail.spare;
2541 size += sizeStackP(&ld->stacks.argument);
2542
2543 size += sizeof_message_queue(&ld->thread.messages);
2544 size += sizeof_local_definitions(ld);
2545
2546 if ( ld->tabling.node_pool )
2547 size += ld->tabling.node_pool->size;
2548 }
2549
2550 return size;
2551 }
2552
2553
25242554 /*******************************
25252555 * THREAD PROPERTY *
25262556 *******************************/
26042634 if ( tid != -1 )
26052635 return PL_unify_integer(prop, system_thread_id(info));
26062636 }
2637
2638 return FALSE;
2639 }
2640
2641 static int
2642 thread_size_propery(PL_thread_info_t *info, term_t prop ARG_LD)
2643 { size_t size;
2644
2645 PL_LOCK(L_THREAD);
2646 size = sizeof_thread(info);
2647 PL_UNLOCK(L_THREAD);
2648
2649 if ( size )
2650 return PL_unify_int64(prop, size);
26072651
26082652 return FALSE;
26092653 }
26172661 { FUNCTOR_engine1, thread_engine_propery },
26182662 { FUNCTOR_thread1, thread_thread_propery },
26192663 { FUNCTOR_system_thread_id1, thread_tid_propery },
2664 { FUNCTOR_size1, thread_size_propery },
26202665 { 0, NULL }
26212666 };
26222667
26412686 if ( state->enum_threads )
26422687 { do
26432688 { state->tid++;
2644 if ( state->tid > thread_highest_id )
2689 if ( state->tid > GD->thread.highest_id )
26452690 fail;
26462691 } while ( GD->thread.threads[state->tid]->status == PL_THREAD_UNUSED ||
26472692 GD->thread.threads[state->tid]->status == PL_THREAD_RESERVED );
40634108 if ( queue->max_size != 0 )
40644109 cv_init(&queue->drain_var, NULL);
40654110 queue->initialized = TRUE;
4111 }
4112
4113
4114 static size_t
4115 sizeof_message_queue(message_queue *queue)
4116 { size_t size = 0;
4117 thread_message *msgp;
4118
4119 simpleMutexLock(&queue->gc_mutex);
4120 for( msgp = queue->head; msgp; msgp = msgp->next )
4121 { size += sizeof(*msgp);
4122 size += msgp->message->size;
4123 }
4124 simpleMutexUnlock(&queue->gc_mutex);
4125
4126 return size;
40664127 }
40674128
40684129 /* Prolog predicates */
44464507
44474508 if ( tid > 0 )
44484509 { have_tid:
4449 if ( tid >= 1 && tid <= thread_highest_id )
4510 if ( tid >= 1 && tid <= GD->thread.highest_id )
44504511 { PL_thread_info_t *info = GD->thread.threads[tid];
44514512
44524513 if ( info->status == PL_THREAD_UNUSED ||
54105471 static int
54115472 GCthread(void)
54125473 { if ( GC_id <= 0 )
5413 { if ( COMPARE_AND_SWAP(&GC_starting, FALSE, TRUE) )
5474 { if ( COMPARE_AND_SWAP_INT(&GC_starting, FALSE, TRUE) )
54145475 { pthread_attr_t attr;
54155476 pthread_t thr;
54165477 int rc;
60306091 int me = PL_thread_self();
60316092 int i;
60326093
6033 for( i=1; i<=thread_highest_id; i++ )
6094 for( i=1; i<=GD->thread.highest_id; i++ )
60346095 { if ( i != me )
60356096 { PL_thread_info_t *info = GD->thread.threads[i];
60366097
63016362 }
63026363
63036364
6365 static size_t
6366 sizeof_local_definitions(PL_local_data_t *ld)
6367 { DefinitionChain ch = ld->thread.local_definitions;
6368 size_t size = 0;
6369
6370 for( ; ch; ch = ch->next)
6371 size += sizeof_predicate(ch->definition);
6372
6373 return size;
6374 }
6375
6376
6377
63046378 /** '$thread_local_clause_count'(:Head, +Thread, -NumberOfClauses) is semidet.
63056379
63066380 True when NumberOfClauses is the number of clauses for the thread-local
64986572 #ifdef O_PLMT
64996573 int i;
65006574
6501 for(i=1; i<=thread_highest_id; i++)
6575 for(i=1; i<=GD->thread.highest_id; i++)
65026576 { PL_thread_info_t *info = GD->thread.threads[i];
65036577 PL_local_data_t *ld = acquire_ldata(info);
65046578
65366610 #ifdef O_PLMT
65376611 int i;
65386612
6539 for(i=1; i<=thread_highest_id; i++)
6613 for(i=1; i<=GD->thread.highest_id; i++)
65406614 { PL_thread_info_t *info = GD->thread.threads[i];
65416615 if ( info && info->access.kvs == kvs )
65426616 { return TRUE;
65586632 #ifdef O_PLMT
65596633 int i;
65606634
6561 for(i=1; i<=thread_highest_id; i++)
6635 for(i=1; i<=GD->thread.highest_id; i++)
65626636 { PL_thread_info_t *info = GD->thread.threads[i];
65636637 if ( info && info->access.atom_table == atom_table )
65646638 { return TRUE;
65766650 #ifdef O_PLMT
65776651 int i;
65786652
6579 for(i=1; i<=thread_highest_id; i++)
6653 for(i=1; i<=GD->thread.highest_id; i++)
65806654 { PL_thread_info_t *info = GD->thread.threads[i];
65816655 if ( info && info->access.atom_bucket == bucket )
65826656 { return TRUE;
65936667 ldata_in_use(PL_local_data_t *ld)
65946668 { int i;
65956669
6596 for(i=1; i<=thread_highest_id; i++)
6670 for(i=1; i<=GD->thread.highest_id; i++)
65976671 { PL_thread_info_t *info = GD->thread.threads[i];
65986672 if ( info && info->access.ldata == ld )
65996673 { return TRUE;
66156689 Atom **buckets = allocHeapOrHalt(sz * sizeof(Atom*));
66166690 memset(buckets, 0, sz * sizeof(Atom*));
66176691
6618 for(i=1; i<=thread_highest_id; i++)
6692 for(i=1; i<=GD->thread.highest_id; i++)
66196693 { PL_thread_info_t *info = GD->thread.threads[i];
66206694 if ( info && info->access.atom_bucket )
66216695 { if ( index >= sz-1 )
66536727 Definition *buckets = allocHeapOrHalt(sz * sizeof(Definition));
66546728 memset(buckets, 0, sz * sizeof(Definition*));
66556729
6656 for(i=1; i<=thread_highest_id; i++)
6730 for(i=1; i<=GD->thread.highest_id; i++)
66576731 { PL_thread_info_t *info = GD->thread.threads[i];
66586732 if ( info && info->access.predicate )
66596733 { if ( index >= sz-1 )
66926766 int me = PL_thread_self();
66936767 int i;
66946768
6695 for(i=1; i<=thread_highest_id; i++)
6769 for(i=1; i<=GD->thread.highest_id; i++)
66966770 { PL_thread_info_t *info = GD->thread.threads[i];
66976771 if ( i != me && info && info->access.functor_table == functor_table )
66986772 { return TRUE;
67616835 outOfCore();
67626836
67636837 memset(newblock, 0, bs*sizeof(definition_ref));
6764 if ( !COMPARE_AND_SWAP(&refs->blocks[idx], NULL, newblock-bs) )
6838 if ( !COMPARE_AND_SWAP_PTR(&refs->blocks[idx], NULL, newblock-bs) )
67656839 PL_free(newblock);
67666840 }
67676841
212212 { atom_t dbref;
213213
214214 if ( (dbref=trie->clause) )
215 { if ( COMPARE_AND_SWAP(&trie->clause, dbref, 0) &&
215 { if ( COMPARE_AND_SWAP_WORD(&trie->clause, dbref, 0) &&
216216 GD->cleaning == CLN_NORMAL ) /* otherwise reclaims clause */
217217 { ClauseRef cref = clause_clref(dbref); /* from two ends */
218218
235235 { indirect_table *it = trie->indirects;
236236
237237 clear_node(trie, &trie->root, FALSE); /* TBD: verify not accessed */
238 if ( it && COMPARE_AND_SWAP(&trie->indirects, it, NULL) )
238 if ( it && COMPARE_AND_SWAP_PTR(&trie->indirects, it, NULL) )
239239 destroy_indirect_table(it);
240240 trie->node_count = 1;
241241 trie->value_count = 0;
366366 if ( children.any )
367367 { switch( children.any->type )
368368 { case TN_KEY:
369 if ( COMPARE_AND_SWAP(&p->children.any, children.any, NULL) )
369 if ( COMPARE_AND_SWAP_PTR(&p->children.any, children.any, NULL) )
370370 PL_free(children.any);
371371 break;
372372 case TN_HASHED:
445445 if ( children.any )
446446 { switch( children.any->type )
447447 { case TN_KEY:
448 if ( COMPARE_AND_SWAP(&p->children.any, children.any, NULL) )
448 if ( COMPARE_AND_SWAP_PTR(&p->children.any, children.any, NULL) )
449449 PL_free(children.any);
450450 break;
451451 case TN_HASHED:
548548 update_var_mask(hnode, new->key);
549549 new->parent = n;
550550
551 if ( COMPARE_AND_SWAP(&n->children.hash, children.hash, hnode) )
551 if ( COMPARE_AND_SWAP_PTR(&n->children.hash, children.hash, hnode) )
552552 { hnode->old_single = children.key; /* See (*) */
553553 return new;
554554 } else
587587 child->key = key;
588588 child->child = new;
589589
590 if ( COMPARE_AND_SWAP(&n->children.key, NULL, child) )
590 if ( COMPARE_AND_SWAP_PTR(&n->children.key, NULL, child) )
591591 { child->child->parent = n;
592592 return child->child;
593593 }
620620 } else if ( add )
621621 { indirect_table *newtab = new_indirect_table();
622622
623 if ( !COMPARE_AND_SWAP(&trie->indirects, NULL, newtab) )
623 if ( !COMPARE_AND_SWAP_PTR(&trie->indirects, NULL, newtab) )
624624 destroy_indirect_table(newtab);
625625 } else
626626 { return 0;
23402340 } else if ( name == ATOM_reevaluated && (idg=trie->data.IDG))
23412341 { return PL_unify_int64(arg, idg->stats.reevaluated);
23422342 #endif
2343 } else if ( (idg=trie->data.IDG) )
2344 { if ( name == ATOM_idg_affected_count )
2345 { return PL_unify_int64(arg, idg->affected ? idg->affected->size : 0);
2346 } else if ( name == ATOM_idg_dependent_count )
2347 { return PL_unify_int64(arg, idg->dependent ? idg->dependent->size : 0);
2348 } else if ( name == ATOM_idg_size )
2349 { size_t size = sizeof(*idg);
2350
2351 if ( idg->affected ) size += sizeofTable(idg->affected);
2352 if ( idg->dependent ) size += sizeofTable(idg->dependent);
2353
2354 return PL_unify_int64(arg, size);
2355 }
23432356 }
23442357 }
23452358 }
28532866 if ( !(dbref = trie->clause) )
28542867 { if ( trie->value_count == 0 )
28552868 { dbref = ATOM_fail;
2856 if ( !COMPARE_AND_SWAP(&trie->clause, 0, dbref) )
2869 if ( !COMPARE_AND_SWAP_WORD(&trie->clause, 0, dbref) )
28572870 goto retry;
28582871 } else
28592872 { trie_compile_state state;
28672880 { cref = assertDefinition(def, cl, CL_END PASS_LD);
28682881 if ( cref )
28692882 { dbref = lookup_clref(cref->value.clause);
2870 if ( !COMPARE_AND_SWAP(&trie->clause, 0, dbref) )
2883 if ( !COMPARE_AND_SWAP_WORD(&trie->clause, 0, dbref) )
28712884 { PL_unregister_atom(dbref);
28722885 retractClauseDefinition(def, cref->value.clause);
28732886 goto retry;
302302
303303 do
304304 { alerted = ld->alerted;
305 } while ( !COMPARE_AND_SWAP(&ld->alerted, alerted, alerted|ALERT_SIGNAL) );
305 } while ( !COMPARE_AND_SWAP_INT(&ld->alerted, alerted, alerted|ALERT_SIGNAL) );
306306
307307 return TRUE;
308308 }
13951395 outOfCore();
13961396
13971397 memset(newblock, 0, bs*sizeof(Definition));
1398 if ( !COMPARE_AND_SWAP(&v->blocks[idx], NULL, newblock-bs) )
1398 if ( !COMPARE_AND_SWAP_PTR(&v->blocks[idx], NULL, newblock-bs) )
13991399 PL_free(newblock);
14001400 }
14011401 }
339339
340340 static bool
341341 Putc(int c, IOSTREAM *s)
342 { return Sputcode(c, s) == EOF ? FALSE : TRUE;
342 { return Sputcode(c, s) != EOF;
343343 }
344344
345345
814814 writeString(term_t t, write_options *options)
815815 { GET_LD
816816 PL_chars_t txt;
817 int rc = TRUE;
817818
818819 PL_get_text(t, &txt, CVT_STRING);
820 if ( txt.storage != PL_CHARS_LOCAL )
821 PL_save_text(&txt, BUF_MALLOC);
819822
820823 if ( true(options, PL_WRT_QUOTED) )
821824 { int quote;
826829 else
827830 quote = '"';
828831
829 TRY(Putc(quote, options->out));
832 if ( !(rc=Putc(quote, options->out)) )
833 goto out;
830834
831835 for(i=0; i<txt.length; i++)
832836 { int chr = get_chr_from_text(&txt, i);
833837
834 TRY(putQuoted(chr, quote, options->flags, options->out));
835 }
836
837 return Putc(quote, options->out);
838 if ( !(rc=putQuoted(chr, quote, options->flags, options->out)) )
839 goto out;
840 }
841
842 rc = Putc(quote, options->out);
838843 } else
839844 { unsigned int i;
840845
841846 for(i=0; i<txt.length; i++)
842847 { int chr = get_chr_from_text(&txt, i);
843848
844 TRY(Putc(chr, options->out));
845 }
846 }
847
848 succeed;
849 if ( !(rc=Putc(chr, options->out)) )
850 break;
851 }
852 }
853
854 out:
855 PL_free_text(&txt);
856
857 return rc;
849858 }
850859
851860 #endif /*O_STRING*/
29172917
29182918 run_pkg_test1(Script, Goal, PkgDir) :-
29192919 current_prolog_flag(executable, SWIPL),
2920 working_directory(CWD, CWD),
2921 format(atom(POpt), 'test_tmp_dir=~w', [CWD]),
29202922 process_create(SWIPL,
29212923 [ '-f', 'none',
29222924 '-t', 'halt',
2925 '--no-packs',
2926 '-p', POpt,
29232927 '-g', Goal,
29242928 Script
29252929 ],