diff options
117 files changed, 1798 insertions, 1304 deletions
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 1e8342c..4a03b7a 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -54,6 +54,7 @@ All Modules /module/CMakePrintSystemInformation /module/CMakePushCheckState /module/CMakeVerifyManifest + /module/CPackArchive /module/CPackBundle /module/CPackComponent /module/CPackCygwin diff --git a/Help/module/CPackArchive.rst b/Help/module/CPackArchive.rst new file mode 100644 index 0000000..eb8d9d2 --- /dev/null +++ b/Help/module/CPackArchive.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CPackArchive.cmake diff --git a/Help/release/dev/ExtractGTestMacro.rst b/Help/release/dev/ExtractGTestMacro.rst index 574982c..ff2b444 100644 --- a/Help/release/dev/ExtractGTestMacro.rst +++ b/Help/release/dev/ExtractGTestMacro.rst @@ -2,4 +2,8 @@ ExtractGTestMacro ----------------- * A new :module:`GoogleTest` module was added to provide the - ``gtest_add_tests`` macro independently of the :module:`FindGTest` module. + :command:`gtest_add_tests` function independently of the :module:`FindGTest` + module. The function was also updated to support keyword arguments, with + functionality expanded to allow a test name prefix and suffix to be + specified, the dependency on the source files to be optional and the list of + discovered test cases to be returned to the caller. diff --git a/Help/release/dev/cpack-archive-per-component-filename.rst b/Help/release/dev/cpack-archive-per-component-filename.rst new file mode 100644 index 0000000..a7a413f --- /dev/null +++ b/Help/release/dev/cpack-archive-per-component-filename.rst @@ -0,0 +1,6 @@ +cpack-rpm-debuginfo-honor-package-filename +------------------------------------------ + +* The :module:`CPackArchive` module learned to modify filename per component. + See :variable:`CPACK_ARCHIVE_FILE_NAME` variable and its per component + version. diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 7ca79bd..f2d43b6 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -95,13 +95,13 @@ function(compiler_id_detection outvar lang) if(CID_ID_DEFINE) foreach(Id ${ordered_compilers}) - set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n") + string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n") endforeach() endif() set(pp_if "#if") if (CID_VERSION_STRINGS) - set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n/* Version number components: V=Version, R=Revision, P=Patch + string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n/* Version number components: V=Version, R=Revision, P=Patch Version date components: YYYY=Year, MM=Month, DD=Day */\n") endif() @@ -126,7 +126,7 @@ function(compiler_id_detection outvar lang) string(CONFIGURE "${_compiler_id_version_compute_${Id}}" VERSION_BLOCK @ONLY) string(APPEND id_content "${VERSION_BLOCK}\n") endif() - set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${id_content}") + string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n${id_content}") set(pp_if "#elif") endforeach() @@ -145,7 +145,7 @@ function(compiler_id_detection outvar lang) # define ${CID_PREFIX}COMPILER_ID \"\"") endif() - set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${platform_compiler_detection}\n#endif") + string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n${platform_compiler_detection}\n#endif") endif() set(${outvar} ${CMAKE_${lang}_COMPILER_ID_CONTENT} PARENT_SCOPE) diff --git a/Modules/CPackArchive.cmake b/Modules/CPackArchive.cmake new file mode 100644 index 0000000..741fb1f --- /dev/null +++ b/Modules/CPackArchive.cmake @@ -0,0 +1,39 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# CPackArchive +# ------------ +# +# Archive CPack generator that supports packaging of sources and binaries in +# different formats: +# +# - 7Z - 7zip - (.7z) +# - TBZ2 (.tar.bz2) +# - TGZ (.tar.gz) +# - TXZ (.tar.xz) +# - TZ (.tar.Z) +# - ZIP (.zip) +# +# Variables specific to CPack Archive generator +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# .. variable:: CPACK_ARCHIVE_FILE_NAME +# CPACK_ARCHIVE_<component>_FILE_NAME +# +# Package file name without extension which is added automatically depending +# on the archive format. +# +# * Mandatory : YES +# * Default : ``<CPACK_PACKAGE_FILE_NAME>[-<component>].<extension>`` with +# spaces replaced by '-' +# +# .. variable:: CPACK_ARCHIVE_COMPONENT_INSTALL +# +# Enable component packaging for CPackArchive +# +# * Mandatory : NO +# * Default : OFF +# +# If enabled (ON) multiple packages are generated. By default a single package +# containing files of all components is generated. diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 2adc9b9..3a10b99 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -309,11 +309,11 @@ set(CPackComponent_CMake_INCLUDED 1) # configuration file. macro(cpack_append_variable_set_command var strvar) if (DEFINED ${var}) - set(${strvar} "${${strvar}}set(${var}") + string(APPEND ${strvar} "set(${var}") foreach(APPENDVAL ${${var}}) - set(${strvar} "${${strvar}} ${APPENDVAL}") + string(APPEND ${strvar} " ${APPENDVAL}") endforeach() - set(${strvar} "${${strvar}})\n") + string(APPEND ${strvar} ")\n") endif () endmacro() @@ -325,7 +325,7 @@ macro(cpack_append_string_variable_set_command var strvar) if (DEFINED ${var}) list(LENGTH ${var} CPACK_APP_VALUE_LEN) if(${CPACK_APP_VALUE_LEN} EQUAL 1) - set(${strvar} "${${strvar}}set(${var} \"${${var}}\")\n") + string(APPEND ${strvar} "set(${var} \"${${var}}\")\n") endif() endif () endmacro() @@ -352,7 +352,7 @@ macro(cpack_append_option_set_command var strvar) if (${var}) list(LENGTH ${var} CPACK_APP_VALUE_LEN) if(${CPACK_APP_VALUE_LEN} EQUAL 1) - set(${strvar} "${${strvar}}set(${var} TRUE)\n") + string(APPEND ${strvar} "set(${var} TRUE)\n") endif() endif () endmacro() diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake index 4b3e223..fcf1df7 100644 --- a/Modules/CheckTypeSize.cmake +++ b/Modules/CheckTypeSize.cmake @@ -247,10 +247,10 @@ macro(CHECK_TYPE_SIZE TYPE VARIABLE) set(${VARIABLE}_CODE) set(_if if) foreach(key ${${VARIABLE}_KEYS}) - set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#${_if} defined(${key})\n# define ${VARIABLE} ${${VARIABLE}-${key}}\n") + string(APPEND ${VARIABLE}_CODE "#${_if} defined(${key})\n# define ${VARIABLE} ${${VARIABLE}-${key}}\n") set(_if elif) endforeach() - set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#else\n# error ${VARIABLE} unknown\n#endif") + string(APPEND ${VARIABLE}_CODE "#else\n# error ${VARIABLE} unknown\n#endif") set(_if) elseif(${VARIABLE}) set(${VARIABLE}_CODE "#define ${VARIABLE} ${${VARIABLE}}") diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 873f88d..7331fb2 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -1111,7 +1111,7 @@ if("${ExternalData_ACTION}" STREQUAL "fetch") list(GET algo_list ${ii} algo) _ExternalData_download_object("${name}" "${hash}" "${algo}" obj succeeded algoErrorMsg) - set(errorMsg "${errorMsg}\n${algoErrorMsg}") + string(APPEND errorMsg "\n${algoErrorMsg}") if(succeeded) break() endif() diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index b812845..2495736 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -415,7 +415,7 @@ file(STRINGS "${CMAKE_CURRENT_LIST_FILE}" lines foreach(line IN LISTS lines) if("${line}" MATCHES "^\\.\\. command:: ([A-Za-z0-9_]+)") if(_ep_func) - set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") + string(APPEND _ep_keywords_${_ep_func} ")$") endif() set(_ep_func "${CMAKE_MATCH_1}") #message("function [${_ep_func}]") @@ -424,13 +424,13 @@ foreach(line IN LISTS lines) elseif("${line}" MATCHES "^ ``([A-Z0-9_]+) .*``$") set(_ep_key "${CMAKE_MATCH_1}") #message(" keyword [${_ep_key}]") - set(_ep_keywords_${_ep_func} - "${_ep_keywords_${_ep_func}}${_ep_keyword_sep}${_ep_key}") + string(APPEND _ep_keywords_${_ep_func} + "${_ep_keyword_sep}${_ep_key}") set(_ep_keyword_sep "|") endif() endforeach() if(_ep_func) - set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") + string(APPEND _ep_keywords_${_ep_func} ")$") endif() # Save regex matching supported hash algorithm names. diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index e323430..a4dca54 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -1825,7 +1825,7 @@ macro(cuda_compile_base cuda_target format generated_files) else() set(_counter 1) endif() - set(_cuda_target "${_cuda_target}_${_counter}") + string(APPEND _cuda_target "_${_counter}") set_property(DIRECTORY PROPERTY _cuda_internal_phony_counter ${_counter}) # Separate the sources from the options diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 503d955..af83fb7 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -178,7 +178,7 @@ if(OPENGL_FOUND) if(OPENGL_gl_LIBRARY MATCHES "/([^/]+)\\.framework$") set(_gl_fw "${OPENGL_gl_LIBRARY}/${CMAKE_MATCH_1}") if(EXISTS "${_gl_fw}.tbd") - set(_gl_fw "${_gl_fw}.tbd") + string(APPEND _gl_fw ".tbd") endif() set_target_properties(OpenGL::GL PROPERTIES IMPORTED_LOCATION "${_gl_fw}") @@ -201,7 +201,7 @@ if(OPENGL_FOUND) if(OPENGL_glu_LIBRARY MATCHES "/([^/]+)\\.framework$") set(_glu_fw "${OPENGL_glu_LIBRARY}/${CMAKE_MATCH_1}") if(EXISTS "${_glu_fw}.tbd") - set(_glu_fw "${_glu_fw}.tbd") + string(APPEND _glu_fw ".tbd") endif() set_target_properties(OpenGL::GLU PROPERTIES IMPORTED_LOCATION "${_glu_fw}") diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index 91a3a25..c9e0544 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -9,48 +9,162 @@ This module defines functions to help use the Google Test infrastructure. .. command:: gtest_add_tests - Automatically add tests with CTest by scanning source code for Google test - macros. + Automatically add tests with CTest by scanning source code for Google Test + macros:: - :: + gtest_add_tests(TARGET target + [SOURCES src1...] + [EXTRA_ARGS arg1...] + [WORKING_DIRECTORY dir] + [TEST_PREFIX prefix] + [TEST_SUFFIX suffix] + [SKIP_DEPENDENCY] + [TEST_LIST outVar] + ) - gtest_add_tests(<exe> <args> <files>...) + ``TARGET target`` + This must be a known CMake target. CMake will substitute the location of + the built executable when running the test. - ``<exe>`` - The path to the test executable. - ``<args>`` + ``SOURCES src1...`` + When provided, only the listed files will be scanned for test cases. If + this option is not given, the :prop_tgt:`SOURCES` property of the + specified ``target`` will be used to obtain the list of sources. + + ``EXTRA_ARGS arg1...`` + Any extra arguments to pass on the command line to each test case. + + ``WORKING_DIRECTORY dir`` + Specifies the directory in which to run the discovered test cases. If this + option is not provided, the current binary directory is used. + + ``TEST_PREFIX prefix`` + Allows the specified ``prefix`` to be prepended to the name of each + discovered test case. This can be useful when the same source files are + being used in multiple calls to ``gtest_add_test()`` but with different + ``EXTRA_ARGS``. + + ``TEST_SUFFIX suffix`` + Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of + every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` can be + specified. + + ``SKIP_DEPENDENCY`` + Normally, the function creates a dependency which will cause CMake to be + re-run if any of the sources being scanned are changed. This is to ensure + that the list of discovered tests is updated. If this behavior is not + desired (as may be the case while actually writing the test cases), this + option can be used to prevent the dependency from being added. + + ``TEST_LIST outVar`` + The variable named by ``outVar`` will be populated in the calling scope + with the list of discovered test cases. This allows the caller to do things + like manipulate test properties of the discovered tests. + + .. code-block:: cmake + + include(GoogleTest) + add_executable(FooTest FooUnitTest.cxx) + gtest_add_tests(TARGET FooTest + TEST_SUFFIX .noArgs + TEST_LIST noArgsTests + ) + gtest_add_tests(TARGET FooTest + EXTRA_ARGS --someArg someValue + TEST_SUFFIX .withArgs + TEST_LIST withArgsTests + ) + set_tests_properties(${noArgsTests} PROPERTIES TIMEOUT 10) + set_tests_properties(${withArgsTests} PROPERTIES TIMEOUT 20) + + For backward compatibility reasons, the following form is also supported:: + + gtest_add_tests(exe args files...) + + ``exe`` + The path to the test executable or the name of a CMake target. + ``args`` A ;-list of extra arguments to be passed to executable. The entire list must be passed as a single argument. Enclose it in quotes, or pass ``""`` for no arguments. - ``<files>...`` + ``files...`` A list of source files to search for tests and test fixtures. - Alternatively, use ``AUTO`` to specify that ``<exe>`` is the name + Alternatively, use ``AUTO`` to specify that ``exe`` is the name of a CMake executable target whose sources should be scanned. -Example -^^^^^^^ - -.. code-block:: cmake + .. code-block:: cmake - include(GoogleTest) - set(FooTestArgs --foo 1 --bar 2) - add_executable(FooTest FooUnitTest.cc) - gtest_add_tests(FooTest "${FooTestArgs}" AUTO) + include(GoogleTest) + set(FooTestArgs --foo 1 --bar 2) + add_executable(FooTest FooUnitTest.cxx) + gtest_add_tests(FooTest "${FooTestArgs}" AUTO) #]=======================================================================] -function(gtest_add_tests executable extra_args) - if(NOT ARGN) - message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS") +function(gtest_add_tests) + + if (ARGC LESS 1) + message(FATAL_ERROR "No arguments supplied to gtest_add_tests()") endif() - if(ARGN STREQUAL "AUTO") - # obtain sources used for building that executable - get_property(ARGN TARGET ${executable} PROPERTY SOURCES) + + set(options + SKIP_DEPENDENCY + ) + set(oneValueArgs + TARGET + WORKING_DIRECTORY + TEST_PREFIX + TEST_SUFFIX + TEST_LIST + ) + set(multiValueArgs + SOURCES + EXTRA_ARGS + ) + set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs}) + + unset(sources) + if("${ARGV0}" IN_LIST allKeywords) + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(autoAddSources YES) + else() + # Non-keyword syntax, convert to keyword form + if (ARGC LESS 3) + message(FATAL_ERROR "gtest_add_tests() without keyword options requires at least 3 arguments") + endif() + set(ARGS_TARGET "${ARGV0}") + set(ARGS_EXTRA_ARGS "${ARGV1}") + if(NOT "${ARGV2}" STREQUAL "AUTO") + set(ARGS_SOURCES "${ARGV}") + list(REMOVE_AT ARGS_SOURCES 0 1) + endif() + endif() + + # The non-keyword syntax allows the first argument to be an arbitrary + # executable rather than a target if source files are also provided. In all + # other cases, both forms require a target. + if(NOT TARGET "${ARGS_TARGET}" AND NOT ARGS_SOURCES) + message(FATAL_ERROR "${ARGS_TARGET} does not define an existing CMake target") + endif() + if(NOT ARGS_WORKING_DIRECTORY) + unset(workDir) + else() + set(workDir WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}") + endif() + + if(NOT ARGS_SOURCES) + get_property(ARGS_SOURCES TARGET ${ARGS_TARGET} PROPERTY SOURCES) endif() + + unset(testList) + set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*") set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)") - foreach(source ${ARGN}) - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source}) + + foreach(source IN LISTS ARGS_SOURCES) + if(NOT ARGS_SKIP_DEPENDENCY) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source}) + endif() file(READ "${source}" contents) string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents}) foreach(hit ${found_tests}) @@ -67,7 +181,16 @@ function(gtest_add_tests executable extra_args) message(WARNING "Could not parse GTest ${hit} for adding to CTest.") continue() endif() - add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args}) + add_test(NAME ${ARGS_TEST_PREFIX}${test_name}${ARGS_TEST_SUFFIX} + ${workDir} + COMMAND ${ARGS_TARGET} --gtest_filter=${test_name} ${ARGS_EXTRA_ARGS} + ) + list(APPEND testList ${ARGS_TEST_PREFIX}${test_name}${ARGS_TEST_SUFFIX}) endforeach() endforeach() + + if(ARGS_TEST_LIST) + set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE) + endif() + endfunction() diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake index ca6e97c..7f08c4a 100644 --- a/Modules/Platform/AIX-GNU.cmake +++ b/Modules/Platform/AIX-GNU.cmake @@ -19,7 +19,7 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -Wl,-brtl") macro(__aix_compiler_gnu lang) set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:") set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") - set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G,-bnoipath") + string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-G,-bnoipath") set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall") set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1) diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index d08dc81..784c8c6 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -40,7 +40,7 @@ macro(__cygwin_compiler_gnu lang) set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-all-symbols") # TODO: Is -Wl,--enable-auto-import now always default? - set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,--enable-auto-import") + string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,--enable-auto-import") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS}") if(NOT CMAKE_RC_COMPILER_INIT) diff --git a/Modules/Platform/HP-UX-GNU.cmake b/Modules/Platform/HP-UX-GNU.cmake index 7ac804b..699c4aa 100644 --- a/Modules/Platform/HP-UX-GNU.cmake +++ b/Modules/Platform/HP-UX-GNU.cmake @@ -9,7 +9,7 @@ endif() set(__HPUX_COMPILER_GNU 1) macro(__hpux_compiler_gnu lang) - set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-E,-b,+nodefaultrpath") + string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-E,-b,+nodefaultrpath") set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-E") set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,+b") set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 22daa62..50477a4 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -148,6 +148,7 @@ macro(__windows_compiler_gnu_abi lang) find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat DOC "Visual Studio vcvars32.bat" PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin" @@ -161,6 +162,7 @@ macro(__windows_compiler_gnu_abi lang) find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars64.bat vcvarsamd64.bat DOC "Visual Studio vcvarsamd64.bat" PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin/amd64" diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index e4aca6e..cfe6e1c 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -152,9 +152,9 @@ if(WINCE) foreach(lang C CXX) if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "ARM") - set(_PLATFORM_DEFINES_${lang} "${_PLATFORM_DEFINES_${lang}} /D${MSVC_${lang}_ARCHITECTURE_ID}") + string(APPEND _PLATFORM_DEFINES_${lang} " /D${MSVC_${lang}_ARCHITECTURE_ID}") if(MSVC_${lang}_ARCHITECTURE_ID MATCHES "^ARMV([45])I$") - set(_FLAGS_${lang} "${_FLAGS_${lang}} /QRarch${CMAKE_MATCH_1}T") + string(APPEND _FLAGS_${lang} " /QRarch${CMAKE_MATCH_1}T") endif() endif() endforeach() diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 8ae3720..1182875 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -417,7 +417,7 @@ endfunction () function(__java_lcat VAR) foreach(_line ${ARGN}) - set(${VAR} "${${VAR}}${_line}\n") + string(APPEND ${VAR} "${_line}\n") endforeach() set(${VAR} "${${VAR}}" PARENT_SCOPE) diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index 362099e..e7f9912 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -447,7 +447,7 @@ function(write_compiler_detection_header endif() if(NOT _WCD_ALLOW_UNKNOWN_COMPILER_VERSIONS) - set(${compiler_file_content} "${${compiler_file_content}} + string(APPEND ${compiler_file_content} " # if !(${_cmake_oldestSupported_${compiler}}) # error Unsupported compiler version # endif\n") @@ -462,7 +462,7 @@ function(write_compiler_detection_header set(MACRO_HEX) endif() string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY) - set(${compiler_file_content} "${${compiler_file_content}}${VERSION_BLOCK}\n") + string(APPEND ${compiler_file_content} "${VERSION_BLOCK}\n") set(PREFIX) set(MACRO_DEC) set(MACRO_HEX) @@ -478,7 +478,7 @@ function(write_compiler_detection_header set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n") set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n") endif() - set(${compiler_file_content} "${${compiler_file_content}}${_define_item}") + string(APPEND ${compiler_file_content} "${_define_item}") endforeach() endforeach() if(pp_if STREQUAL "elif") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 2ac81fa..5cb5a84 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 8) -set(CMake_VERSION_PATCH 20170518) +set(CMake_VERSION_PATCH 20170519) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index cc01b0c..575c949 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -25,6 +25,28 @@ cmCPackArchiveGenerator::~cmCPackArchiveGenerator() { } +std::string cmCPackArchiveGenerator::GetArchiveComponentFileName( + const std::string& component, bool isGroupName) +{ + std::string componentUpper(cmSystemTools::UpperCase(component)); + std::string packageFileName; + + if (this->IsSet("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME")) { + packageFileName += + this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME"); + } else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { + packageFileName += GetComponentPackageFileName( + this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName); + } else { + packageFileName += GetComponentPackageFileName( + this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName); + } + + packageFileName += this->GetOutputExtension(); + + return packageFileName; +} + int cmCPackArchiveGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1"); @@ -101,11 +123,9 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compGIt->first << std::endl); // Begin the archive for this group - std::string packageFileName = std::string(toplevel); - packageFileName += "/" + - GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), - compGIt->first, true) + - this->GetOutputExtension(); + std::string packageFileName = std::string(toplevel) + "/" + + this->GetArchiveComponentFileName(compGIt->first, true); + // open a block in order to automatically close archive // at the end of the block { @@ -137,10 +157,9 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) std::string packageFileName = std::string(toplevel); localToplevel += "/" + compIt->first; - packageFileName += "/" + GetComponentPackageFileName( - this->GetOption("CPACK_PACKAGE_FILE_NAME"), - compIt->first, false) + - this->GetOutputExtension(); + packageFileName += + "/" + this->GetArchiveComponentFileName(compIt->first, false); + { DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive); // Add the files of this component to the archive @@ -161,10 +180,9 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) std::string packageFileName = std::string(toplevel); localToplevel += "/" + compIt->first; - packageFileName += "/" + - GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), - compIt->first, false) + - this->GetOutputExtension(); + packageFileName += + "/" + this->GetArchiveComponentFileName(compIt->first, false); + { DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive); // Add the files of this component to the archive @@ -182,9 +200,16 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne() // reset the package file names packageFileNames.clear(); packageFileNames.push_back(std::string(toplevel)); - packageFileNames[0] += "/" + - std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + - this->GetOutputExtension(); + packageFileNames[0] += "/"; + + if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { + packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME"); + } else { + packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + } + + packageFileNames[0] += this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package..." "(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)" diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 58d67e3..e7116c4 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -34,6 +34,11 @@ public: // component support bool SupportsComponentInstallation() const CM_OVERRIDE; +private: + // get archive component filename + std::string GetArchiveComponentFileName(const std::string& component, + bool isGroupName); + protected: int InitializeInternal() CM_OVERRIDE; /** diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index 691e3ae..cd1fb8a 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -251,13 +251,16 @@ public: SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1] .Characteristics; - if (SectChar & IMAGE_SCN_MEM_EXECUTE) { - this->Symbols.insert(symbol); - } else if (SectChar & IMAGE_SCN_MEM_READ) { - // skip __real@ and __xmm@ - if (symbol.find("_real") == std::string::npos && - symbol.find("_xmm") == std::string::npos) { - this->DataSymbols.insert(symbol); + // skip symbols containing a dot + if (symbol.find('.') == std::string::npos) { + if (SectChar & IMAGE_SCN_MEM_EXECUTE) { + this->Symbols.insert(symbol); + } else if (SectChar & IMAGE_SCN_MEM_READ) { + // skip __real@ and __xmm@ + if (symbol.find("_real") == std::string::npos && + symbol.find("_xmm") == std::string::npos) { + this->DataSymbols.insert(symbol); + } } } } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index d9a8cab..88fcb12 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -898,6 +898,10 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand( this->GetCMakeInstance()->GetHomeOutputDirectory(); if (!this->CompileCommandsStream) { std::string buildFilePath = buildFileDir + "/compile_commands.json"; + if (this->ComputingUnknownDependencies) { + this->CombinedBuildOutputs.insert( + this->NinjaOutputPath("compile_commands.json")); + } // Get a stream where to generate things. this->CompileCommandsStream = diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index f54d777..a966300 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceGroupCommand.h" -#include <algorithm> -#include <iterator> #include <set> #include <sstream> #include <stddef.h> @@ -16,7 +14,7 @@ namespace { const size_t RootIndex = 1; const size_t FilesWithoutPrefixKeywordIndex = 2; const size_t FilesWithPrefixKeywordIndex = 4; -const size_t PrefixKeywordIdex = 2; +const size_t PrefixKeywordIndex = 2; std::vector<std::string> tokenizePath(const std::string& path) { @@ -80,17 +78,26 @@ cmSourceGroup* addSourceGroup(const std::vector<std::string>& tokenizedPath, return sg; } -std::string prepareFilePathForTree(const std::string& path) +std::string prepareFilePathForTree(const std::string& path, + const std::string& currentSourceDir) { + if (!cmSystemTools::FileIsFullPath(path)) { + return cmSystemTools::CollapseFullPath(currentSourceDir + "/" + path); + } return cmSystemTools::CollapseFullPath(path); } std::vector<std::string> prepareFilesPathsForTree( std::vector<std::string>::const_iterator begin, - std::vector<std::string>::const_iterator end) + std::vector<std::string>::const_iterator end, + const std::string& currentSourceDir) { - std::vector<std::string> prepared(std::distance(begin, end)); - std::transform(begin, end, prepared.begin(), prepareFilePathForTree); + std::vector<std::string> prepared; + + for (; begin != end; ++begin) { + prepared.push_back(prepareFilePathForTree(*begin, currentSourceDir)); + } + return prepared; } @@ -229,13 +236,13 @@ bool cmSourceGroupCommand::checkTreeArgumentsPreconditions( } if (args[FilesWithoutPrefixKeywordIndex] != "FILES" && - args[PrefixKeywordIdex] != "PREFIX") { + args[PrefixKeywordIndex] != "PREFIX") { errorMsg = "Unknown argument \"" + args[2] + "\". Perhaps the FILES keyword is missing.\n"; return false; } - if (args[PrefixKeywordIdex] == "PREFIX" && + if (args[PrefixKeywordIndex] == "PREFIX" && (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) { errorMsg = "Missing FILES arguments."; return false; @@ -254,13 +261,14 @@ bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args, const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]); std::string prefix; size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1; - if (args[PrefixKeywordIdex] == "PREFIX") { - prefix = args[PrefixKeywordIdex + 1]; + if (args[PrefixKeywordIndex] == "PREFIX") { + prefix = args[PrefixKeywordIndex + 1]; filesBegin = FilesWithPrefixKeywordIndex + 1; } const std::vector<std::string> filesVector = - prepareFilesPathsForTree(args.begin() + filesBegin, args.end()); + prepareFilesPathsForTree(args.begin() + filesBegin, args.end(), + this->Makefile->GetCurrentSourceDirectory()); if (!rootIsPrefix(root, filesVector, errorMsg)) { return false; diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c index 37c3b8c..99f008e 100644 --- a/Source/kwsys/Base64.c +++ b/Source/kwsys/Base64.c @@ -9,13 +9,11 @@ #include "Base64.h.in" #endif -/*--------------------------------------------------------------------------*/ static const unsigned char kwsysBase64EncodeTable[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; -/*--------------------------------------------------------------------------*/ static const unsigned char kwsysBase64DecodeTable[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -40,19 +38,16 @@ static const unsigned char kwsysBase64DecodeTable[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -/*--------------------------------------------------------------------------*/ static unsigned char kwsysBase64EncodeChar(int c) { return kwsysBase64EncodeTable[(unsigned char)c]; } -/*--------------------------------------------------------------------------*/ static unsigned char kwsysBase64DecodeChar(unsigned char c) { return kwsysBase64DecodeTable[c]; } -/*--------------------------------------------------------------------------*/ /* Encode 3 bytes into a 4 byte string. */ void kwsysBase64_Encode3(const unsigned char* src, unsigned char* dest) { @@ -64,7 +59,6 @@ void kwsysBase64_Encode3(const unsigned char* src, unsigned char* dest) dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F); } -/*--------------------------------------------------------------------------*/ /* Encode 2 bytes into a 4 byte string. */ void kwsysBase64_Encode2(const unsigned char* src, unsigned char* dest) { @@ -75,7 +69,6 @@ void kwsysBase64_Encode2(const unsigned char* src, unsigned char* dest) dest[3] = '='; } -/*--------------------------------------------------------------------------*/ /* Encode 1 bytes into a 4 byte string. */ void kwsysBase64_Encode1(const unsigned char* src, unsigned char* dest) { @@ -85,7 +78,6 @@ void kwsysBase64_Encode1(const unsigned char* src, unsigned char* dest) dest[3] = '='; } -/*--------------------------------------------------------------------------*/ /* Encode 'length' bytes from the input buffer and store the encoded stream into the output buffer. Return the length of the encoded buffer (output). Note that the output buffer must be allocated by the caller @@ -135,7 +127,6 @@ size_t kwsysBase64_Encode(const unsigned char* input, size_t length, return (size_t)(optr - output); } -/*--------------------------------------------------------------------------*/ /* Decode 4 bytes into a 3 byte string. */ int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest) { @@ -169,7 +160,6 @@ int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest) return 3; } -/*--------------------------------------------------------------------------*/ /* Decode bytes from the input buffer and store the decoded stream into the output buffer until 'length' bytes have been decoded. Return the real length of the decoded stream (which should be equal to 'length'). Note diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index 226263c..5613bd7 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -41,8 +41,6 @@ namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- -//============================================================================ struct CommandLineArgumentsCallbackStructure { const char* Argument; @@ -91,10 +89,7 @@ public: VectorOfStrings UnusedArguments; }; -//============================================================================ -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- CommandLineArguments::CommandLineArguments() { this->Internals = new CommandLineArguments::Internal; @@ -103,13 +98,11 @@ CommandLineArguments::CommandLineArguments() this->StoreUnusedArgumentsFlag = false; } -//---------------------------------------------------------------------------- CommandLineArguments::~CommandLineArguments() { delete this->Internals; } -//---------------------------------------------------------------------------- void CommandLineArguments::Initialize(int argc, const char* const argv[]) { int cc; @@ -121,26 +114,22 @@ void CommandLineArguments::Initialize(int argc, const char* const argv[]) } } -//---------------------------------------------------------------------------- void CommandLineArguments::Initialize(int argc, char* argv[]) { this->Initialize(argc, static_cast<const char* const*>(argv)); } -//---------------------------------------------------------------------------- void CommandLineArguments::Initialize() { this->Internals->Argv.clear(); this->Internals->LastArgument = 0; } -//---------------------------------------------------------------------------- void CommandLineArguments::ProcessArgument(const char* arg) { this->Internals->Argv.push_back(arg); } -//---------------------------------------------------------------------------- bool CommandLineArguments::GetMatchedArguments( std::vector<std::string>* matches, const std::string& arg) { @@ -164,7 +153,6 @@ bool CommandLineArguments::GetMatchedArguments( return !matches->empty(); } -//---------------------------------------------------------------------------- int CommandLineArguments::Parse() { std::vector<std::string>::size_type cc; @@ -286,7 +274,6 @@ int CommandLineArguments::Parse() return 1; } -//---------------------------------------------------------------------------- void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv) { CommandLineArguments::Internal::VectorOfStrings::size_type size = @@ -310,7 +297,6 @@ void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv) *argv = args; } -//---------------------------------------------------------------------------- void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv) { CommandLineArguments::Internal::VectorOfStrings::size_type size = @@ -334,7 +320,6 @@ void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv) *argv = args; } -//---------------------------------------------------------------------------- void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) { int cc; @@ -344,7 +329,6 @@ void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) delete[] * argv; } -//---------------------------------------------------------------------------- void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type, CallbackType callback, void* call_data, @@ -363,7 +347,6 @@ void CommandLineArguments::AddCallback(const char* argument, this->GenerateHelp(); } -//---------------------------------------------------------------------------- void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, VariableTypeEnum vtype, void* variable, @@ -382,7 +365,6 @@ void CommandLineArguments::AddArgument(const char* argument, this->GenerateHelp(); } -//---------------------------------------------------------------------------- #define CommandLineArgumentsAddArgumentMacro(type, ctype) \ void CommandLineArguments::AddArgument(const char* argument, \ ArgumentTypeEnum type, \ @@ -392,22 +374,24 @@ void CommandLineArguments::AddArgument(const char* argument, variable, help); \ } +/* clang-format off */ CommandLineArgumentsAddArgumentMacro(BOOL, bool) - CommandLineArgumentsAddArgumentMacro(INT, int) - CommandLineArgumentsAddArgumentMacro(DOUBLE, double) - CommandLineArgumentsAddArgumentMacro(STRING, char*) - CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string) - - CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>) - CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>) - CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, - std::vector<double>) - CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, - std::vector<char*>) - CommandLineArgumentsAddArgumentMacro( - VECTOR_STL_STRING, std::vector<std::string>) - -//---------------------------------------------------------------------------- +CommandLineArgumentsAddArgumentMacro(INT, int) +CommandLineArgumentsAddArgumentMacro(DOUBLE, double) +CommandLineArgumentsAddArgumentMacro(STRING, char*) +CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string) + +CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>) +CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>) +CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, std::vector<double>) +CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, std::vector<char*>) +CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, + std::vector<std::string>) +#ifdef HELP_CLANG_FORMAT +; +#endif +/* clang-format on */ + #define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \ void CommandLineArguments::AddBooleanArgument( \ const char* argument, ctype* variable, const char* help) \ @@ -416,29 +400,28 @@ CommandLineArgumentsAddArgumentMacro(BOOL, bool) CommandLineArguments::type##_TYPE, variable, help); \ } - CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool) - CommandLineArgumentsAddBooleanArgumentMacro(INT, int) - CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, - double) - CommandLineArgumentsAddBooleanArgumentMacro(STRING, - char*) - CommandLineArgumentsAddBooleanArgumentMacro( - STL_STRING, std::string) +/* clang-format off */ +CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool) +CommandLineArgumentsAddBooleanArgumentMacro(INT, int) +CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double) +CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*) +CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string) +#ifdef HELP_CLANG_FORMAT +; +#endif +/* clang-format on */ - //---------------------------------------------------------------------------- - void CommandLineArguments::SetClientData(void* client_data) +void CommandLineArguments::SetClientData(void* client_data) { this->Internals->ClientData = client_data; } -//---------------------------------------------------------------------------- void CommandLineArguments::SetUnknownArgumentCallback( CommandLineArguments::ErrorCallbackType callback) { this->Internals->UnknownArgumentCallback = callback; } -//---------------------------------------------------------------------------- const char* CommandLineArguments::GetHelp(const char* arg) { CommandLineArguments::Internal::CallbacksMap::iterator it = @@ -461,7 +444,6 @@ const char* CommandLineArguments::GetHelp(const char* arg) return cs->Help; } -//---------------------------------------------------------------------------- void CommandLineArguments::SetLineLength(unsigned int ll) { if (ll < 9 || ll > 1000) { @@ -471,19 +453,16 @@ void CommandLineArguments::SetLineLength(unsigned int ll) this->GenerateHelp(); } -//---------------------------------------------------------------------------- const char* CommandLineArguments::GetArgv0() { return this->Internals->Argv0.c_str(); } -//---------------------------------------------------------------------------- unsigned int CommandLineArguments::GetLastArgument() { return static_cast<unsigned int>(this->Internals->LastArgument + 1); } -//---------------------------------------------------------------------------- void CommandLineArguments::GenerateHelp() { std::ostringstream str; @@ -633,7 +612,6 @@ void CommandLineArguments::GenerateHelp() this->Help = str.str(); } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(bool* variable, const std::string& value) { @@ -646,7 +624,6 @@ void CommandLineArguments::PopulateVariable(bool* variable, } } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(int* variable, const std::string& value) { @@ -658,7 +635,6 @@ void CommandLineArguments::PopulateVariable(int* variable, // } } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(double* variable, const std::string& value) { @@ -670,7 +646,6 @@ void CommandLineArguments::PopulateVariable(double* variable, // } } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(char** variable, const std::string& value) { @@ -682,14 +657,12 @@ void CommandLineArguments::PopulateVariable(char** variable, strcpy(*variable, value.c_str()); } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::string* variable, const std::string& value) { *variable = value; } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, const std::string& value) { @@ -702,7 +675,6 @@ void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, variable->push_back(val); } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::vector<int>* variable, const std::string& value) { @@ -714,7 +686,6 @@ void CommandLineArguments::PopulateVariable(std::vector<int>* variable, // } } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::vector<double>* variable, const std::string& value) { @@ -726,7 +697,6 @@ void CommandLineArguments::PopulateVariable(std::vector<double>* variable, // } } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::vector<char*>* variable, const std::string& value) { @@ -735,14 +705,12 @@ void CommandLineArguments::PopulateVariable(std::vector<char*>* variable, variable->push_back(var); } -//---------------------------------------------------------------------------- void CommandLineArguments::PopulateVariable(std::vector<std::string>* variable, const std::string& value) { variable->push_back(value); } -//---------------------------------------------------------------------------- bool CommandLineArguments::PopulateVariable( CommandLineArgumentsCallbackStructure* cs, const char* value) { diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 3c31b49..ca1cb18 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -20,7 +20,6 @@ namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- class DirectoryInternals { public: @@ -31,25 +30,21 @@ public: std::string Path; }; -//---------------------------------------------------------------------------- Directory::Directory() { this->Internal = new DirectoryInternals; } -//---------------------------------------------------------------------------- Directory::~Directory() { delete this->Internal; } -//---------------------------------------------------------------------------- unsigned long Directory::GetNumberOfFiles() const { return static_cast<unsigned long>(this->Internal->Files.size()); } -//---------------------------------------------------------------------------- const char* Directory::GetFile(unsigned long dindex) const { if (dindex >= this->Internal->Files.size()) { @@ -58,13 +53,11 @@ const char* Directory::GetFile(unsigned long dindex) const return this->Internal->Files[dindex].c_str(); } -//---------------------------------------------------------------------------- const char* Directory::GetPath() const { return this->Internal->Path.c_str(); } -//---------------------------------------------------------------------------- void Directory::Clear() { this->Internal->Path.resize(0); diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index e494db6..1b4596a 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -26,20 +26,17 @@ // the static methods of DynamicLoader. #if !KWSYS_SUPPORTS_SHARED_LIBS -//---------------------------------------------------------------------------- // Implementation for environments without dynamic libs #include <string.h> // for strerror() namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { return 0; } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { if (!lib) { @@ -49,14 +46,12 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return 1; } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { return 0; } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return "General error"; @@ -65,21 +60,18 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #elif defined(__hpux) -//---------------------------------------------------------------------------- // Implementation for HPUX machines #include <dl.h> #include <errno.h> namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L); } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { if (!lib) { @@ -88,7 +80,6 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return !shl_unload(lib); } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -132,14 +123,12 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030) -//---------------------------------------------------------------------------- // Implementation for Mac OS X 10.2.x and earlier #include <mach-o/dyld.h> #include <string.h> // for strlen namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { @@ -158,7 +147,6 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( return handle; } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED @@ -170,7 +158,6 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return success; } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -191,7 +178,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return 0; @@ -200,13 +186,11 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #elif defined(_WIN32) && !defined(__CYGWIN__) -//---------------------------------------------------------------------------- // Implementation for Windows win32 code but not cygwin #include <windows.h> namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { @@ -220,13 +204,11 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( return lh; } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { return (int)FreeLibrary(lib); } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -274,7 +256,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( #endif } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { LPVOID lpMsgBuf = NULL; @@ -299,7 +280,6 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #elif defined(__BEOS__) -//---------------------------------------------------------------------------- // Implementation for BeOS / Haiku #include <string.h> // for strerror() @@ -310,7 +290,6 @@ namespace KWSYS_NAMESPACE { static image_id last_dynamic_err = B_OK; -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { @@ -325,7 +304,6 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( return rc + 1; } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { if (!lib) { @@ -343,7 +321,6 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return 1; } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -372,7 +349,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( return result.psym; } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { const char* retval = strerror(last_dynamic_err); @@ -383,7 +359,6 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #elif defined(__MINT__) -//---------------------------------------------------------------------------- // Implementation for FreeMiNT on Atari #define _GNU_SOURCE /* for program_invocation_name */ #include <dld.h> @@ -393,7 +368,6 @@ const char* DynamicLoader::LastError() namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { @@ -404,7 +378,6 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( return (void*)name; } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { dld_unlink_by_file((char*)lib, 0); @@ -412,7 +385,6 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return 0; } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -426,7 +398,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( return result.psym; } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return dld_strerror(dld_errno); @@ -435,21 +406,18 @@ const char* DynamicLoader::LastError() } // namespace KWSYS_NAMESPACE #else -//---------------------------------------------------------------------------- // Default implementation for *NIX systems (including Mac OS X 10.3 and // later) which use dlopen #include <dlfcn.h> namespace KWSYS_NAMESPACE { -//---------------------------------------------------------------------------- DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname) { return dlopen(libname.c_str(), RTLD_LAZY); } -//---------------------------------------------------------------------------- int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) { if (lib) { @@ -460,7 +428,6 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) return 0; } -//---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const std::string& sym) { @@ -474,7 +441,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( return result.psym; } -//---------------------------------------------------------------------------- const char* DynamicLoader::LastError() { return dlerror(); diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index fa8760d..d2f0b85 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -37,7 +37,6 @@ namespace KWSYS_NAMESPACE { #define KWSYS_GLOB_SUPPORT_NETWORK_PATHS #endif -//---------------------------------------------------------------------------- class GlobInternals { public: @@ -45,7 +44,6 @@ public: std::vector<kwsys::RegularExpression> Expressions; }; -//---------------------------------------------------------------------------- Glob::Glob() { this->Internals = new GlobInternals; @@ -62,19 +60,16 @@ Glob::Glob() this->RecurseListDirs = false; } -//---------------------------------------------------------------------------- Glob::~Glob() { delete this->Internals; } -//---------------------------------------------------------------------------- std::vector<std::string>& Glob::GetFiles() { return this->Internals->Files; } -//---------------------------------------------------------------------------- std::string Glob::PatternToRegex(const std::string& pattern, bool require_whole_string, bool preserve_case) { @@ -183,7 +178,6 @@ std::string Glob::PatternToRegex(const std::string& pattern, return regex; } -//---------------------------------------------------------------------------- bool Glob::RecurseDirectory(std::string::size_type start, const std::string& dir, GlobMessages* messages) { @@ -277,7 +271,6 @@ bool Glob::RecurseDirectory(std::string::size_type start, return true; } -//---------------------------------------------------------------------------- void Glob::ProcessDirectory(std::string::size_type start, const std::string& dir, GlobMessages* messages) { @@ -337,7 +330,6 @@ void Glob::ProcessDirectory(std::string::size_type start, } } -//---------------------------------------------------------------------------- bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages) { std::string cexpr; @@ -420,14 +412,12 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages) return true; } -//---------------------------------------------------------------------------- void Glob::AddExpression(const std::string& expr) { this->Internals->Expressions.push_back( kwsys::RegularExpression(this->PatternToRegex(expr))); } -//---------------------------------------------------------------------------- void Glob::SetRelative(const char* dir) { if (!dir) { @@ -437,7 +427,6 @@ void Glob::SetRelative(const char* dir) this->Relative = dir; } -//---------------------------------------------------------------------------- const char* Glob::GetRelative() { if (this->Relative.empty()) { @@ -446,7 +435,6 @@ const char* Glob::GetRelative() return this->Relative.c_str(); } -//---------------------------------------------------------------------------- void Glob::AddFile(std::vector<std::string>& files, const std::string& file) { if (!this->Relative.empty()) { diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c index 1310c64..3188fb6 100644 --- a/Source/kwsys/MD5.c +++ b/Source/kwsys/MD5.c @@ -13,8 +13,6 @@ #include <stdlib.h> /* malloc, free */ #include <string.h> /* memcpy, strlen */ -/*--------------------------------------------------------------------------*/ - /* This MD5 implementation has been taken from a third party. Slight modifications to the arrangement of the code have been made to put it in a single source file instead of a separate header and @@ -425,14 +423,12 @@ static void md5_finish(md5_state_t* pms, md5_byte_t digest[16]) #pragma clang diagnostic pop #endif -/*--------------------------------------------------------------------------*/ /* Wrap up the MD5 state in our opaque structure. */ struct kwsysMD5_s { md5_state_t md5_state; }; -/*--------------------------------------------------------------------------*/ kwsysMD5* kwsysMD5_New(void) { /* Allocate a process control structure. */ @@ -443,7 +439,6 @@ kwsysMD5* kwsysMD5_New(void) return md5; } -/*--------------------------------------------------------------------------*/ void kwsysMD5_Delete(kwsysMD5* md5) { /* Make sure we have an instance. */ @@ -455,13 +450,11 @@ void kwsysMD5_Delete(kwsysMD5* md5) free(md5); } -/*--------------------------------------------------------------------------*/ void kwsysMD5_Initialize(kwsysMD5* md5) { md5_init(&md5->md5_state); } -/*--------------------------------------------------------------------------*/ void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length) { size_t dlen; @@ -473,13 +466,11 @@ void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length) md5_append(&md5->md5_state, (md5_byte_t const*)data, dlen); } -/*--------------------------------------------------------------------------*/ void kwsysMD5_Finalize(kwsysMD5* md5, unsigned char digest[16]) { md5_finish(&md5->md5_state, (md5_byte_t*)digest); } -/*--------------------------------------------------------------------------*/ void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32]) { unsigned char digest[16]; @@ -487,7 +478,6 @@ void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32]) kwsysMD5_DigestToHex(digest, buffer); } -/*--------------------------------------------------------------------------*/ void kwsysMD5_DigestToHex(unsigned char const digest[16], char buffer[32]) { /* Map from 4-bit index to hexadecimal representation. */ diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in index b8349a6..237001c 100644 --- a/Source/kwsys/Process.h.in +++ b/Source/kwsys/Process.h.in @@ -42,7 +42,6 @@ #define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired) #define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed) #define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned) -#define kwsysProcess_GetState kwsys_ns(Process_GetState) #define kwsysProcess_State_e kwsys_ns(Process_State_e) #define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None) #define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault) @@ -50,12 +49,21 @@ #define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt) #define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical) #define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other) -#define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException) #define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e) +#define kwsysProcess_GetState kwsys_ns(Process_GetState) +#define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException) #define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode) #define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue) #define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString) #define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString) +#define kwsysProcess_GetStateByIndex kwsys_ns(Process_GetStateByIndex) +#define kwsysProcess_GetExitExceptionByIndex \ + kwsys_ns(Process_GetExitExceptionByIndex) +#define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) +#define kwsysProcess_GetExitValueByIndex kwsys_ns(Process_GetExitValueByIndex) +#define kwsysProcess_GetExceptionStringByIndex \ + kwsys_ns(Process_GetExceptionStringByIndex) +#define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) #define kwsysProcess_Execute kwsys_ns(Process_Execute) #define kwsysProcess_Disown kwsys_ns(Process_Disown) #define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData) @@ -298,6 +306,67 @@ kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp); kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp); /** +* Get the current state of the Process instance. Possible states are: +* +* kwsysProcess_StateByIndex_Starting = Execute has not yet been called. +* kwsysProcess_StateByIndex_Exception = Child process exited abnormally. +* kwsysProcess_StateByIndex_Exited = Child process exited normally. +* kwsysProcess_StateByIndex_Error = Error getting the child return code. +*/ +kwsysEXPORT int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx); +enum kwsysProcess_StateByIndex_e +{ + kwsysProcess_StateByIndex_Starting = kwsysProcess_State_Starting, + kwsysProcess_StateByIndex_Exception = kwsysProcess_State_Exception, + kwsysProcess_StateByIndex_Exited = kwsysProcess_State_Exited, + kwsysProcess_StateByIndex_Error = kwsysProcess_State_Error +}; + +/** +* When GetState returns "Exception", this method returns a +* platform-independent description of the exceptional behavior that +* caused the child to terminate abnormally. Possible exceptions are: +* +* kwsysProcess_Exception_None = No exceptional behavior occurred. +* kwsysProcess_Exception_Fault = Child crashed with a memory fault. +* kwsysProcess_Exception_Illegal = Child crashed with an illegal +* instruction. +* kwsysProcess_Exception_Interrupt = Child was interrupted by user +* (Cntl-C/Break). +* kwsysProcess_Exception_Numerical = Child crashed with a numerical +* exception. +* kwsysProcess_Exception_Other = Child terminated for another reason. +*/ +kwsysEXPORT int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, + int idx); + +/** +* When GetState returns "Exited" or "Exception", this method returns +* the platform-specific raw exit code of the process. UNIX platforms +* should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access +* this value. Windows users should compare the value to the various +* EXCEPTION_* values. +* +* If GetState returns "Exited", use GetExitValue to get the +* platform-independent child return value. +*/ +kwsysEXPORT int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx); + +/** +* When GetState returns "Exited", this method returns the child's +* platform-independent exit code (such as the value returned by the +* child's main). +*/ +kwsysEXPORT int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx); + +/** +* When GetState returns "Exception", this method returns a string +* describing the problem. Otherwise, it returns NULL. +*/ +kwsysEXPORT const char* kwsysProcess_GetExceptionStringByIndex( + kwsysProcess* cp, int idx); + +/** * Start executing the child process. */ kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp); diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index ed09095..9ebcfce 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -140,7 +140,6 @@ typedef struct kwsysProcessCreateInformation_s int ErrorPipe[2]; } kwsysProcessCreateInformation; -/*--------------------------------------------------------------------------*/ static void kwsysProcessVolatileFree(volatile void* p); static int kwsysProcessInitialize(kwsysProcess* cp); static void kwsysProcessCleanup(kwsysProcess* cp, int error); @@ -166,7 +165,8 @@ static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2); static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2); -static void kwsysProcessSetExitException(kwsysProcess* cp, int sig); +static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int sig, + int idx); static void kwsysProcessChildErrorExit(int errorPipe); static void kwsysProcessRestoreDefaultSignalHandlers(void); static pid_t kwsysProcessFork(kwsysProcess* cp, @@ -184,7 +184,26 @@ static void kwsysProcessesSignalHandler(int signum, siginfo_t* info, static void kwsysProcessesSignalHandler(int signum); #endif -/*--------------------------------------------------------------------------*/ +/* A structure containing results data for each process. */ +typedef struct kwsysProcessResults_s kwsysProcessResults; +struct kwsysProcessResults_s +{ + /* The status of the child process. */ + int State; + + /* The exceptional behavior that terminated the process, if any. */ + int ExitException; + + /* The process exit code. */ + int ExitCode; + + /* The process return code, if any. */ + int ExitValue; + + /* Description for the ExitException. */ + char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; +}; + /* Structure containing data used to implement the child's execution. */ struct kwsysProcess_s { @@ -255,28 +274,18 @@ struct kwsysProcess_s /* The number of children still executing. */ int CommandsLeft; - /* The current status of the child process. Must be atomic because + /* The status of the process structure. Must be atomic because the signal handler checks this to avoid a race. */ volatile sig_atomic_t State; - /* The exceptional behavior that terminated the child process, if - * any. */ - int ExitException; - - /* The exit code of the child process. */ - int ExitCode; - - /* The exit value of the child process, if any. */ - int ExitValue; - /* Whether the process was killed. */ volatile sig_atomic_t Killed; /* Buffer for error message in case of failure. */ char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1]; - /* Description for the ExitException. */ - char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; + /* process results. */ + kwsysProcessResults* ProcessResults; /* The exit codes of each child process in the pipeline. */ int* CommandExitCodes; @@ -301,7 +310,6 @@ struct kwsysProcess_s char* RealWorkingDirectory; }; -/*--------------------------------------------------------------------------*/ kwsysProcess* kwsysProcess_New(void) { /* Allocate a process control structure. */ @@ -328,7 +336,6 @@ kwsysProcess* kwsysProcess_New(void) return cp; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Delete(kwsysProcess* cp) { /* Make sure we have an instance. */ @@ -354,10 +361,10 @@ void kwsysProcess_Delete(kwsysProcess* cp) if (cp->CommandExitCodes) { free(cp->CommandExitCodes); } + free(cp->ProcessResults); free(cp); } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) { int i; @@ -382,7 +389,6 @@ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) return 1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) { int newNumberOfCommands; @@ -462,7 +468,6 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) { if (!cp) { @@ -476,7 +481,6 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) cp->TimeoutTime.tv_sec = -1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) { if (!cp) { @@ -502,7 +506,6 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) return 1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file) { char** pfile; @@ -543,7 +546,6 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file) return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared) { if (!cp) { @@ -572,7 +574,6 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2]) { int* pPipeNative = 0; @@ -612,7 +613,6 @@ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2]) } } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) { if (!cp) { @@ -633,7 +633,6 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) { if (!cp) { @@ -658,31 +657,32 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) } } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetState(kwsysProcess* cp) { return cp ? cp->State : kwsysProcess_State_Error; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitException(kwsysProcess* cp) { - return cp ? cp->ExitException : kwsysProcess_Exception_Other; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitException + : kwsysProcess_Exception_Other; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitCode(kwsysProcess* cp) { - return cp ? cp->ExitCode : 0; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitCode + : 0; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitValue(kwsysProcess* cp) { - return cp ? cp->ExitValue : -1; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitValue + : -1; } -/*--------------------------------------------------------------------------*/ const char* kwsysProcess_GetErrorString(kwsysProcess* cp) { if (!cp) { @@ -693,18 +693,58 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp) return "Success"; } -/*--------------------------------------------------------------------------*/ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp) { - if (!cp) { + if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) { return "GetExceptionString called with NULL process management structure"; } else if (cp->State == kwsysProcess_State_Exception) { - return cp->ExitExceptionString; + return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString; + } + return "No exception"; +} + +/* the index should be in array bound. */ +#define KWSYSPE_IDX_CHK(RET) \ + if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \ + return RET; \ + } + +int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(kwsysProcess_State_Error) + return cp->ProcessResults[idx].State; +} + +int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other) + return cp->ProcessResults[idx].ExitException; +} + +int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(-1) + return cp->ProcessResults[idx].ExitValue; +} + +int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(-1) + return cp->CommandExitCodes[idx]; +} + +const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management " + "structure or index out of bound") + if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) { + return cp->ProcessResults[idx].ExitExceptionString; } return "No exception"; } -/*--------------------------------------------------------------------------*/ +#undef KWSYSPE_IDX_CHK + void kwsysProcess_Execute(kwsysProcess* cp) { int i; @@ -990,7 +1030,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) cp->Detached = cp->OptionDetach; } -/*--------------------------------------------------------------------------*/ kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp) { /* Make sure a detached child process is running. */ @@ -1009,7 +1048,6 @@ kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp) cp->State = kwsysProcess_State_Disowned; } -/*--------------------------------------------------------------------------*/ typedef struct kwsysProcessWaitData_s { int Expired; @@ -1021,7 +1059,6 @@ typedef struct kwsysProcessWaitData_s static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length, kwsysProcessWaitData* wd); -/*--------------------------------------------------------------------------*/ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, double* userTimeout) { @@ -1083,7 +1120,6 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, } } -/*--------------------------------------------------------------------------*/ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length, kwsysProcessWaitData* wd) { @@ -1285,10 +1321,8 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length, #endif } -/*--------------------------------------------------------------------------*/ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) { - int status = 0; int prPipe = 0; /* Make sure we are executing a process. */ @@ -1319,10 +1353,6 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) cp->State = kwsysProcess_State_Error; return 1; } - - /* Use the status of the last process in the pipeline. */ - status = cp->CommandExitCodes[cp->NumberOfCommands - 1]; - /* Determine the outcome. */ if (cp->Killed) { /* We killed the child. */ @@ -1330,29 +1360,36 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) } else if (cp->TimeoutExpired) { /* The timeout expired. */ cp->State = kwsysProcess_State_Expired; - } else if (WIFEXITED(status)) { - /* The child exited normally. */ - cp->State = kwsysProcess_State_Exited; - cp->ExitException = kwsysProcess_Exception_None; - cp->ExitCode = status; - cp->ExitValue = (int)WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) { - /* The child received an unhandled signal. */ - cp->State = kwsysProcess_State_Exception; - cp->ExitCode = status; - kwsysProcessSetExitException(cp, (int)WTERMSIG(status)); } else { - /* Error getting the child return code. */ - strcpy(cp->ErrorMessage, "Error getting child return code."); - cp->State = kwsysProcess_State_Error; + /* The children exited. Report the outcome of the child processes. */ + for (prPipe = 0; prPipe < cp->NumberOfCommands; ++prPipe) { + cp->ProcessResults[prPipe].ExitCode = cp->CommandExitCodes[prPipe]; + if (WIFEXITED(cp->ProcessResults[prPipe].ExitCode)) { + /* The child exited normally. */ + cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited; + cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None; + cp->ProcessResults[prPipe].ExitValue = + (int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode); + } else if (WIFSIGNALED(cp->ProcessResults[prPipe].ExitCode)) { + /* The child received an unhandled signal. */ + cp->ProcessResults[prPipe].State = kwsysProcess_State_Exception; + kwsysProcessSetExitExceptionByIndex( + cp, (int)WTERMSIG(cp->ProcessResults[prPipe].ExitCode), prPipe); + } else { + /* Error getting the child return code. */ + strcpy(cp->ProcessResults[prPipe].ExitExceptionString, + "Error getting child return code."); + cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Error; + } + } + /* support legacy state status value */ + cp->State = cp->ProcessResults[cp->NumberOfCommands - 1].State; } - /* Normal cleanup. */ kwsysProcessCleanup(cp, 0); return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Interrupt(kwsysProcess* cp) { int i; @@ -1384,7 +1421,6 @@ void kwsysProcess_Interrupt(kwsysProcess* cp) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Kill(kwsysProcess* cp) { int i; @@ -1431,7 +1467,6 @@ void kwsysProcess_Kill(kwsysProcess* cp) cp->CommandsLeft = 0; } -/*--------------------------------------------------------------------------*/ /* Call the free() function with a pointer to volatile without causing compiler warnings. */ static void kwsysProcessVolatileFree(volatile void* p) @@ -1448,7 +1483,6 @@ static void kwsysProcessVolatileFree(volatile void* p) #endif } -/*--------------------------------------------------------------------------*/ /* Initialize a process control structure for kwsysProcess_Execute. */ static int kwsysProcessInitialize(kwsysProcess* cp) { @@ -1474,11 +1508,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp) #endif cp->State = kwsysProcess_State_Starting; cp->Killed = 0; - cp->ExitException = kwsysProcess_Exception_None; - cp->ExitCode = 1; - cp->ExitValue = 1; cp->ErrorMessage[0] = 0; - strcpy(cp->ExitExceptionString, "No exception"); oldForkPIDs = cp->ForkPIDs; cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) * @@ -1504,6 +1534,23 @@ static int kwsysProcessInitialize(kwsysProcess* cp) memset(cp->CommandExitCodes, 0, sizeof(int) * (size_t)(cp->NumberOfCommands)); + /* Allocate process result information for each process. */ + free(cp->ProcessResults); + cp->ProcessResults = (kwsysProcessResults*)malloc( + sizeof(kwsysProcessResults) * (size_t)(cp->NumberOfCommands)); + if (!cp->ProcessResults) { + return 0; + } + memset(cp->ProcessResults, 0, + sizeof(kwsysProcessResults) * (size_t)(cp->NumberOfCommands)); + for (i = 0; i < cp->NumberOfCommands; i++) { + cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; + cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting; + cp->ProcessResults[i].ExitCode = 1; + cp->ProcessResults[i].ExitValue = 1; + strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception"); + } + /* Allocate memory to save the real working directory. */ if (cp->WorkingDirectory) { #if defined(MAXPATHLEN) @@ -1523,7 +1570,6 @@ static int kwsysProcessInitialize(kwsysProcess* cp) return 1; } -/*--------------------------------------------------------------------------*/ /* Free all resources used by the given kwsysProcess instance that were allocated by kwsysProcess_Execute. */ static void kwsysProcessCleanup(kwsysProcess* cp, int error) @@ -1590,7 +1636,6 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error) } } -/*--------------------------------------------------------------------------*/ /* Close the given file descriptor if it is open. Reset its value to -1. */ static void kwsysProcessCleanupDescriptor(int* pfd) { @@ -1603,7 +1648,6 @@ static void kwsysProcessCleanupDescriptor(int* pfd) } } -/*--------------------------------------------------------------------------*/ static void kwsysProcessClosePipes(kwsysProcess* cp) { int i; @@ -1636,7 +1680,6 @@ static void kwsysProcessClosePipes(kwsysProcess* cp) } } -/*--------------------------------------------------------------------------*/ static int kwsysProcessSetNonBlocking(int fd) { int flags = fcntl(fd, F_GETFL); @@ -1646,12 +1689,10 @@ static int kwsysProcessSetNonBlocking(int fd) return flags >= 0; } -/*--------------------------------------------------------------------------*/ #if defined(__VMS) int decc$set_child_standard_streams(int fd1, int fd2, int fd3); #endif -/*--------------------------------------------------------------------------*/ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, kwsysProcessCreateInformation* si) { @@ -1831,7 +1872,6 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, return 1; } -/*--------------------------------------------------------------------------*/ static void kwsysProcessDestroy(kwsysProcess* cp) { /* A child process has terminated. Reap it if it is one handled by @@ -1880,7 +1920,6 @@ static void kwsysProcessDestroy(kwsysProcess* cp) sigprocmask(SIG_SETMASK, &old_mask, 0); } -/*--------------------------------------------------------------------------*/ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name) { int fout; @@ -1906,7 +1945,6 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name) return 1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]) { /* Close the existing descriptor. */ @@ -1925,7 +1963,6 @@ static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]) return 1; } -/*--------------------------------------------------------------------------*/ /* Get the time at which either the process or user timeout will expire. Returns 1 if the user timeout is first, and 0 otherwise. */ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, @@ -1957,7 +1994,6 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, return 0; } -/*--------------------------------------------------------------------------*/ /* Get the length of time before the given timeout time arrives. Returns 1 if the time has already arrived, and 0 otherwise. */ static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, @@ -1992,7 +2028,6 @@ static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, } } -/*--------------------------------------------------------------------------*/ static kwsysProcessTime kwsysProcessTimeGetCurrent(void) { kwsysProcessTime current; @@ -2003,13 +2038,11 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void) return current; } -/*--------------------------------------------------------------------------*/ static double kwsysProcessTimeToDouble(kwsysProcessTime t) { return (double)t.tv_sec + (double)(t.tv_usec) * 0.000001; } -/*--------------------------------------------------------------------------*/ static kwsysProcessTime kwsysProcessTimeFromDouble(double d) { kwsysProcessTime t; @@ -2018,14 +2051,12 @@ static kwsysProcessTime kwsysProcessTimeFromDouble(double d) return t; } -/*--------------------------------------------------------------------------*/ static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2) { return ((in1.tv_sec < in2.tv_sec) || ((in1.tv_sec == in2.tv_sec) && (in1.tv_usec < in2.tv_usec))); } -/*--------------------------------------------------------------------------*/ static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2) { @@ -2039,7 +2070,6 @@ static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, return out; } -/*--------------------------------------------------------------------------*/ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2) { @@ -2053,11 +2083,11 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, return out; } -/*--------------------------------------------------------------------------*/ #define KWSYSPE_CASE(type, str) \ - cp->ExitException = kwsysProcess_Exception_##type; \ - strcpy(cp->ExitExceptionString, str) -static void kwsysProcessSetExitException(kwsysProcess* cp, int sig) + cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_##type; \ + strcpy(cp->ProcessResults[idx].ExitExceptionString, str) +static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int sig, + int idx) { switch (sig) { #ifdef SIGSEGV @@ -2243,14 +2273,13 @@ static void kwsysProcessSetExitException(kwsysProcess* cp, int sig) #endif #endif default: - cp->ExitException = kwsysProcess_Exception_Other; - sprintf(cp->ExitExceptionString, "Signal %d", sig); + cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_Other; + sprintf(cp->ProcessResults[idx].ExitExceptionString, "Signal %d", sig); break; } } #undef KWSYSPE_CASE -/*--------------------------------------------------------------------------*/ /* When the child process encounters an error before its program is invoked, this is called to report the error to the parent and exit. */ @@ -2269,7 +2298,6 @@ static void kwsysProcessChildErrorExit(int errorPipe) _exit(1); } -/*--------------------------------------------------------------------------*/ /* Restores all signal handlers to their default values. */ static void kwsysProcessRestoreDefaultSignalHandlers(void) { @@ -2377,13 +2405,11 @@ static void kwsysProcessRestoreDefaultSignalHandlers(void) #endif } -/*--------------------------------------------------------------------------*/ static void kwsysProcessExit(void) { _exit(0); } -/*--------------------------------------------------------------------------*/ #if !defined(__VMS) static pid_t kwsysProcessFork(kwsysProcess* cp, kwsysProcessCreateInformation* si) @@ -2433,7 +2459,6 @@ static pid_t kwsysProcessFork(kwsysProcess* cp, } #endif -/*--------------------------------------------------------------------------*/ /* We try to obtain process information by invoking the ps command. Here we define the command to call on each platform and the corresponding parsing format string. The parsing format should @@ -2457,7 +2482,6 @@ static pid_t kwsysProcessFork(kwsysProcess* cp, #define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n" #endif -/*--------------------------------------------------------------------------*/ static void kwsysProcessKill(pid_t process_id) { #if defined(__linux__) || defined(__CYGWIN__) @@ -2561,7 +2585,6 @@ static void kwsysProcessKill(pid_t process_id) #endif } -/*--------------------------------------------------------------------------*/ #if defined(__VMS) int decc$feature_get_index(const char* name); int decc$feature_set_value(int index, int mode, int value); @@ -2574,7 +2597,6 @@ static int kwsysProcessSetVMSFeature(const char* name, int value) } #endif -/*--------------------------------------------------------------------------*/ /* Global set of executing processes for use by the signal handler. This global instance will be zero-initialized by the compiler. */ typedef struct kwsysProcessInstances_s @@ -2590,7 +2612,6 @@ static struct sigaction kwsysProcessesOldSigChldAction; static struct sigaction kwsysProcessesOldSigIntAction; static struct sigaction kwsysProcessesOldSigTermAction; -/*--------------------------------------------------------------------------*/ static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses) { /* Block signals while we update the set of pipes to check. @@ -2611,7 +2632,6 @@ static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses) sigprocmask(SIG_SETMASK, &oldset, 0); } -/*--------------------------------------------------------------------------*/ static int kwsysProcessesAdd(kwsysProcess* cp) { /* Create a pipe through which the signal handler can notify the @@ -2721,7 +2741,6 @@ static int kwsysProcessesAdd(kwsysProcess* cp) return 1; } -/*--------------------------------------------------------------------------*/ static void kwsysProcessesRemove(kwsysProcess* cp) { /* Attempt to remove the given signal pipe from the signal handler set. */ @@ -2772,7 +2791,6 @@ static void kwsysProcessesRemove(kwsysProcess* cp) kwsysProcessCleanupDescriptor(&cp->SignalPipe); } -/*--------------------------------------------------------------------------*/ static void kwsysProcessesSignalHandler(int signum #if KWSYSPE_USE_SIGINFO , @@ -2884,7 +2902,6 @@ static void kwsysProcessesSignalHandler(int signum errno = old_errno; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_ResetStartTime(kwsysProcess* cp) { if (!cp) { diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index d10c733..5183e3d 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -86,7 +86,6 @@ typedef struct kwsysProcessCreateInformation_s HANDLE hStdError; } kwsysProcessCreateInformation; -/*--------------------------------------------------------------------------*/ typedef struct kwsysProcessPipeData_s kwsysProcessPipeData; static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd); static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, @@ -119,6 +118,8 @@ static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2); static void kwsysProcessSetExitException(kwsysProcess* cp, int code); +static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code, + int idx); static void kwsysProcessKillTree(int pid); static void kwsysProcessDisablePipeThreads(kwsysProcess* cp); static int kwsysProcessesInitialize(void); @@ -129,7 +130,6 @@ static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId, static void kwsysProcessesRemove(HANDLE hProcess); static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType); -/*--------------------------------------------------------------------------*/ /* A structure containing synchronization data for each thread. */ typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync; struct kwsysProcessPipeSync_s @@ -147,7 +147,6 @@ struct kwsysProcessPipeSync_s HANDLE Reset; }; -/*--------------------------------------------------------------------------*/ /* A structure containing data for each pipe's threads. */ struct kwsysProcessPipeData_s { @@ -183,7 +182,26 @@ struct kwsysProcessPipeData_s HANDLE Write; }; -/*--------------------------------------------------------------------------*/ +/* A structure containing results data for each process. */ +typedef struct kwsysProcessResults_s kwsysProcessResults; +struct kwsysProcessResults_s +{ + /* The status of the process. */ + int State; + + /* The exceptional behavior that terminated the process, if any. */ + int ExitException; + + /* The process exit code. */ + DWORD ExitCode; + + /* The process return code, if any. */ + int ExitValue; + + /* Description for the ExitException. */ + char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; +}; + /* Structure containing data used to implement the child's execution. */ struct kwsysProcess_s { @@ -249,15 +267,6 @@ struct kwsysProcess_s /* ------------- Data managed per call to Execute ------------- */ - /* The exceptional behavior that terminated the process, if any. */ - int ExitException; - - /* The process exit code. */ - DWORD ExitCode; - - /* The process return code, if any. */ - int ExitValue; - /* Index of last pipe to report data, if any. */ int CurrentIndex; @@ -289,8 +298,8 @@ struct kwsysProcess_s /* Buffer for error messages. */ char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1]; - /* Description for the ExitException. */ - char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; + /* process results. */ + kwsysProcessResults* ProcessResults; /* Windows process information data. */ PROCESS_INFORMATION* ProcessInformation; @@ -308,7 +317,6 @@ struct kwsysProcess_s HANDLE PipeChildStd[3]; }; -/*--------------------------------------------------------------------------*/ kwsysProcess* kwsysProcess_New(void) { int i; @@ -447,7 +455,6 @@ kwsysProcess* kwsysProcess_New(void) return cp; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Delete(kwsysProcess* cp) { int i; @@ -519,10 +526,10 @@ void kwsysProcess_Delete(kwsysProcess* cp) if (cp->CommandExitCodes) { free(cp->CommandExitCodes); } + free(cp->ProcessResults); free(cp); } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) { int i; @@ -543,7 +550,6 @@ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) return 1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) { int newNumberOfCommands; @@ -639,7 +645,6 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) { if (!cp) { @@ -653,7 +658,6 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) cp->TimeoutTime.QuadPart = -1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) { if (!cp) { @@ -685,7 +689,6 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) return 1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file) { char** pfile; @@ -727,7 +730,6 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file) return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared) { if (!cp) { @@ -756,7 +758,6 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2]) { HANDLE* pPipeNative = 0; @@ -796,7 +797,6 @@ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2]) } } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) { if (!cp) { @@ -819,7 +819,6 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) { if (!cp) { @@ -847,31 +846,32 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) } } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetState(kwsysProcess* cp) { return cp ? cp->State : kwsysProcess_State_Error; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitException(kwsysProcess* cp) { - return cp ? cp->ExitException : kwsysProcess_Exception_Other; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitException + : kwsysProcess_Exception_Other; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitValue(kwsysProcess* cp) { - return cp ? cp->ExitValue : -1; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitValue + : -1; } -/*--------------------------------------------------------------------------*/ int kwsysProcess_GetExitCode(kwsysProcess* cp) { - return cp ? cp->ExitCode : 0; + return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) + ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitCode + : 0; } -/*--------------------------------------------------------------------------*/ const char* kwsysProcess_GetErrorString(kwsysProcess* cp) { if (!cp) { @@ -882,18 +882,59 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp) return "Success"; } -/*--------------------------------------------------------------------------*/ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp) { - if (!cp) { + if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) { return "GetExceptionString called with NULL process management structure"; } else if (cp->State == kwsysProcess_State_Exception) { - return cp->ExitExceptionString; + return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString; } return "No exception"; } -/*--------------------------------------------------------------------------*/ +/* the index should be in array bound. */ +#define KWSYSPE_IDX_CHK(RET) \ + if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \ + KWSYSPE_DEBUG((stderr, "array index out of bound\n")); \ + return RET; \ + } + +int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(kwsysProcess_State_Error) + return cp->ProcessResults[idx].State; +} + +int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other) + return cp->ProcessResults[idx].ExitException; +} + +int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(-1) + return cp->ProcessResults[idx].ExitValue; +} + +int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK(-1) + return cp->CommandExitCodes[idx]; +} + +const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx) +{ + KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management " + "structure or index out of bound") + if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) { + return cp->ProcessResults[idx].ExitExceptionString; + } + return "No exception"; +} + +#undef KWSYSPE_IDX_CHK + void kwsysProcess_Execute(kwsysProcess* cp) { int i; @@ -1135,7 +1176,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) cp->Detached = cp->OptionDetach; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Disown(kwsysProcess* cp) { int i; @@ -1162,8 +1202,6 @@ void kwsysProcess_Disown(kwsysProcess* cp) cp->State = kwsysProcess_State_Disowned; } -/*--------------------------------------------------------------------------*/ - int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, double* userTimeout) { @@ -1289,7 +1327,6 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, } } -/*--------------------------------------------------------------------------*/ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) { int i; @@ -1338,25 +1375,29 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) /* The timeout expired. */ cp->State = kwsysProcess_State_Expired; } else { - /* The children exited. Report the outcome of the last process. */ - cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands - 1]; - if ((cp->ExitCode & 0xF0000000) == 0xC0000000) { - /* Child terminated due to exceptional behavior. */ - cp->State = kwsysProcess_State_Exception; - cp->ExitValue = 1; - kwsysProcessSetExitException(cp, cp->ExitCode); - } else { - /* Child exited without exception. */ - cp->State = kwsysProcess_State_Exited; - cp->ExitException = kwsysProcess_Exception_None; - cp->ExitValue = cp->ExitCode; + /* The children exited. Report the outcome of the child processes. */ + for (i = 0; i < cp->NumberOfCommands; ++i) { + cp->ProcessResults[i].ExitCode = cp->CommandExitCodes[i]; + if ((cp->ProcessResults[i].ExitCode & 0xF0000000) == 0xC0000000) { + /* Child terminated due to exceptional behavior. */ + cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exception; + cp->ProcessResults[i].ExitValue = 1; + kwsysProcessSetExitExceptionByIndex(cp, cp->ProcessResults[i].ExitCode, + i); + } else { + /* Child exited without exception. */ + cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exited; + cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; + cp->ProcessResults[i].ExitValue = cp->ProcessResults[i].ExitCode; + } } + /* support legacy state status value */ + cp->State = cp->ProcessResults[cp->NumberOfCommands - 1].State; } return 1; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Interrupt(kwsysProcess* cp) { int i; @@ -1394,7 +1435,6 @@ void kwsysProcess_Interrupt(kwsysProcess* cp) } } -/*--------------------------------------------------------------------------*/ void kwsysProcess_Kill(kwsysProcess* cp) { int i; @@ -1429,8 +1469,6 @@ void kwsysProcess_Kill(kwsysProcess* cp) for them to exit. */ } -/*--------------------------------------------------------------------------*/ - /* Function executed for each pipe's thread. Argument is a pointer to the kwsysProcessPipeData instance for this thread. @@ -1451,8 +1489,6 @@ DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd) return 0; } -/*--------------------------------------------------------------------------*/ - /* Function called in each pipe's thread to handle data for one execution of a subprocess. @@ -1494,8 +1530,6 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td) ReleaseSemaphore(td->Reader.Go, 1, 0); } -/*--------------------------------------------------------------------------*/ - /* Function executed for each pipe's thread. Argument is a pointer to the kwsysProcessPipeData instance for this thread. @@ -1516,8 +1550,6 @@ DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd) return 0; } -/*--------------------------------------------------------------------------*/ - /* Function called in each pipe's thread to handle reading thread wakeup for one execution of a subprocess. @@ -1540,23 +1572,34 @@ void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td) } } -/*--------------------------------------------------------------------------*/ /* Initialize a process control structure for kwsysProcess_Execute. */ int kwsysProcessInitialize(kwsysProcess* cp) { + int i; /* Reset internal status flags. */ cp->TimeoutExpired = 0; cp->Terminated = 0; cp->Killed = 0; - cp->ExitException = kwsysProcess_Exception_None; - cp->ExitCode = 1; - cp->ExitValue = 1; - /* Reset error data. */ - cp->ErrorMessage[0] = 0; - strcpy(cp->ExitExceptionString, "No exception"); + free(cp->ProcessResults); + /* Allocate process result information for each process. */ + cp->ProcessResults = (kwsysProcessResults*)malloc( + sizeof(kwsysProcessResults) * (cp->NumberOfCommands)); + if (!cp->ProcessResults) { + return 0; + } + ZeroMemory(cp->ProcessResults, + sizeof(kwsysProcessResults) * cp->NumberOfCommands); + for (i = 0; i < cp->NumberOfCommands; i++) { + cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; + cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting; + cp->ProcessResults[i].ExitCode = 1; + cp->ProcessResults[i].ExitValue = 1; + strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception"); + } /* Allocate process information for each process. */ + free(cp->ProcessInformation); cp->ProcessInformation = (PROCESS_INFORMATION*)malloc( sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands); if (!cp->ProcessInformation) { @@ -1596,7 +1639,6 @@ int kwsysProcessInitialize(kwsysProcess* cp) } } { - int i; for (i = 0; i < 3; ++i) { cp->PipeChildStd[i] = INVALID_HANDLE_VALUE; } @@ -1605,7 +1647,6 @@ int kwsysProcessInitialize(kwsysProcess* cp) return 1; } -/*--------------------------------------------------------------------------*/ static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn) { DWORD flags; @@ -1641,7 +1682,6 @@ static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn) } } -/*--------------------------------------------------------------------------*/ DWORD kwsysProcessCreate(kwsysProcess* cp, int index, kwsysProcessCreateInformation* si) { @@ -1706,7 +1746,6 @@ DWORD kwsysProcessCreate(kwsysProcess* cp, int index, return error; } -/*--------------------------------------------------------------------------*/ void kwsysProcessDestroy(kwsysProcess* cp, int event) { int i; @@ -1756,7 +1795,6 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event) } } -/*--------------------------------------------------------------------------*/ DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) { HANDLE fout; @@ -1784,7 +1822,6 @@ DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) return ERROR_SUCCESS; } -/*--------------------------------------------------------------------------*/ void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) { /* Close the existing handle. */ @@ -1793,7 +1830,6 @@ void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) *handle = GetStdHandle(nStdHandle); } -/*--------------------------------------------------------------------------*/ void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle) { /* Close the existing handle. */ @@ -1802,8 +1838,6 @@ void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle) *handle = native; } -/*--------------------------------------------------------------------------*/ - /* Close the given handle if it is open. Reset its value to 0. */ void kwsysProcessCleanupHandle(PHANDLE h) { @@ -1816,8 +1850,6 @@ void kwsysProcessCleanupHandle(PHANDLE h) } } -/*--------------------------------------------------------------------------*/ - /* Close all handles created by kwsysProcess_Execute. */ void kwsysProcessCleanup(kwsysProcess* cp, DWORD error) { @@ -1902,7 +1934,6 @@ void kwsysProcessCleanup(kwsysProcess* cp, DWORD error) } } -/*--------------------------------------------------------------------------*/ void kwsysProcessCleanErrorMessage(kwsysProcess* cp) { /* Remove trailing period and newline, if any. */ @@ -1920,7 +1951,6 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp) } } -/*--------------------------------------------------------------------------*/ /* Get the time at which either the process or user timeout will expire. Returns 1 if the user timeout is first, and 0 otherwise. */ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, @@ -1952,7 +1982,6 @@ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, return 0; } -/*--------------------------------------------------------------------------*/ /* Get the length of time before the given timeout time arrives. Returns 1 if the time has already arrived, and 0 otherwise. */ int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, @@ -1982,7 +2011,6 @@ int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, } } -/*--------------------------------------------------------------------------*/ kwsysProcessTime kwsysProcessTimeGetCurrent() { kwsysProcessTime current; @@ -1993,19 +2021,16 @@ kwsysProcessTime kwsysProcessTimeGetCurrent() return current; } -/*--------------------------------------------------------------------------*/ DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t) { return (DWORD)(t.QuadPart * 0.0001); } -/*--------------------------------------------------------------------------*/ double kwsysProcessTimeToDouble(kwsysProcessTime t) { return t.QuadPart * 0.0000001; } -/*--------------------------------------------------------------------------*/ kwsysProcessTime kwsysProcessTimeFromDouble(double d) { kwsysProcessTime t; @@ -2013,13 +2038,11 @@ kwsysProcessTime kwsysProcessTimeFromDouble(double d) return t; } -/*--------------------------------------------------------------------------*/ int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2) { return in1.QuadPart < in2.QuadPart; } -/*--------------------------------------------------------------------------*/ kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2) { @@ -2028,7 +2051,6 @@ kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, return out; } -/*--------------------------------------------------------------------------*/ kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2) { @@ -2037,11 +2059,11 @@ kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, return out; } -/*--------------------------------------------------------------------------*/ #define KWSYSPE_CASE(type, str) \ - cp->ExitException = kwsysProcess_Exception_##type; \ - strcpy(cp->ExitExceptionString, str) -static void kwsysProcessSetExitException(kwsysProcess* cp, int code) + cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_##type; \ + strcpy(cp->ProcessResults[idx].ExitExceptionString, str) +static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code, + int idx) { switch (code) { case STATUS_CONTROL_C_EXIT: @@ -2120,9 +2142,9 @@ static void kwsysProcessSetExitException(kwsysProcess* cp, int code) case STATUS_NO_MEMORY: default: - cp->ExitException = kwsysProcess_Exception_Other; - _snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE, - "Exit code 0x%x\n", code); + cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_Other; + _snprintf(cp->ProcessResults[idx].ExitExceptionString, + KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code); break; } } @@ -2136,7 +2158,6 @@ static int kwsysProcess_List_NextProcess(kwsysProcess_List* self); static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self); static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self); -/*--------------------------------------------------------------------------*/ /* Windows NT 4 API definitions. */ #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) typedef LONG NTSTATUS; @@ -2168,7 +2189,6 @@ struct _SYSTEM_PROCESS_INFORMATION ULONG InheritedFromProcessId; }; -/*--------------------------------------------------------------------------*/ /* Toolhelp32 API definitions. */ #define TH32CS_SNAPPROCESS 0x00000002 #if defined(_WIN64) @@ -2192,7 +2212,6 @@ struct tagPROCESSENTRY32 char szExeFile[MAX_PATH]; }; -/*--------------------------------------------------------------------------*/ /* Windows API function types. */ typedef HANDLE(WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD); typedef BOOL(WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32); @@ -2200,7 +2219,6 @@ typedef BOOL(WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32); typedef NTSTATUS(WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID, ULONG, PULONG); -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self); static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self); static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self); @@ -2233,7 +2251,6 @@ struct kwsysProcess_List_s PROCESSENTRY32 CurrentEntry; }; -/*--------------------------------------------------------------------------*/ static kwsysProcess_List* kwsysProcess_List_New(void) { OSVERSIONINFO osv; @@ -2279,7 +2296,6 @@ static kwsysProcess_List* kwsysProcess_List_New(void) return self; } -/*--------------------------------------------------------------------------*/ static void kwsysProcess_List_Delete(kwsysProcess_List* self) { if (self) { @@ -2292,7 +2308,6 @@ static void kwsysProcess_List_Delete(kwsysProcess_List* self) } } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List_Update(kwsysProcess_List* self) { return self ? (self->NT4 ? kwsysProcess_List__Update_NT4(self) @@ -2300,7 +2315,6 @@ static int kwsysProcess_List_Update(kwsysProcess_List* self) : 0; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self) { return self ? (self->NT4 ? kwsysProcess_List__GetProcessId_NT4(self) @@ -2308,7 +2322,6 @@ static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self) : -1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self) { return self ? (self->NT4 ? kwsysProcess_List__GetParentId_NT4(self) @@ -2316,7 +2329,6 @@ static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self) : -1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List_NextProcess(kwsysProcess_List* self) { return (self ? (self->NT4 ? kwsysProcess_List__Next_NT4(self) @@ -2324,7 +2336,6 @@ static int kwsysProcess_List_NextProcess(kwsysProcess_List* self) : 0); } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self) { /* Get a handle to the NT runtime module that should already be @@ -2348,7 +2359,6 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self) return self->Buffer ? 1 : 0; } -/*--------------------------------------------------------------------------*/ static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self) { /* Free the process information buffer. */ @@ -2357,7 +2367,6 @@ static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self) } } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self) { self->CurrentInfo = 0; @@ -2387,7 +2396,6 @@ static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self) } } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self) { if (self->CurrentInfo) { @@ -2401,19 +2409,16 @@ static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self) return 0; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self) { return self->CurrentInfo ? self->CurrentInfo->ProcessId : -1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self) { return self->CurrentInfo ? self->CurrentInfo->InheritedFromProcessId : -1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self) { /* Get a handle to the Windows runtime module that should already be @@ -2436,7 +2441,6 @@ static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self) : 0; } -/*--------------------------------------------------------------------------*/ static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self) { if (self->Snapshot) { @@ -2444,7 +2448,6 @@ static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self) } } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self) { if (self->Snapshot) { @@ -2464,7 +2467,6 @@ static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self) return 1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self) { if (self->Snapshot) { @@ -2477,19 +2479,16 @@ static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self) return 0; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self) { return self->Snapshot ? self->CurrentEntry.th32ProcessID : -1; } -/*--------------------------------------------------------------------------*/ static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self) { return self->Snapshot ? self->CurrentEntry.th32ParentProcessID : -1; } -/*--------------------------------------------------------------------------*/ static void kwsysProcessKill(DWORD pid) { HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid); @@ -2500,7 +2499,6 @@ static void kwsysProcessKill(DWORD pid) } } -/*--------------------------------------------------------------------------*/ static void kwsysProcessKillTree(int pid) { kwsysProcess_List* plist = kwsysProcess_List_New(); @@ -2516,7 +2514,6 @@ static void kwsysProcessKillTree(int pid) } } -/*--------------------------------------------------------------------------*/ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) { int i; @@ -2568,7 +2565,6 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) } } -/*--------------------------------------------------------------------------*/ /* Global set of executing processes for use by the Ctrl handler. This global instance will be zero-initialized by the compiler. @@ -2598,7 +2594,6 @@ typedef struct kwsysProcessInstances_s } kwsysProcessInstances; static kwsysProcessInstances kwsysProcesses; -/*--------------------------------------------------------------------------*/ /* Initialize critial section and set up console Ctrl handler. You MUST call this before using any other kwsysProcesses* functions below. */ static int kwsysProcessesInitialize(void) @@ -2617,7 +2612,6 @@ static int kwsysProcessesInitialize(void) return 1; } -/*--------------------------------------------------------------------------*/ /* The Ctrl handler waits on the global list of processes. To prevent an orphaned process, do not create a new process if the Ctrl handler is already running. Do so by using this function to check if it is ok to @@ -2636,7 +2630,6 @@ static int kwsysTryEnterCreateProcessSection(void) } } -/*--------------------------------------------------------------------------*/ /* Matching function on successful kwsysTryEnterCreateProcessSection return. Make sure you called kwsysProcessesAdd if applicable before calling this.*/ static void kwsysLeaveCreateProcessSection(void) @@ -2644,7 +2637,6 @@ static void kwsysLeaveCreateProcessSection(void) LeaveCriticalSection(&kwsysProcesses.Lock); } -/*--------------------------------------------------------------------------*/ /* Add new process to global process list. The Ctrl handler will wait for the process to exit before it returns. Do not close the process handle until after calling kwsysProcessesRemove. The newProcessGroup parameter @@ -2702,7 +2694,6 @@ static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid, return 1; } -/*--------------------------------------------------------------------------*/ /* Removes process to global process list. */ static void kwsysProcessesRemove(HANDLE hProcess) { @@ -2738,7 +2729,6 @@ static void kwsysProcessesRemove(HANDLE hProcess) LeaveCriticalSection(&kwsysProcesses.Lock); } -/*--------------------------------------------------------------------------*/ static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType) { size_t i; @@ -2774,7 +2764,6 @@ static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType) return FALSE; } -/*--------------------------------------------------------------------------*/ void kwsysProcess_ResetStartTime(kwsysProcess* cp) { if (!cp) { diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in index c9ae135..f638267 100644 --- a/Source/kwsys/SharedForward.h.in +++ b/Source/kwsys/SharedForward.h.in @@ -72,8 +72,6 @@ #pragma warn - 8019 #endif -/*--------------------------------------------------------------------------*/ - /* Full path to the directory in which this executable is built. Do not include a trailing slash. */ #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD) @@ -159,7 +157,6 @@ #undef KWSYS_SHARED_FORWARD_OPTION_LDD #endif -/*--------------------------------------------------------------------------*/ /* Include needed system headers. */ #include <errno.h> @@ -180,7 +177,6 @@ #include <unistd.h> #endif -/*--------------------------------------------------------------------------*/ /* Configuration for this platform. */ /* The path separator for this platform. */ @@ -292,7 +288,6 @@ static const char kwsys_shared_forward_path_slash[2] = { #endif #ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV -/*--------------------------------------------------------------------------*/ typedef struct kwsys_sf_arg_info_s { const char* arg; @@ -300,7 +295,6 @@ typedef struct kwsys_sf_arg_info_s int quote; } kwsys_sf_arg_info; -/*--------------------------------------------------------------------------*/ static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in) { /* Initialize information. */ @@ -354,7 +348,6 @@ static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in) return info; } -/*--------------------------------------------------------------------------*/ static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out) { /* String iterator. */ @@ -413,7 +406,6 @@ static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out) } #endif -/*--------------------------------------------------------------------------*/ /* Function to convert a logical or relative path to a physical full path. */ static int kwsys_shared_forward_realpath(const char* in_path, char* out_path) { @@ -428,7 +420,6 @@ static int kwsys_shared_forward_realpath(const char* in_path, char* out_path) #endif } -/*--------------------------------------------------------------------------*/ static int kwsys_shared_forward_samepath(const char* file1, const char* file2) { #if defined(_WIN32) @@ -458,7 +449,6 @@ static int kwsys_shared_forward_samepath(const char* file1, const char* file2) #endif } -/*--------------------------------------------------------------------------*/ /* Function to report a system error message. */ static void kwsys_shared_forward_strerror(char* message) { @@ -481,7 +471,6 @@ static void kwsys_shared_forward_strerror(char* message) #endif } -/*--------------------------------------------------------------------------*/ /* Functions to execute a child process. */ static void kwsys_shared_forward_execvp(const char* cmd, char const* const* argv) @@ -521,7 +510,6 @@ static void kwsys_shared_forward_execvp(const char* cmd, #endif } -/*--------------------------------------------------------------------------*/ /* Function to get the directory containing the given file or directory. */ static void kwsys_shared_forward_dirname(const char* begin, char* result) { @@ -557,7 +545,6 @@ static void kwsys_shared_forward_dirname(const char* begin, char* result) } } -/*--------------------------------------------------------------------------*/ /* Function to check if a file exists and is executable. */ static int kwsys_shared_forward_is_executable(const char* f) { @@ -578,7 +565,6 @@ static int kwsys_shared_forward_is_executable(const char* f) } } -/*--------------------------------------------------------------------------*/ /* Function to locate the executable currently running. */ static int kwsys_shared_forward_self_path(const char* argv0, char* result) { @@ -644,7 +630,6 @@ static int kwsys_shared_forward_self_path(const char* argv0, char* result) return 0; } -/*--------------------------------------------------------------------------*/ /* Function to convert a specified path to a full path. If it is not already full, it is taken relative to the self path. */ static int kwsys_shared_forward_fullpath(const char* self_path, @@ -681,7 +666,6 @@ static int kwsys_shared_forward_fullpath(const char* self_path, return 1; } -/*--------------------------------------------------------------------------*/ /* Function to compute the library search path and executable name based on the self path. */ static int kwsys_shared_forward_get_settings(const char* self_path, @@ -773,7 +757,6 @@ static int kwsys_shared_forward_get_settings(const char* self_path, return 1; } -/*--------------------------------------------------------------------------*/ /* Function to print why execution of a command line failed. */ static void kwsys_shared_forward_print_failure(char const* const* argv) { @@ -791,7 +774,6 @@ static void kwsys_shared_forward_print_failure(char const* const* argv) static char kwsys_shared_forward_ldpath[65535] = KWSYS_SHARED_FORWARD_LDPATH "="; -/*--------------------------------------------------------------------------*/ /* Main driver function to be called from main. */ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in) { diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c index 43c60c5..b9af8e9 100644 --- a/Source/kwsys/System.c +++ b/Source/kwsys/System.c @@ -22,7 +22,6 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t; typedef int kwsysSystem_ptrdiff_t; #endif -/*--------------------------------------------------------------------------*/ static int kwsysSystem__AppendByte(char* local, char** begin, char** end, int* size, char c) { @@ -47,7 +46,6 @@ static int kwsysSystem__AppendByte(char* local, char** begin, char** end, return 1; } -/*--------------------------------------------------------------------------*/ static int kwsysSystem__AppendArgument(char** local, char*** begin, char*** end, int* size, char* arg_local, char** arg_begin, char** arg_end, @@ -91,7 +89,6 @@ static int kwsysSystem__AppendArgument(char** local, char*** begin, return 1; } -/*--------------------------------------------------------------------------*/ #define KWSYSPE_LOCAL_BYTE_COUNT 1024 #define KWSYSPE_LOCAL_ARGS_COUNT 32 static char** kwsysSystem__ParseUnixCommand(const char* command, int flags) @@ -227,7 +224,6 @@ static char** kwsysSystem__ParseUnixCommand(const char* command, int flags) return newCommand; } -/*--------------------------------------------------------------------------*/ char** kwsysSystem_Parse_CommandForUnix(const char* command, int flags) { /* Validate the flags. */ diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 70f1a43..6b00fc6 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -838,7 +838,6 @@ void SystemInformation::RunMemoryCheck() this->Implementation->RunMemoryCheck(); } -// -------------------------------------------------------------- // SystemInformationImplementation starts here #define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x @@ -1314,7 +1313,6 @@ private: int ReportPath; }; -// -------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& os, const SymbolProperties& sp) { #if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP) @@ -1333,7 +1331,6 @@ std::ostream& operator<<(std::ostream& os, const SymbolProperties& sp) return os; } -// -------------------------------------------------------------------------- SymbolProperties::SymbolProperties() { // not using an initializer list @@ -1352,7 +1349,6 @@ SymbolProperties::SymbolProperties() this->GetLineNumber(); } -// -------------------------------------------------------------------------- std::string SymbolProperties::GetFileName(const std::string& path) const { std::string file(path); @@ -1365,7 +1361,6 @@ std::string SymbolProperties::GetFileName(const std::string& path) const return file; } -// -------------------------------------------------------------------------- std::string SymbolProperties::GetBinary() const { // only linux has proc fs @@ -1386,7 +1381,6 @@ std::string SymbolProperties::GetBinary() const return this->GetFileName(this->Binary); } -// -------------------------------------------------------------------------- std::string SymbolProperties::Demangle(const char* symbol) const { std::string result = safes(symbol); @@ -1406,7 +1400,6 @@ std::string SymbolProperties::Demangle(const char* symbol) const return result; } -// -------------------------------------------------------------------------- void SymbolProperties::Initialize(void* address) { this->Address = address; @@ -1425,7 +1418,6 @@ void SymbolProperties::Initialize(void* address) } #endif // don't define this class if we're not using it -// -------------------------------------------------------------------------- #if defined(_WIN32) || defined(__CYGWIN__) #define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes #endif diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index b6da368..5ca382f 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -547,8 +547,6 @@ bool SystemTools::HasEnv(const std::string& key) return SystemTools::HasEnv(key.c_str()); } -//---------------------------------------------------------------------------- - #if KWSYS_CXX_HAS_UNSETENV /* unsetenv("A") removes A from the environment. On older platforms it returns void instead of int. */ @@ -639,8 +637,6 @@ static int kwsysUnPutEnv(const std::string& env) } #endif -//---------------------------------------------------------------------------- - #if KWSYS_CXX_HAS_SETENV /* setenv("A", "B", 1) will set A=B in the environment and makes its @@ -731,8 +727,6 @@ bool SystemTools::UnPutEnv(const std::string& env) #endif -//---------------------------------------------------------------------------- - const char* SystemTools::GetExecutableExtension() { #if defined(_WIN32) || defined(__CYGWIN__) || defined(__VMS) @@ -1144,7 +1138,6 @@ bool SystemTools::SameFile(const std::string& file1, const std::string& file2) #endif } -//---------------------------------------------------------------------------- bool SystemTools::PathExists(const std::string& path) { if (path.empty()) { @@ -1167,7 +1160,6 @@ bool SystemTools::PathExists(const std::string& path) #endif } -//---------------------------------------------------------------------------- bool SystemTools::FileExists(const char* filename) { if (!filename) { @@ -1176,7 +1168,6 @@ bool SystemTools::FileExists(const char* filename) return SystemTools::FileExists(std::string(filename)); } -//---------------------------------------------------------------------------- bool SystemTools::FileExists(const std::string& filename) { if (filename.empty()) { @@ -1203,7 +1194,6 @@ bool SystemTools::FileExists(const std::string& filename) #endif } -//---------------------------------------------------------------------------- bool SystemTools::FileExists(const char* filename, bool isFile) { if (!filename) { @@ -1212,7 +1202,6 @@ bool SystemTools::FileExists(const char* filename, bool isFile) return SystemTools::FileExists(std::string(filename), isFile); } -//---------------------------------------------------------------------------- bool SystemTools::FileExists(const std::string& filename, bool isFile) { if (SystemTools::FileExists(filename)) { @@ -1223,7 +1212,6 @@ bool SystemTools::FileExists(const std::string& filename, bool isFile) return false; } -//---------------------------------------------------------------------------- bool SystemTools::TestFileAccess(const char* filename, TestFilePermissions permissions) { @@ -1233,7 +1221,6 @@ bool SystemTools::TestFileAccess(const char* filename, return SystemTools::TestFileAccess(std::string(filename), permissions); } -//---------------------------------------------------------------------------- bool SystemTools::TestFileAccess(const std::string& filename, TestFilePermissions permissions) { @@ -1255,7 +1242,6 @@ bool SystemTools::TestFileAccess(const std::string& filename, #endif } -//---------------------------------------------------------------------------- int SystemTools::Stat(const char* path, SystemTools::Stat_t* buf) { if (!path) { @@ -1265,7 +1251,6 @@ int SystemTools::Stat(const char* path, SystemTools::Stat_t* buf) return SystemTools::Stat(std::string(path), buf); } -//---------------------------------------------------------------------------- int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf) { if (path.empty()) { @@ -1287,7 +1272,6 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf) #endif } -//---------------------------------------------------------------------------- #ifdef __CYGWIN__ bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path) { @@ -1752,7 +1736,6 @@ std::string SystemTools::CropString(const std::string& s, size_t max_len) return n; } -//---------------------------------------------------------------------------- std::vector<kwsys::String> SystemTools::SplitString(const std::string& p, char sep, bool isPath) { @@ -1777,7 +1760,6 @@ std::vector<kwsys::String> SystemTools::SplitString(const std::string& p, return paths; } -//---------------------------------------------------------------------------- int SystemTools::EstimateFormatLength(const char* format, va_list ap) { if (!format) { @@ -2165,7 +2147,6 @@ bool SystemTools::FilesDiffer(const std::string& source, return false; } -//---------------------------------------------------------------------------- /** * Copy a file named by "source" to the file named by "destination". */ @@ -2269,7 +2250,6 @@ bool SystemTools::CopyFileAlways(const std::string& source, return true; } -//---------------------------------------------------------------------------- bool SystemTools::CopyAFile(const std::string& source, const std::string& destination, bool always) { @@ -3550,7 +3530,6 @@ static std::string GetCasePathName(std::string const& pathIn) } #endif -//---------------------------------------------------------------------------- std::string SystemTools::GetActualCaseForPath(const std::string& p) { #ifndef _WIN32 @@ -3571,7 +3550,6 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p) #endif } -//---------------------------------------------------------------------------- const char* SystemTools::SplitPathRootComponent(const std::string& p, std::string* root) { @@ -3638,7 +3616,6 @@ const char* SystemTools::SplitPathRootComponent(const std::string& p, return c; } -//---------------------------------------------------------------------------- void SystemTools::SplitPath(const std::string& p, std::vector<std::string>& components, bool expand_home_dir) @@ -3695,13 +3672,11 @@ void SystemTools::SplitPath(const std::string& p, } } -//---------------------------------------------------------------------------- std::string SystemTools::JoinPath(const std::vector<std::string>& components) { return SystemTools::JoinPath(components.begin(), components.end()); } -//---------------------------------------------------------------------------- std::string SystemTools::JoinPath( std::vector<std::string>::const_iterator first, std::vector<std::string>::const_iterator last) @@ -3733,7 +3708,6 @@ std::string SystemTools::JoinPath( return result; } -//---------------------------------------------------------------------------- bool SystemTools::ComparePath(const std::string& c1, const std::string& c2) { #if defined(_WIN32) || defined(__APPLE__) @@ -3749,7 +3723,6 @@ bool SystemTools::ComparePath(const std::string& c1, const std::string& c2) #endif } -//---------------------------------------------------------------------------- bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines, char separator) { @@ -3770,7 +3743,6 @@ bool SystemTools::Split(const std::string& str, return true; } -//---------------------------------------------------------------------------- bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines) { @@ -4707,7 +4679,6 @@ std::string SystemTools::GetOperatingSystemNameAndVersion() return res; } -// ---------------------------------------------------------------------- bool SystemTools::ParseURLProtocol(const std::string& URL, std::string& protocol, std::string& dataglom) @@ -4726,7 +4697,6 @@ bool SystemTools::ParseURLProtocol(const std::string& URL, return true; } -// ---------------------------------------------------------------------- bool SystemTools::ParseURL(const std::string& URL, std::string& protocol, std::string& username, std::string& password, std::string& hostname, std::string& dataport, @@ -4757,7 +4727,6 @@ bool SystemTools::ParseURL(const std::string& URL, std::string& protocol, return true; } -// ---------------------------------------------------------------------- // These must NOT be initialized. Default initialization to zero is // necessary. static unsigned int SystemToolsManagerCount; diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index c0b7f45..eaa5c7d 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -9,7 +9,6 @@ #include "Terminal.h.in" #endif -/*--------------------------------------------------------------------------*/ /* Configure support for this platform. */ #if defined(_WIN32) || defined(__CYGWIN__) #define KWSYS_TERMINAL_SUPPORT_CONSOLE @@ -18,7 +17,6 @@ #define KWSYS_TERMINAL_ISATTY_WORKS #endif -/*--------------------------------------------------------------------------*/ /* Include needed system APIs. */ #include <stdarg.h> /* va_list */ @@ -36,7 +34,6 @@ #include <sys/stat.h> /* fstat */ #endif -/*--------------------------------------------------------------------------*/ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, int default_tty); static void kwsysTerminalSetVT100Color(FILE* stream, int color); @@ -47,7 +44,6 @@ static void kwsysTerminalSetConsoleColor(HANDLE hOut, FILE* stream, int color); #endif -/*--------------------------------------------------------------------------*/ void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...) { /* Setup the stream with the given color if possible. */ @@ -89,7 +85,6 @@ void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...) } } -/*--------------------------------------------------------------------------*/ /* Detect cases when a stream is definitely not interactive. */ #if !defined(KWSYS_TERMINAL_ISATTY_WORKS) static int kwsysTerminalStreamIsNotInteractive(FILE* stream) @@ -106,7 +101,6 @@ static int kwsysTerminalStreamIsNotInteractive(FILE* stream) } #endif -/*--------------------------------------------------------------------------*/ /* List of terminal names known to support VT100 color escape sequences. */ static const char* kwsysTerminalVT100Names[] = { "Eterm", "ansi", @@ -162,7 +156,6 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm", "xterm-termite", 0 }; -/*--------------------------------------------------------------------------*/ /* Detect whether a stream is displayed in a VT100-compatible terminal. */ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, int default_tty) @@ -214,7 +207,6 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, #endif } -/*--------------------------------------------------------------------------*/ /* VT100 escape sequence strings. */ #define KWSYS_TERMINAL_VT100_NORMAL "\33[0m" #define KWSYS_TERMINAL_VT100_BOLD "\33[1m" @@ -238,7 +230,6 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, #define KWSYS_TERMINAL_VT100_BACKGROUND_CYAN "\33[46m" #define KWSYS_TERMINAL_VT100_BACKGROUND_WHITE "\33[47m" -/*--------------------------------------------------------------------------*/ /* Write VT100 escape sequences to the stream for the given color. */ static void kwsysTerminalSetVT100Color(FILE* stream, int color) { @@ -307,7 +298,6 @@ static void kwsysTerminalSetVT100Color(FILE* stream, int color) } } -/*--------------------------------------------------------------------------*/ #if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) #define KWSYS_TERMINAL_MASK_FOREGROUND \ diff --git a/Source/kwsys/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c index d12fac0..64a361b 100644 --- a/Source/kwsys/kwsysPlatformTestsC.c +++ b/Source/kwsys/kwsysPlatformTestsC.c @@ -27,7 +27,6 @@ main(int argc, char* argv[]) #endif -/*--------------------------------------------------------------------------*/ #ifdef TEST_KWSYS_C_HAS_PTRDIFF_T #include <stddef.h> int f(ptrdiff_t n) @@ -43,7 +42,6 @@ int KWSYS_PLATFORM_TEST_C_MAIN() } #endif -/*--------------------------------------------------------------------------*/ #ifdef TEST_KWSYS_C_HAS_SSIZE_T #include <unistd.h> int f(ssize_t n) @@ -57,7 +55,6 @@ int KWSYS_PLATFORM_TEST_C_MAIN() } #endif -/*--------------------------------------------------------------------------*/ #ifdef TEST_KWSYS_C_TYPE_MACROS char* info_macros = #if defined(__SIZEOF_SHORT__) diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx index 3b8cdab..21930f9 100644 --- a/Source/kwsys/testConsoleBuf.cxx +++ b/Source/kwsys/testConsoleBuf.cxx @@ -74,7 +74,6 @@ std::basic_streambuf<wchar_t>* errstream(const wchar_t* unused) return std::wcerr.rdbuf(); } -//---------------------------------------------------------------------------- template <typename T> static void dumpBuffers(const T* expected, const T* received, size_t size) { @@ -107,7 +106,6 @@ static void dumpBuffers(const T* expected, const T* received, size_t size) std::cerr << std::endl; } -//---------------------------------------------------------------------------- static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) { BOOL bInheritHandles = FALSE; @@ -158,7 +156,6 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) return success; } -//---------------------------------------------------------------------------- static void finishProcess(bool success) { if (success) { @@ -172,7 +169,6 @@ static void finishProcess(bool success) CloseHandle(processInfo.hThread); } -//---------------------------------------------------------------------------- static bool createPipe(PHANDLE readPipe, PHANDLE writePipe) { SECURITY_ATTRIBUTES securityAttributes; @@ -183,7 +179,6 @@ static bool createPipe(PHANDLE readPipe, PHANDLE writePipe) : true; } -//---------------------------------------------------------------------------- static void finishPipe(HANDLE readPipe, HANDLE writePipe) { if (readPipe != INVALID_HANDLE_VALUE) { @@ -194,7 +189,6 @@ static void finishPipe(HANDLE readPipe, HANDLE writePipe) } } -//---------------------------------------------------------------------------- static HANDLE createFile(LPCWSTR fileName) { SECURITY_ATTRIBUTES securityAttributes; @@ -218,7 +212,6 @@ static HANDLE createFile(LPCWSTR fileName) return file; } -//---------------------------------------------------------------------------- static void finishFile(HANDLE file) { if (file != INVALID_HANDLE_VALUE) { @@ -226,8 +219,6 @@ static void finishFile(HANDLE file) } } -//---------------------------------------------------------------------------- - #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC (0) #endif @@ -269,7 +260,6 @@ static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr) inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0; } -//---------------------------------------------------------------------------- static int testPipe() { int didFail = 1; @@ -377,7 +367,6 @@ static int testPipe() return didFail; } -//---------------------------------------------------------------------------- static int testFile() { int didFail = 1; @@ -487,7 +476,6 @@ static int testFile() #define _WIN32_WINNT_VISTA 0x0600 #endif -//---------------------------------------------------------------------------- static int testConsole() { int didFail = 1; @@ -748,7 +736,6 @@ static int testConsole() #endif -//---------------------------------------------------------------------------- int testConsoleBuf(int, char* []) { int ret = 0; diff --git a/Source/kwsys/testConsoleBufChild.cxx b/Source/kwsys/testConsoleBufChild.cxx index 83bf545..6a743ed 100644 --- a/Source/kwsys/testConsoleBufChild.cxx +++ b/Source/kwsys/testConsoleBufChild.cxx @@ -16,7 +16,6 @@ #include "testConsoleBuf.hxx" -//---------------------------------------------------------------------------- int main(int argc, const char* argv[]) { #if defined(_WIN32) diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx index 457e8a8..2c5ef46 100644 --- a/Source/kwsys/testEncoding.cxx +++ b/Source/kwsys/testEncoding.cxx @@ -22,7 +22,6 @@ #include "Encoding.hxx.in" #endif -//---------------------------------------------------------------------------- static const unsigned char helloWorldStrings[][32] = { // English { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 }, @@ -50,7 +49,6 @@ static const unsigned char helloWorldStrings[][32] = { { 0 } }; -//---------------------------------------------------------------------------- static int testHelloWorldEncoding() { int ret = 0; @@ -262,7 +260,6 @@ static int testToWindowsExtendedPath() #endif } -//---------------------------------------------------------------------------- int testEncoding(int, char* []) { const char* loc = setlocale(LC_ALL, ""); diff --git a/Source/kwsys/testFStream.cxx b/Source/kwsys/testFStream.cxx index 670f5e7..a92a781 100644 --- a/Source/kwsys/testFStream.cxx +++ b/Source/kwsys/testFStream.cxx @@ -20,7 +20,6 @@ #include <iostream> -//---------------------------------------------------------------------------- static int testNoFile() { kwsys::ifstream in_file("NoSuchFile.txt"); @@ -69,7 +68,6 @@ static unsigned char file_data[num_test_files][max_test_file_size] = { 0x72, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64 }, }; -//---------------------------------------------------------------------------- static int testBOM() { // test various encodings in binary mode @@ -104,7 +102,6 @@ static int testBOM() return 0; } -//---------------------------------------------------------------------------- int testFStream(int, char* []) { int ret = 0; diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index d11bcae..900894c 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -35,7 +35,6 @@ typedef unsigned short mode_t; #endif -//---------------------------------------------------------------------------- static const char* toUnixPaths[][2] = { { "/usr/local/bin/passwd", "/usr/local/bin/passwd" }, { "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" }, @@ -67,7 +66,6 @@ static bool CheckConvertToUnixSlashes(std::string input, std::string output) return true; } -//---------------------------------------------------------------------------- static const char* checkEscapeChars[][4] = { { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2" }, { " {} ", "{}", "#", " #{#} " }, @@ -86,7 +84,6 @@ static bool CheckEscapeChars(std::string input, const char* chars_to_escape, return true; } -//---------------------------------------------------------------------------- static bool CheckFileOperations() { bool res = true; @@ -469,7 +466,6 @@ static bool CheckFileOperations() return res; } -//---------------------------------------------------------------------------- static bool CheckStringOperations() { bool res = true; @@ -613,8 +609,6 @@ static bool CheckStringOperations() return res; } -//---------------------------------------------------------------------------- - static bool CheckPutEnv(const std::string& env, const char* name, const char* value) { @@ -842,7 +836,6 @@ static bool CheckGetLineFromStream() return ret; } -//---------------------------------------------------------------------------- int testSystemTools(int, char* []) { bool res = true; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 8d8b3aa..4b335bd 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1391,6 +1391,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release if(CMake_TEST_FindGTest) add_subdirectory(FindGTest) + add_subdirectory(GoogleTest) endif() if(CMake_TEST_FindICU) diff --git a/Tests/FindGTest/Test/CMakeLists.txt b/Tests/FindGTest/Test/CMakeLists.txt index 99368ac..b65b9d2 100644 --- a/Tests/FindGTest/Test/CMakeLists.txt +++ b/Tests/FindGTest/Test/CMakeLists.txt @@ -2,9 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(TestFindGTest CXX) include(CTest) -# CMake does not actually provide FindGTest publicly. -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules) - find_package(GTest REQUIRED) add_executable(test_gtest_tgt main.cxx) diff --git a/Tests/FindTIFF/Test/CMakeLists.txt b/Tests/FindTIFF/Test/CMakeLists.txt index 6985e3f..85453ed 100644 --- a/Tests/FindTIFF/Test/CMakeLists.txt +++ b/Tests/FindTIFF/Test/CMakeLists.txt @@ -2,9 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(TestFindTIFF C) include(CTest) -# CMake does not actually provide FindTIFF publicly. -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules) - find_package(TIFF REQUIRED) add_executable(test_tiff_tgt main.c) diff --git a/Tests/FindXalanC/Test/CMakeLists.txt b/Tests/FindXalanC/Test/CMakeLists.txt index b445e0e..a8c2a0a 100644 --- a/Tests/FindXalanC/Test/CMakeLists.txt +++ b/Tests/FindXalanC/Test/CMakeLists.txt @@ -2,9 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(TestFindXalanC CXX) include(CTest) -# CMake does not actually provide FindXalanC publicly. -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules) - find_package(XalanC REQUIRED) add_executable(test_xalanc_tgt main.cxx) diff --git a/Tests/FindXercesC/Test/CMakeLists.txt b/Tests/FindXercesC/Test/CMakeLists.txt index 8e7767c..267c6a9 100644 --- a/Tests/FindXercesC/Test/CMakeLists.txt +++ b/Tests/FindXercesC/Test/CMakeLists.txt @@ -2,9 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(TestFindXercesC CXX) include(CTest) -# CMake does not actually provide FindXercesC publicly. -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules) - find_package(XercesC REQUIRED) add_executable(test_xercesc_tgt main.cxx) diff --git a/Tests/GoogleTest/CMakeLists.txt b/Tests/GoogleTest/CMakeLists.txt new file mode 100644 index 0000000..21f8b8b --- /dev/null +++ b/Tests/GoogleTest/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME GoogleTest.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/GoogleTest/Test" + "${CMake_BINARY_DIR}/Tests/GoogleTest/Test" + ${build_generator_args} + --build-project TestGoogleTest + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/GoogleTest/Test/CMakeLists.txt b/Tests/GoogleTest/Test/CMakeLists.txt new file mode 100644 index 0000000..a1f08d4 --- /dev/null +++ b/Tests/GoogleTest/Test/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 3.8) +project(TestGoogleTest) +include(CTest) + +include(GoogleTest) + +find_package(GTest REQUIRED) + +add_executable(test_gtest1 main1.cxx) +target_link_libraries(test_gtest1 GTest::GTest) + +# Simple test of defaults +gtest_add_tests(TARGET test_gtest1 + TEST_LIST testList +) +set(expectedTests + GoogleTest.LinksAndRuns + GoogleTest.ConditionalFail +) +if(NOT testList STREQUAL "${expectedTests}") + message(FATAL_ERROR "Expected test list: ${expectedTests} +Actual test list: ${testList}") +endif() + + +# Same target, different arguments, so use test prefix and suffix to +# differentiate from the above test cases +gtest_add_tests(TARGET test_gtest1 + TEST_LIST testList + TEST_PREFIX "set2." + TEST_SUFFIX ".foo" + EXTRA_ARGS --forceFail +) + +set(expectedTests + set2.GoogleTest.LinksAndRuns.foo + set2.GoogleTest.ConditionalFail.foo +) +if(NOT testList STREQUAL "${expectedTests}") + message(FATAL_ERROR "Expected test list: ${expectedTests} +Actual test list: ${testList}") +endif() + +set_tests_properties(set2.GoogleTest.ConditionalFail.foo PROPERTIES WILL_FAIL YES) + + +# Search specific sources to get the test list +add_executable(test_gtest2 main2.cxx) +target_link_libraries(test_gtest2 GTest::Main) +gtest_add_tests(TARGET test_gtest2 + TEST_LIST testList + SOURCES main2.h +) +set(expectedTests + GoogleTest.SomethingElse +) +if(NOT testList STREQUAL "${expectedTests}") + message(FATAL_ERROR "Expected test list: ${expectedTests} +Actual test list: ${testList}") +endif() + + +# Non-keyword form, auto-find sources +add_executable(test_gtest3 main3.cxx) +target_link_libraries(test_gtest3 GTest::Main) +gtest_add_tests(test_gtest3 "" AUTO) +if(NOT TEST GoogleTest.Foo) + message(FATAL_ERROR "Test case GoogleTest.Foo not defined") +endif() +if(NOT TEST GoogleTest.Bar) + message(FATAL_ERROR "Test case GoogleTest.Bar not defined") +endif() + + +# Non-keyword form, explicitly specified sources. Allows a non-target to be +# given for the executable. +add_executable(test_gtest4 main4.cxx) +target_link_libraries(test_gtest4 GTest::Main) +gtest_add_tests($<TARGET_FILE:test_gtest4> "" main4.h) +if(NOT TEST GoogleTest.NoKeywords) + message(FATAL_ERROR "Test case GoogleTest.NoKeywords not defined") +endif() diff --git a/Tests/GoogleTest/Test/main1.cxx b/Tests/GoogleTest/Test/main1.cxx new file mode 100644 index 0000000..03d604b --- /dev/null +++ b/Tests/GoogleTest/Test/main1.cxx @@ -0,0 +1,30 @@ +#include <gtest/gtest.h> + +#include <string> + +namespace { +bool shouldFail = false; +} + +TEST(GoogleTest, LinksAndRuns) +{ + ASSERT_TRUE(true); +} + +TEST(GoogleTest, ConditionalFail) +{ + ASSERT_FALSE(shouldFail); +} + +int main(int argc, char* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + + if (argc > 1) { + if (argv[1] != std::string("--forceFail")) { + throw "Unexpected argument"; + } + shouldFail = true; + } + return RUN_ALL_TESTS(); +} diff --git a/Tests/GoogleTest/Test/main2.cxx b/Tests/GoogleTest/Test/main2.cxx new file mode 100644 index 0000000..05ffb4a --- /dev/null +++ b/Tests/GoogleTest/Test/main2.cxx @@ -0,0 +1 @@ +#include "main2.h" diff --git a/Tests/GoogleTest/Test/main2.h b/Tests/GoogleTest/Test/main2.h new file mode 100644 index 0000000..7243f53 --- /dev/null +++ b/Tests/GoogleTest/Test/main2.h @@ -0,0 +1,6 @@ +#include <gtest/gtest.h> + +TEST(GoogleTest, SomethingElse) +{ + ASSERT_TRUE(true); +} diff --git a/Tests/GoogleTest/Test/main3.cxx b/Tests/GoogleTest/Test/main3.cxx new file mode 100644 index 0000000..98ce13c --- /dev/null +++ b/Tests/GoogleTest/Test/main3.cxx @@ -0,0 +1,11 @@ +#include <gtest/gtest.h> + +TEST(GoogleTest, Foo) +{ + ASSERT_TRUE(true); +} + +TEST(GoogleTest, Bar) +{ + ASSERT_TRUE(true); +} diff --git a/Tests/GoogleTest/Test/main4.cxx b/Tests/GoogleTest/Test/main4.cxx new file mode 100644 index 0000000..8023bc1 --- /dev/null +++ b/Tests/GoogleTest/Test/main4.cxx @@ -0,0 +1 @@ +#include "main4.h" diff --git a/Tests/GoogleTest/Test/main4.h b/Tests/GoogleTest/Test/main4.h new file mode 100644 index 0000000..19da12a --- /dev/null +++ b/Tests/GoogleTest/Test/main4.h @@ -0,0 +1,6 @@ +#include <gtest/gtest.h> + +TEST(GoogleTest, NoKeywords) +{ + ASSERT_TRUE(true); +} diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index 752ce8a..faf151a 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -5,7 +5,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake") # run_cpack_test args: TEST_NAME "GENERATORS" RUN_CMAKE_BUILD_STEP "PACKAGING_TYPES" run_cpack_test(CUSTOM_BINARY_SPEC_FILE "RPM" false "MONOLITHIC;COMPONENT") -run_cpack_test(CUSTOM_NAMES "RPM;DEB" true "COMPONENT") +run_cpack_test(CUSTOM_NAMES "RPM;DEB;TGZ" true "COMPONENT") run_cpack_test(DEBUGINFO "RPM" true "COMPONENT") run_cpack_test(DEPENDENCIES "RPM;DEB" true "COMPONENT") run_cpack_test(DIST "RPM" false "MONOLITHIC") diff --git a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake index ae5f0af..5cb280c 100644 --- a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake @@ -9,4 +9,7 @@ set(EXPECTED_FILE_CONTENT_3_LIST "/usr;/usr/foo;/usr/foo/CMakeLists.txt") if(GENERATOR_TYPE STREQUAL "DEB" OR GENERATOR_TYPE STREQUAL "RPM") string(TOLOWER "${GENERATOR_TYPE}" file_extension_) set(EXPECTED_FILE_3 "pkg_3_abc.${file_extension_}") +elseif(GENERATOR_TYPE STREQUAL "TGZ") + set(EXPECTED_FILE_2 "second.tar.gz") + set(EXPECTED_FILE_3 "pkg_3_abc.tar.gz") endif() diff --git a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake index 0c2b37b..4c20e41 100644 --- a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake +++ b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake @@ -7,6 +7,9 @@ if(GENERATOR_TYPE STREQUAL "DEB" OR GENERATOR_TYPE STREQUAL "RPM") set(CPACK_${GENERATOR_TYPE}${generator_type_suffix_}_PKG_2_PACKAGE_NAME "second") string(TOLOWER "${GENERATOR_TYPE}" file_extension_) set(CPACK_${GENERATOR_TYPE}${generator_type_suffix_}_PKG_3_FILE_NAME "pkg_3_abc.${file_extension_}") +elseif(GENERATOR_TYPE STREQUAL "TGZ") + set(CPACK_ARCHIVE_PKG_2_FILE_NAME "second") + set(CPACK_ARCHIVE_PKG_3_FILE_NAME "pkg_3_abc") endif() install(FILES CMakeLists.txt DESTINATION foo COMPONENT pkg_1) diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt index 9289e84..4e4a030 100644 --- a/Tests/SourceGroups/CMakeLists.txt +++ b/Tests/SourceGroups/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 3.8) project(SourceGroups) # this is not really a test which can fail @@ -33,10 +33,11 @@ source_group(EmptyGroup) set(root ${CMAKE_CURRENT_SOURCE_DIR}) set(tree_files_without_prefix ${root}/sub1/tree_bar.c - ${root}/sub1/tree_baz.c - ${root}/sub1/tree_subdir/tree_foobar.c) + sub1/tree_baz.c + sub1/../sub1/tree_subdir/tree_foobar.c) -set(tree_files_with_prefix ${root}/tree_foo.c) +set(tree_files_with_prefix ${root}/tree_prefix_foo.c + tree_prefix_bar.c) source_group(TREE ${root} FILES ${tree_files_without_prefix}) diff --git a/Tests/SourceGroups/main.c b/Tests/SourceGroups/main.c index b88f2f8..4d84cf2 100644 --- a/Tests/SourceGroups/main.c +++ b/Tests/SourceGroups/main.c @@ -5,7 +5,8 @@ extern int bar(void); extern int foobar(void); extern int barbar(void); extern int baz(void); -extern int tree_foo(void); +extern int tree_prefix_foo(void); +extern int tree_prefix_bar(void); extern int tree_bar(void); extern int tree_foobar(void); extern int tree_baz(void); @@ -15,7 +16,9 @@ int main() printf("foo: %d bar: %d foobar: %d barbar: %d baz: %d\n", foo(), bar(), foobar(), barbar(), baz()); - printf("tree_foo: %d tree_bar: %d tree_foobar: %d tree_baz: %d\n", - tree_foo(), tree_bar(), tree_foobar(), tree_baz()); + printf("tree_prefix_foo: %d tree_prefix_bar: %d tree_bar: %d tree_foobar: " + "%d tree_baz: %d\n", + tree_prefix_foo(), tree_prefix_bar(), tree_bar(), tree_foobar(), + tree_baz()); return 0; } diff --git a/Tests/SourceGroups/tree_foo.c b/Tests/SourceGroups/tree_foo.c deleted file mode 100644 index d392e41..0000000 --- a/Tests/SourceGroups/tree_foo.c +++ /dev/null @@ -1,4 +0,0 @@ -int tree_foo(void) -{ - return 6; -} diff --git a/Tests/SourceGroups/tree_prefix_bar.c b/Tests/SourceGroups/tree_prefix_bar.c new file mode 100644 index 0000000..bd98476 --- /dev/null +++ b/Tests/SourceGroups/tree_prefix_bar.c @@ -0,0 +1,4 @@ +int tree_prefix_bar(void) +{ + return 66; +} diff --git a/Tests/SourceGroups/tree_prefix_foo.c b/Tests/SourceGroups/tree_prefix_foo.c new file mode 100644 index 0000000..92c2fd7 --- /dev/null +++ b/Tests/SourceGroups/tree_prefix_foo.c @@ -0,0 +1,4 @@ +int tree_prefix_foo(void) +{ + return 6; +} diff --git a/Utilities/Release/osx_release.cmake b/Utilities/Release/osx_release.cmake index 88ea39b..36498a7 100644 --- a/Utilities/Release/osx_release.cmake +++ b/Utilities/Release/osx_release.cmake @@ -27,7 +27,7 @@ CMAKE_SKIP_RPATH:BOOL=TRUE CMake_TEST_NO_FindPackageModeMakefileTest:BOOL=TRUE ") set(ENV [[ -export CMAKE_PREFIX_PATH='/Users/kitware/SDKs/qt-5.6.0-clang-x64' +export CMAKE_PREFIX_PATH='/Users/kitware/SDKs/qt-5.6.2-clang-x64' ]]) get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH) include(${path}/release_cmake.cmake) diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt index e806680..bb3b8a7 100644 --- a/Utilities/cmliblzma/CMakeLists.txt +++ b/Utilities/cmliblzma/CMakeLists.txt @@ -15,11 +15,11 @@ CHECK_C_SOURCE_COMPILES( HAVE___RESTRICT) CHECK_C_SOURCE_COMPILES( - "inline int test (void) {return 0;}\nint main (void) {return test();}" + "static inline int test (void) {return 0;}\nint main (void) {return test();}" HAVE_INLINE) CHECK_C_SOURCE_COMPILES ( - "__inline int test (void) {return 0;}\nint main (void) {return test();}" + "static __inline int test (void) {return 0;}\nint main (void) {return test();}" HAVE___INLINE) CHECK_INCLUDE_FILE(byteswap.h HAVE_BYTESWAP_H) diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index b6e7941..618f79d 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -143,6 +143,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") _DARWIN_UNLIMITED_SELECT=1 ) list(APPEND uv_sources + src/unix/bsd-ifaddrs.c src/unix/darwin.c src/unix/darwin-proctitle.c src/unix/fsevents.c @@ -175,8 +176,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") include/uv-bsd.h ) list(APPEND uv_sources + src/unix/bsd-ifaddrs.c src/unix/freebsd.c src/unix/kqueue.c + src/unix/posix-hrtime.c ) endif() @@ -188,8 +191,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") include/uv-bsd.h ) list(APPEND uv_sources + src/unix/bsd-ifaddrs.c src/unix/netbsd.c src/unix/kqueue.c + src/unix/posix-hrtime.c ) endif() @@ -201,8 +206,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") include/uv-bsd.h ) list(APPEND uv_sources + src/unix/bsd-ifaddrs.c src/unix/openbsd.c src/unix/kqueue.c + src/unix/posix-hrtime.c ) endif() diff --git a/Utilities/cmlibuv/include/uv-unix.h b/Utilities/cmlibuv/include/uv-unix.h index 3030f71..5440729 100644 --- a/Utilities/cmlibuv/include/uv-unix.h +++ b/Utilities/cmlibuv/include/uv-unix.h @@ -79,7 +79,6 @@ #endif struct uv__io_s; -struct uv__async; struct uv_loop_s; typedef void (*uv__io_cb)(struct uv_loop_s* loop, @@ -97,16 +96,6 @@ struct uv__io_s { UV_IO_PRIVATE_PLATFORM_FIELDS }; -typedef void (*uv__async_cb)(struct uv_loop_s* loop, - struct uv__async* w, - unsigned int nevents); - -struct uv__async { - uv__async_cb cb; - uv__io_t io_watcher; - int wfd; -}; - #ifndef UV_PLATFORM_SEM_T # define UV_PLATFORM_SEM_T sem_t #endif @@ -216,7 +205,9 @@ typedef struct { void* check_handles[2]; \ void* idle_handles[2]; \ void* async_handles[2]; \ - struct uv__async async_watcher; \ + void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ + uv__io_t async_io_watcher; \ + int async_wfd; \ struct { \ void* min; \ unsigned int nelts; \ diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index 5879764..ce04875 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -278,6 +278,7 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*); UV_EXTERN size_t uv_loop_size(void); UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); UV_EXTERN void uv_stop(uv_loop_t*); @@ -1077,6 +1078,10 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + typedef enum { UV_FS_UNKNOWN = -1, @@ -1328,6 +1333,9 @@ UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); UV_EXTERN int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); UV_EXTERN int uv_signal_stop(uv_signal_t* handle); UV_EXTERN void uv_loadavg(double avg[3]); diff --git a/Utilities/cmlibuv/src/threadpool.c b/Utilities/cmlibuv/src/threadpool.c index 2c5152b..1089341 100644 --- a/Utilities/cmlibuv/src/threadpool.c +++ b/Utilities/cmlibuv/src/threadpool.c @@ -23,18 +23,6 @@ #if !defined(_WIN32) # include "unix/internal.h" -#else -# include "win/req-inl.h" -/* TODO(saghul): unify internal req functions */ -static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type) { - uv_req_init(loop, req); - req->type = type; - uv__req_register(loop, req); -} -# define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) #endif #include <stdlib.h> @@ -139,7 +127,7 @@ UV_DESTRUCTOR(static void cleanup(void)) { #endif -static void init_once(void) { +static void init_threads(void) { unsigned int i; const char* val; @@ -177,6 +165,27 @@ static void init_once(void) { } +#ifndef _WIN32 +static void reset_once(void) { + uv_once_t child_once = UV_ONCE_INIT; + memcpy(&once, &child_once, sizeof(child_once)); +} +#endif + + +static void init_once(void) { +#ifndef _WIN32 + /* Re-initialize the threadpool after fork. + * Note that this discards the global mutex and condition as well + * as the work queue. + */ + if (pthread_atfork(NULL, NULL, &reset_once)) + abort(); +#endif + init_threads(); +} + + void uv__work_submit(uv_loop_t* loop, struct uv__work* w, void (*work)(struct uv__work* w), diff --git a/Utilities/cmlibuv/src/unix/aix.c b/Utilities/cmlibuv/src/unix/aix.c index 1d2cd4a..388c9cc 100644 --- a/Utilities/cmlibuv/src/unix/aix.c +++ b/Utilities/cmlibuv/src/unix/aix.c @@ -96,6 +96,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct poll_ctl pc; diff --git a/Utilities/cmlibuv/src/unix/async.c b/Utilities/cmlibuv/src/unix/async.c index 393cdeb..45c088e 100644 --- a/Utilities/cmlibuv/src/unix/async.c +++ b/Utilities/cmlibuv/src/unix/async.c @@ -33,16 +33,15 @@ #include <string.h> #include <unistd.h> -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents); +static void uv__async_send(uv_loop_t* loop); +static int uv__async_start(uv_loop_t* loop); static int uv__async_eventfd(void); int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; - err = uv__async_start(loop, &loop->async_watcher, uv__async_event); + err = uv__async_start(loop); if (err) return err; @@ -63,7 +62,7 @@ int uv_async_send(uv_async_t* handle) { return 0; if (cmpxchgi(&handle->pending, 0, 1) == 0) - uv__async_send(&handle->loop->async_watcher); + uv__async_send(handle->loop); return 0; } @@ -75,44 +74,18 @@ void uv__async_close(uv_async_t* handle) { } -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents) { +static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + char buf[1024]; + ssize_t r; QUEUE queue; QUEUE* q; uv_async_t* h; - QUEUE_MOVE(&loop->async_handles, &queue); - while (!QUEUE_EMPTY(&queue)) { - q = QUEUE_HEAD(&queue); - h = QUEUE_DATA(q, uv_async_t, queue); - - QUEUE_REMOVE(q); - QUEUE_INSERT_TAIL(&loop->async_handles, q); - - if (cmpxchgi(&h->pending, 1, 0) == 0) - continue; - - if (h->async_cb == NULL) - continue; - h->async_cb(h); - } -} - + assert(w == &loop->async_io_watcher); -static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - struct uv__async* wa; - char buf[1024]; - unsigned n; - ssize_t r; - - n = 0; for (;;) { r = read(w->fd, buf, sizeof(buf)); - if (r > 0) - n += r; - if (r == sizeof(buf)) continue; @@ -128,23 +101,26 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { abort(); } - wa = container_of(w, struct uv__async, io_watcher); + QUEUE_MOVE(&loop->async_handles, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_async_t, queue); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&loop->async_handles, q); -#if defined(__linux__) - if (wa->wfd == -1) { - uint64_t val; - assert(n == sizeof(val)); - memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */ - wa->cb(loop, wa, val); - return; - } -#endif + if (cmpxchgi(&h->pending, 1, 0) == 0) + continue; + + if (h->async_cb == NULL) + continue; - wa->cb(loop, wa, n); + h->async_cb(h); + } } -void uv__async_send(struct uv__async* wa) { +static void uv__async_send(uv_loop_t* loop) { const void* buf; ssize_t len; int fd; @@ -152,14 +128,14 @@ void uv__async_send(struct uv__async* wa) { buf = ""; len = 1; - fd = wa->wfd; + fd = loop->async_wfd; #if defined(__linux__) if (fd == -1) { static const uint64_t val = 1; buf = &val; len = sizeof(val); - fd = wa->io_watcher.fd; /* eventfd */ + fd = loop->async_io_watcher.fd; /* eventfd */ } #endif @@ -178,17 +154,11 @@ void uv__async_send(struct uv__async* wa) { } -void uv__async_init(struct uv__async* wa) { - wa->io_watcher.fd = -1; - wa->wfd = -1; -} - - -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { +static int uv__async_start(uv_loop_t* loop) { int pipefd[2]; int err; - if (wa->io_watcher.fd != -1) + if (loop->async_io_watcher.fd != -1) return 0; err = uv__async_eventfd(); @@ -222,32 +192,41 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { if (err < 0) return err; - uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]); - uv__io_start(loop, &wa->io_watcher, POLLIN); - wa->wfd = pipefd[1]; - wa->cb = cb; + uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]); + uv__io_start(loop, &loop->async_io_watcher, POLLIN); + loop->async_wfd = pipefd[1]; return 0; } -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) { - if (wa->io_watcher.fd == -1) +int uv__async_fork(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) /* never started */ + return 0; + + uv__async_stop(loop); + + return uv__async_start(loop); +} + + +void uv__async_stop(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) return; - if (wa->wfd != -1) { - if (wa->wfd != wa->io_watcher.fd) - uv__close(wa->wfd); - wa->wfd = -1; + if (loop->async_wfd != -1) { + if (loop->async_wfd != loop->async_io_watcher.fd) + uv__close(loop->async_wfd); + loop->async_wfd = -1; } - uv__io_stop(loop, &wa->io_watcher, POLLIN); - uv__close(wa->io_watcher.fd); - wa->io_watcher.fd = -1; + uv__io_stop(loop, &loop->async_io_watcher, POLLIN); + uv__close(loop->async_io_watcher.fd); + loop->async_io_watcher.fd = -1; } -static int uv__async_eventfd() { +static int uv__async_eventfd(void) { #if defined(__linux__) static int no_eventfd2; static int no_eventfd; diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c new file mode 100644 index 0000000..0b5653d --- /dev/null +++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c @@ -0,0 +1,133 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <errno.h> +#include <stddef.h> + +#include <ifaddrs.h> +#include <net/if.h> +#include <net/if_dl.h> + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) + /* + * On BSD getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information. + */ + if (ent->ifa_addr->sa_family == AF_LINK) + return 1; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + if (ent->ifa_addr->sa_family != PF_INET) + return 1; +#endif + return 0; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + struct ifaddrs* addrs; + struct ifaddrs* ent; + uv_interface_address_t* address; + int i; + + if (getifaddrs(&addrs) != 0) + return -errno; + + *count = 0; + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + (*count)++; + } + + *addresses = uv__malloc(*count * sizeof(**addresses)); + + if (*addresses == NULL) { + freeifaddrs(addrs); + return -ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); + + address++; + } + + /* Fill in physical addresses for each interface */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address = *addresses; + + for (i = 0; i < *count; i++) { + if (strcmp(address->name, ent->ifa_name) == 0) { + struct sockaddr_dl* sa_addr; + sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + } + address++; + } + } + + freeifaddrs(addrs); + + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 9ef7134..96495b8 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -1240,3 +1240,48 @@ int uv_translate_sys_error(int sys_errno) { /* If < 0 then it's already a libuv error. */ return sys_errno <= 0 ? sys_errno : -sys_errno; } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + char* var; + size_t len; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + var = getenv(name); + + if (var == NULL) + return -ENOENT; + + len = strlen(var); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, var, len + 1); + *size = len; + + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + if (name == NULL || value == NULL) + return -EINVAL; + + if (setenv(name, value, 1) != 0) + return -errno; + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + if (unsetenv(name) != 0) + return -errno; + + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c index cf95da2..df6dd1c 100644 --- a/Utilities/cmlibuv/src/unix/darwin.c +++ b/Utilities/cmlibuv/src/unix/darwin.c @@ -25,10 +25,6 @@ #include <stdint.h> #include <errno.h> -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - #include <mach/mach.h> #include <mach/mach_time.h> #include <mach-o/dyld.h> /* _NSGetExecutablePath */ @@ -233,103 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Mac OS X getifaddrs returns information related to Mac Addresses for - * various devices, such as firewire, etc. These are not relevant here. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/Utilities/cmlibuv/src/unix/freebsd.c b/Utilities/cmlibuv/src/unix/freebsd.c index cba44a3..e52ae99 100644 --- a/Utilities/cmlibuv/src/unix/freebsd.c +++ b/Utilities/cmlibuv/src/unix/freebsd.c @@ -25,10 +25,6 @@ #include <string.h> #include <errno.h> -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - #include <kvm.h> #include <paths.h> #include <sys/user.h> @@ -41,9 +37,6 @@ #include <unistd.h> /* sysconf */ #include <fcntl.h> -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - #ifndef CPUSTATES # define CPUSTATES 5U #endif @@ -67,13 +60,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - #ifdef __DragonFly__ int uv_exepath(char* buffer, size_t* size) { char abspath[PATH_MAX * 2 + 1]; @@ -358,103 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On FreeBSD getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h index b48f8fa..2e3afa6 100644 --- a/Utilities/cmlibuv/src/unix/internal.h +++ b/Utilities/cmlibuv/src/unix/internal.h @@ -192,12 +192,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w); int uv__io_active(const uv__io_t* w, unsigned int events); int uv__io_check_fd(uv_loop_t* loop, int fd); void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ +int uv__io_fork(uv_loop_t* loop); /* async */ -void uv__async_send(struct uv__async* wa); -void uv__async_init(struct uv__async* wa); -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb); -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa); +void uv__async_stop(uv_loop_t* loop); +int uv__async_fork(uv_loop_t* loop); + /* loop */ void uv__run_idle(uv_loop_t* loop); @@ -233,6 +233,7 @@ int uv__next_timeout(const uv_loop_t* loop); void uv__signal_close(uv_signal_t* handle); void uv__signal_global_once_init(void); void uv__signal_loop_cleanup(uv_loop_t* loop); +int uv__signal_loop_fork(uv_loop_t* loop); /* platform specific */ uint64_t uv__hrtime(uv_clocktype_t type); @@ -302,15 +303,6 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000; #endif /* defined(__APPLE__) */ -UV_UNUSED(static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type)) { - req->type = type; - uv__req_register(loop, req); -} -#define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) - UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { /* Use a fast time source if available. We only need millisecond precision. */ @@ -327,4 +319,8 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) { return s + 1; } +#if defined(__linux__) +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers); +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/Utilities/cmlibuv/src/unix/kqueue.c b/Utilities/cmlibuv/src/unix/kqueue.c index fffd462..6bc60bb 100644 --- a/Utilities/cmlibuv/src/unix/kqueue.c +++ b/Utilities/cmlibuv/src/unix/kqueue.c @@ -48,6 +48,37 @@ int uv__kqueue_init(uv_loop_t* loop) { } +static int uv__has_forked_with_cfrunloop; + +int uv__io_fork(uv_loop_t* loop) { + int err; + uv__close(loop->backend_fd); + loop->backend_fd = -1; + err = uv__kqueue_init(loop); + if (err) + return err; + +#if defined(__APPLE__) + if (loop->cf_state != NULL) { + /* We cannot start another CFRunloop and/or thread in the child + process; CF aborts if you try or if you try to touch the thread + at all to kill it. So the best we can do is ignore it from now + on. This means we can't watch directories in the same way + anymore (like other BSDs). It also means we cannot properly + clean up the allocated resources; calling + uv__fsevents_loop_delete from uv_loop_close will crash the + process. So we sidestep the issue by pretending like we never + started it in the first place. + */ + uv__has_forked_with_cfrunloop = 1; + uv__free(loop->cf_state); + loop->cf_state = NULL; + } +#endif + return err; +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct kevent ev; int rc; @@ -404,6 +435,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->cb = cb; #if defined(__APPLE__) + if (uv__has_forked_with_cfrunloop) + goto fallback; + /* Nullify field to perform checks later */ handle->cf_cb = NULL; handle->realpath = NULL; @@ -438,7 +472,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); #if defined(__APPLE__) - if (uv__fsevents_close(handle)) + if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle)) #endif /* defined(__APPLE__) */ { uv__io_close(handle->loop, &handle->event_watcher); diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c index 58dd813..646be4f 100644 --- a/Utilities/cmlibuv/src/unix/linux-core.c +++ b/Utilities/cmlibuv/src/unix/linux-core.c @@ -107,6 +107,24 @@ int uv__platform_loop_init(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + int err; + void* old_watchers; + + old_watchers = loop->inotify_watchers; + + uv__close(loop->backend_fd); + loop->backend_fd = -1; + uv__platform_loop_delete(loop); + + err = uv__platform_loop_init(loop); + if (err) + return err; + + return uv__inotify_fork(loop, old_watchers); +} + + void uv__platform_loop_delete(uv_loop_t* loop) { if (loop->inotify_fd == -1) return; uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN); @@ -868,6 +886,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + /* + * On Linux getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information yet. + */ + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { @@ -887,11 +918,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } (*count)++; } @@ -908,17 +936,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Linux getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == PF_PACKET) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); @@ -942,11 +960,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } address = *addresses; diff --git a/Utilities/cmlibuv/src/unix/linux-inotify.c b/Utilities/cmlibuv/src/unix/linux-inotify.c index 4708c05..5934c5d 100644 --- a/Utilities/cmlibuv/src/unix/linux-inotify.c +++ b/Utilities/cmlibuv/src/unix/linux-inotify.c @@ -61,6 +61,8 @@ static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, unsigned int revents); +static void maybe_free_watcher_list(struct watcher_list* w, + uv_loop_t* loop); static int new_inotify_fd(void) { int err; @@ -108,6 +110,71 @@ static int init_inotify(uv_loop_t* loop) { } +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) { + /* Open the inotify_fd, and re-arm all the inotify watchers. */ + int err; + struct watcher_list* tmp_watcher_list_iter; + struct watcher_list* watcher_list; + struct watcher_list tmp_watcher_list; + QUEUE queue; + QUEUE* q; + uv_fs_event_t* handle; + char* tmp_path; + + if (old_watchers != NULL) { + /* We must restore the old watcher list to be able to close items + * out of it. + */ + loop->inotify_watchers = old_watchers; + + QUEUE_INIT(&tmp_watcher_list.watchers); + /* Note that the queue we use is shared with the start and stop() + * functions, making QUEUE_FOREACH unsafe to use. So we use the + * QUEUE_MOVE trick to safely iterate. Also don't free the watcher + * list until we're done iterating. c.f. uv__inotify_read. + */ + RB_FOREACH_SAFE(watcher_list, watcher_root, + CAST(&old_watchers), tmp_watcher_list_iter) { + watcher_list->iterating = 1; + QUEUE_MOVE(&watcher_list->watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + /* It's critical to keep a copy of path here, because it + * will be set to NULL by stop() and then deallocated by + * maybe_free_watcher_list + */ + tmp_path = uv__strdup(handle->path); + assert(tmp_path != NULL); + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&watcher_list->watchers, q); + uv_fs_event_stop(handle); + + QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers); + handle->path = tmp_path; + } + watcher_list->iterating = 0; + maybe_free_watcher_list(watcher_list, loop); + } + + QUEUE_MOVE(&tmp_watcher_list.watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + QUEUE_REMOVE(q); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + tmp_path = handle->path; + handle->path = NULL; + err = uv_fs_event_start(handle, handle->cb, tmp_path, 0); + uv__free(tmp_path); + if (err) + return err; + } + } + + return 0; +} + + static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { struct watcher_list w; w.wd = wd; diff --git a/Utilities/cmlibuv/src/unix/loop.c b/Utilities/cmlibuv/src/unix/loop.c index bd63c2f..bcd4924 100644 --- a/Utilities/cmlibuv/src/unix/loop.c +++ b/Utilities/cmlibuv/src/unix/loop.c @@ -54,7 +54,8 @@ int uv_loop_init(uv_loop_t* loop) { loop->closing_handles = NULL; uv__update_time(loop); - uv__async_init(&loop->async_watcher); + loop->async_io_watcher.fd = -1; + loop->async_wfd = -1; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; @@ -108,10 +109,43 @@ fail_signal_init: } +int uv_loop_fork(uv_loop_t* loop) { + int err; + unsigned int i; + uv__io_t* w; + + err = uv__io_fork(loop); + if (err) + return err; + + err = uv__async_fork(loop); + if (err) + return err; + + err = uv__signal_loop_fork(loop); + if (err) + return err; + + /* Rearm all the watchers that aren't re-queued by the above. */ + for (i = 0; i < loop->nwatchers; i++) { + w = loop->watchers[i]; + if (w == NULL) + continue; + + if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) { + w->events = 0; /* Force re-registration in uv__io_poll. */ + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + } + } + + return 0; +} + + void uv__loop_close(uv_loop_t* loop) { uv__signal_loop_cleanup(loop); uv__platform_loop_delete(loop); - uv__async_stop(loop, &loop->async_watcher); + uv__async_stop(loop); if (loop->emfile_fd != -1) { uv__close(loop->emfile_fd); diff --git a/Utilities/cmlibuv/src/unix/netbsd.c b/Utilities/cmlibuv/src/unix/netbsd.c index 4a9e6cb..9b5546b 100644 --- a/Utilities/cmlibuv/src/unix/netbsd.c +++ b/Utilities/cmlibuv/src/unix/netbsd.c @@ -27,14 +27,11 @@ #include <kvm.h> #include <paths.h> -#include <ifaddrs.h> #include <unistd.h> #include <time.h> #include <stdlib.h> #include <fcntl.h> -#include <net/if.h> -#include <net/if_dl.h> #include <sys/resource.h> #include <sys/types.h> #include <sys/sysctl.h> @@ -43,9 +40,6 @@ #include <unistd.h> #include <time.h> -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -58,13 +52,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -283,98 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c index ac28b69..7e4b253 100644 --- a/Utilities/cmlibuv/src/unix/openbsd.c +++ b/Utilities/cmlibuv/src/unix/openbsd.c @@ -28,10 +28,6 @@ #include <sys/time.h> #include <sys/sysctl.h> -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - #include <errno.h> #include <fcntl.h> #include <kvm.h> @@ -40,9 +36,6 @@ #include <string.h> #include <unistd.h> -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -56,13 +49,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -297,100 +283,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs) != 0) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.c b/Utilities/cmlibuv/src/unix/os390-syscalls.c index 2bf3b73..7edf235 100644 --- a/Utilities/cmlibuv/src/unix/os390-syscalls.c +++ b/Utilities/cmlibuv/src/unix/os390-syscalls.c @@ -120,7 +120,7 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { } -static void epoll_init() { +static void epoll_init(void) { QUEUE_INIT(&global_epoll_queue); if (uv_mutex_init(&global_epoll_lock)) abort(); diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c index be325a9..e9ba90c 100644 --- a/Utilities/cmlibuv/src/unix/os390.c +++ b/Utilities/cmlibuv/src/unix/os390.c @@ -863,3 +863,9 @@ update_timeout: void uv__set_process_title(const char* title) { /* do nothing */ } + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c index 80f5e6f..023e965 100644 --- a/Utilities/cmlibuv/src/unix/pipe.c +++ b/Utilities/cmlibuv/src/unix/pipe.c @@ -73,7 +73,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { /* Convert ENOENT to EACCES for compatibility with Windows. */ if (err == -ENOENT) err = -EACCES; - goto err_bind; + + uv__close(sockfd); + goto err_socket; } /* Success. */ @@ -82,9 +84,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { handle->io_watcher.fd = sockfd; return 0; -err_bind: - uv__close(sockfd); - err_socket: uv__free((void*)pipe_fname); return err; diff --git a/Utilities/cmlibuv/src/unix/posix-hrtime.c b/Utilities/cmlibuv/src/unix/posix-hrtime.c new file mode 100644 index 0000000..323dfc2 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/posix-hrtime.c @@ -0,0 +1,35 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <time.h> + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +uint64_t uv__hrtime(uv_clocktype_t type) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); +} diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c index dbd8f86..cb09ead 100644 --- a/Utilities/cmlibuv/src/unix/signal.c +++ b/Utilities/cmlibuv/src/unix/signal.c @@ -38,9 +38,14 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s); static int uv__signal_unlock(void); +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); static void uv__signal_stop(uv_signal_t* handle); +static void uv__signal_unregister_handler(int signum); static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; @@ -53,8 +58,19 @@ RB_GENERATE_STATIC(uv__signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare) +static void uv__signal_global_reinit(void); static void uv__signal_global_init(void) { + if (!uv__signal_lock_pipefd[0]) + /* pthread_atfork can register before and after handlers, one + * for each child. This only registers one for the child. That + * state is both persistent and cumulative, so if we keep doing + * it the handler functions will be called multiple times. Thus + * we only want to do it once. + */ + if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) + abort(); + if (uv__make_pipe(uv__signal_lock_pipefd, 0)) abort(); @@ -63,6 +79,22 @@ static void uv__signal_global_init(void) { } +static void uv__signal_global_reinit(void) { + /* We can only use signal-safe functions here. + * That includes read/write and close, fortunately. + * We do all of this directly here instead of resetting + * uv__signal_global_init_guard because + * uv__signal_global_once_init is only called from uv_loop_init + * and this needs to function in existing loops. + */ + uv__close(uv__signal_lock_pipefd[0]); + uv__signal_lock_pipefd[0] = -1; + uv__close(uv__signal_lock_pipefd[1]); + uv__signal_lock_pipefd[1] = -1; + uv__signal_global_init(); +} + + void uv__signal_global_once_init(void) { uv_once(&uv__signal_global_init_guard, uv__signal_global_init); } @@ -122,6 +154,7 @@ static uv_signal_t* uv__signal_first_handle(int signum) { uv_signal_t* handle; lookup.signum = signum; + lookup.flags = 0; lookup.loop = NULL; handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); @@ -174,7 +207,7 @@ static void uv__signal_handler(int signum) { } -static int uv__signal_register_handler(int signum) { +static int uv__signal_register_handler(int signum, int oneshot) { /* When this function is called, the signal lock must be held. */ struct sigaction sa; @@ -183,6 +216,7 @@ static int uv__signal_register_handler(int signum) { if (sigfillset(&sa.sa_mask)) abort(); sa.sa_handler = uv__signal_handler; + sa.sa_flags = oneshot ? SA_RESETHAND : 0; /* XXX save old action so we can restore it later on? */ if (sigaction(signum, &sa, NULL)) @@ -228,6 +262,16 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) { } +int uv__signal_loop_fork(uv_loop_t* loop) { + uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); + uv__close(loop->signal_pipefd[0]); + uv__close(loop->signal_pipefd[1]); + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; + return uv__signal_loop_once_init(loop); +} + + void uv__signal_loop_cleanup(uv_loop_t* loop) { QUEUE* q; @@ -287,8 +331,24 @@ void uv__signal_close(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { sigset_t saved_sigmask; int err; + uv_signal_t* first_handle; assert(!uv__is_closing(handle)); @@ -318,9 +378,12 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { /* If at this point there are no active signal watchers for this signum (in * any of the loops), it's time to try and register a handler for it here. + * Also in case there's only one-shot handlers and a regular handler comes in. */ - if (uv__signal_first_handle(signum) == NULL) { - err = uv__signal_register_handler(signum); + first_handle = uv__signal_first_handle(signum); + if (first_handle == NULL || + (!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) { + err = uv__signal_register_handler(signum, oneshot); if (err) { /* Registering the signal handler failed. Must be an invalid signal. */ uv__signal_unlock_and_unblock(&saved_sigmask); @@ -329,6 +392,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { } handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); uv__signal_unlock_and_unblock(&saved_sigmask); @@ -390,6 +456,9 @@ static void uv__signal_event(uv_loop_t* loop, handle->dispatched_signals++; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv__signal_stop(handle); + /* If uv_close was called while there were caught signals that were not * yet dispatched, the uv__finish_close was deferred. Make close pending * now if this has happened. @@ -414,12 +483,22 @@ static void uv__signal_event(uv_loop_t* loop, static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + int f1; + int f2; /* Compare signums first so all watchers with the same signnum end up * adjacent. */ if (w1->signum < w2->signum) return -1; if (w1->signum > w2->signum) return 1; + /* Handlers without UV__SIGNAL_ONE_SHOT set will come first, so if the first + * handler returned is a one-shot handler, the rest will be too. + */ + f1 = w1->flags & UV__SIGNAL_ONE_SHOT; + f2 = w2->flags & UV__SIGNAL_ONE_SHOT; + if (f1 < f2) return -1; + if (f1 > f2) return 1; + /* Sort by loop pointer, so we can easily look up the first item after * { .signum = x, .loop = NULL }. */ @@ -443,6 +522,10 @@ int uv_signal_stop(uv_signal_t* handle) { static void uv__signal_stop(uv_signal_t* handle) { uv_signal_t* removed_handle; sigset_t saved_sigmask; + uv_signal_t* first_handle; + int rem_oneshot; + int first_oneshot; + int ret; /* If the watcher wasn't started, this is a no-op. */ if (handle->signum == 0) @@ -457,8 +540,17 @@ static void uv__signal_stop(uv_signal_t* handle) { /* Check if there are other active signal watchers observing this signal. If * not, unregister the signal handler. */ - if (uv__signal_first_handle(handle->signum) == NULL) + first_handle = uv__signal_first_handle(handle->signum); + if (first_handle == NULL) { uv__signal_unregister_handler(handle->signum); + } else { + rem_oneshot = handle->flags & UV__SIGNAL_ONE_SHOT; + first_oneshot = first_handle->flags & UV__SIGNAL_ONE_SHOT; + if (first_oneshot && !rem_oneshot) { + ret = uv__signal_register_handler(handle->signum, 1); + assert(ret == 0); + } + } uv__signal_unlock_and_unblock(&saved_sigmask); diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c index 7059df1..dbd04f2 100644 --- a/Utilities/cmlibuv/src/unix/stream.c +++ b/Utilities/cmlibuv/src/unix/stream.c @@ -785,7 +785,12 @@ start: struct msghdr msg; struct cmsghdr *cmsg; int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - char scratch[64] = {0}; + union { + char data[64]; + struct cmsghdr alias; + } scratch; + + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -795,7 +800,7 @@ start: msg.msg_iovlen = iovcnt; msg.msg_flags = 0; - msg.msg_control = (void*) scratch; + msg.msg_control = &scratch.alias; msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); cmsg = CMSG_FIRSTHDR(&msg); diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c index 14c58af..d100263 100644 --- a/Utilities/cmlibuv/src/unix/sunos.c +++ b/Utilities/cmlibuv/src/unix/sunos.c @@ -103,6 +103,18 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { +#if defined(PORT_SOURCE_FILE) + if (loop->fs_fd != -1) { + /* stop the watcher before we blow away its fileno */ + uv__io_stop(loop, &loop->fs_event_watcher, POLLIN); + } +#endif + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + + void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { struct port_event* events; uintptr_t i; @@ -473,8 +485,10 @@ int uv_fs_event_start(uv_fs_event_t* handle, memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->path; err = uv__fs_event_rearm(handle); - if (err != 0) + if (err != 0) { + uv_fs_event_stop(handle); return err; + } if (first_run) { uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); @@ -750,6 +764,17 @@ static int uv__set_phys_addr(uv_interface_address_t* address, return 0; } + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} + int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; struct ifaddrs* addrs; @@ -763,12 +788,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } - (*count)++; } @@ -781,10 +802,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); diff --git a/Utilities/cmlibuv/src/unix/udp.c b/Utilities/cmlibuv/src/unix/udp.c index 1cd4925..c556325 100644 --- a/Utilities/cmlibuv/src/unix/udp.c +++ b/Utilities/cmlibuv/src/unix/udp.c @@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle, if (flags & UV_UDP_REUSEADDR) { err = uv__set_reuse(fd); if (err) - goto out; + return err; } if (flags & UV_UDP_IPV6ONLY) { @@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle, yes = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { err = -errno; - goto out; + return err; } #else err = -ENOTSUP; - goto out; + return err; #endif } @@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle, /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a * socket created with AF_INET to an AF_INET6 address or vice versa. */ err = -EINVAL; - goto out; + return err; } if (addr->sa_family == AF_INET6) handle->flags |= UV_HANDLE_IPV6; handle->flags |= UV_HANDLE_BOUND; - return 0; - -out: - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - return err; } static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain, unsigned int flags) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; + union { + struct sockaddr_in6 in6; + struct sockaddr_in in; + struct sockaddr addr; + } taddr; socklen_t addrlen; if (handle->io_watcher.fd != -1) @@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, switch (domain) { case AF_INET: { - struct sockaddr_in* addr = (void*)&taddr; + struct sockaddr_in* addr = &taddr.in; memset(addr, 0, sizeof *addr); addr->sin_family = AF_INET; addr->sin_addr.s_addr = INADDR_ANY; @@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, } case AF_INET6: { - struct sockaddr_in6* addr = (void*)&taddr; + struct sockaddr_in6* addr = &taddr.in6; memset(addr, 0, sizeof *addr); addr->sin6_family = AF_INET6; addr->sin6_addr = in6addr_any; @@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, abort(); } - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags); + return uv__udp_bind(handle, &taddr.addr, addrlen, flags); } @@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req, if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); + + /* `uv__udp_sendmsg` may not be able to do non-blocking write straight + * away. In such cases the `io_watcher` has to be queued for asynchronous + * write. + */ + if (!QUEUE_EMPTY(&handle->write_queue)) + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } else { uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } diff --git a/Utilities/cmlibuv/src/uv-common.h b/Utilities/cmlibuv/src/uv-common.h index 27902fd..781a855 100644 --- a/Utilities/cmlibuv/src/uv-common.h +++ b/Utilities/cmlibuv/src/uv-common.h @@ -55,16 +55,19 @@ extern int snprintf(char*, size_t, const char*, ...); #ifndef _WIN32 enum { + UV__SIGNAL_ONE_SHOT = 0x80000, /* On signal reception remove sighandler */ UV__HANDLE_INTERNAL = 0x8000, UV__HANDLE_ACTIVE = 0x4000, UV__HANDLE_REF = 0x2000, UV__HANDLE_CLOSING = 0 /* no-op on unix */ }; #else -# define UV__HANDLE_INTERNAL 0x80 -# define UV__HANDLE_ACTIVE 0x40 -# define UV__HANDLE_REF 0x20 -# define UV__HANDLE_CLOSING 0x01 +# define UV__SIGNAL_ONE_SHOT_DISPATCHED 0x200 +# define UV__SIGNAL_ONE_SHOT 0x100 +# define UV__HANDLE_INTERNAL 0x80 +# define UV__HANDLE_ACTIVE 0x40 +# define UV__HANDLE_REF 0x20 +# define UV__HANDLE_CLOSING 0x01 #endif int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap); @@ -215,6 +218,30 @@ void uv__fs_scandir_cleanup(uv_fs_t* req); } \ while (0) +/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of + * a circular dependency between src/uv-common.h and src/win/internal.h. + */ +#if defined(_WIN32) +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + (req)->u.io.overlapped.Internal = 0; /* SET_REQ_SUCCESS() */ \ + } \ + while (0) +#else +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + } \ + while (0) +#endif + +#define uv__req_init(loop, req, typ) \ + do { \ + UV_REQ_INIT(req, typ); \ + uv__req_register(loop, req); \ + } \ + while (0) /* Allocator prototypes */ void *uv__calloc(size_t count, size_t size); diff --git a/Utilities/cmlibuv/src/win/async.c b/Utilities/cmlibuv/src/win/async.c index ad240ab..0b636ed 100644 --- a/Utilities/cmlibuv/src/win/async.c +++ b/Utilities/cmlibuv/src/win/async.c @@ -45,8 +45,7 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { handle->async_cb = async_cb; req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; + UV_REQ_INIT(req, UV_WAKEUP); req->data = handle; uv__handle_start(handle); diff --git a/Utilities/cmlibuv/src/win/atomicops-inl.h b/Utilities/cmlibuv/src/win/atomicops-inl.h index 61e0060..6d8126f 100644 --- a/Utilities/cmlibuv/src/win/atomicops-inl.h +++ b/Utilities/cmlibuv/src/win/atomicops-inl.h @@ -23,6 +23,7 @@ #define UV_WIN_ATOMICOPS_INL_H_ #include "uv.h" +#include "internal.h" /* Atomic set operation on char */ @@ -34,7 +35,7 @@ /* target to be aligned. */ #pragma intrinsic(_InterlockedOr8) -static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) { +static char INLINE uv__atomic_exchange_set(char volatile* target) { return _InterlockedOr8(target, 1); } diff --git a/Utilities/cmlibuv/src/win/core.c b/Utilities/cmlibuv/src/win/core.c index e84186d..9ed4e82 100644 --- a/Utilities/cmlibuv/src/win/core.c +++ b/Utilities/cmlibuv/src/win/core.c @@ -83,13 +83,8 @@ static int uv__loops_capacity; #define UV__LOOPS_CHUNK_SIZE 8 static uv_mutex_t uv__loops_lock; -static void uv__loops_init() { +static void uv__loops_init(void) { uv_mutex_init(&uv__loops_lock); - uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*)); - if (!uv__loops) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - uv__loops_size = 0; - uv__loops_capacity = UV__LOOPS_CHUNK_SIZE; } static int uv__loops_add(uv_loop_t* loop) { @@ -138,6 +133,13 @@ static void uv__loops_remove(uv_loop_t* loop) { uv__loops[uv__loops_size - 1] = NULL; --uv__loops_size; + if (uv__loops_size == 0) { + uv__loops_capacity = 0; + uv__free(uv__loops); + uv__loops = NULL; + goto loop_removed; + } + /* If we didn't grow to big skip downsizing */ if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE) goto loop_removed; @@ -156,7 +158,7 @@ loop_removed: uv_mutex_unlock(&uv__loops_lock); } -void uv__wake_all_loops() { +void uv__wake_all_loops(void) { int i; uv_loop_t* loop; @@ -332,6 +334,11 @@ int uv_backend_fd(const uv_loop_t* loop) { } +int uv_loop_fork(uv_loop_t* loop) { + return UV_ENOSYS; +} + + int uv_backend_timeout(const uv_loop_t* loop) { if (loop->stop_flag != 0) return 0; diff --git a/Utilities/cmlibuv/src/win/detect-wakeup.c b/Utilities/cmlibuv/src/win/detect-wakeup.c index a12179f..72dfb7a 100644 --- a/Utilities/cmlibuv/src/win/detect-wakeup.c +++ b/Utilities/cmlibuv/src/win/detect-wakeup.c @@ -2,9 +2,9 @@ #include "internal.h" #include "winapi.h" -static void uv__register_system_resume_callback(); +static void uv__register_system_resume_callback(void); -void uv__init_detect_system_wakeup() { +void uv__init_detect_system_wakeup(void) { /* Try registering system power event callback. This is the cleanest * method, but it will only work on Win8 and above. */ @@ -20,7 +20,7 @@ static ULONG CALLBACK uv__system_resume_callback(PVOID Context, return 0; } -static void uv__register_system_resume_callback() { +static void uv__register_system_resume_callback(void) { _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient; _HPOWERNOTIFY registration_handle; diff --git a/Utilities/cmlibuv/src/win/fs-event.c b/Utilities/cmlibuv/src/win/fs-event.c index 05fc1d0..95f843a 100644 --- a/Utilities/cmlibuv/src/win/fs-event.c +++ b/Utilities/cmlibuv/src/win/fs-event.c @@ -81,8 +81,17 @@ static void uv_relative_path(const WCHAR* filename, static int uv_split_path(const WCHAR* filename, WCHAR** dir, WCHAR** file) { - int len = wcslen(filename); - int i = len; + size_t len, i; + + if (filename == NULL) { + if (dir != NULL) + *dir = NULL; + *file = NULL; + return 0; + } + + len = wcslen(filename); + i = len; while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); if (i == 0) { @@ -131,8 +140,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { handle->short_filew = NULL; handle->dirw = NULL; - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; + UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ); handle->req.data = handle; return 0; @@ -146,7 +154,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, int name_size, is_path_dir; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; - WCHAR short_path[MAX_PATH]; + WCHAR short_path_buffer[MAX_PATH]; + WCHAR* short_path; if (uv__is_active(handle)) return UV_EINVAL; @@ -196,9 +205,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, */ /* Convert to short path. */ + short_path = short_path_buffer; if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; + short_path = NULL; } if (uv_split_path(pathw, &dir, &handle->filew) != 0) { @@ -306,6 +315,9 @@ error: handle->buffer = NULL; } + if (uv__is_active(handle)) + uv__handle_stop(handle); + return uv_translate_sys_error(last_error); } @@ -345,8 +357,11 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { } -static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) { - int str_len; +static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) { + size_t str_len; + + if (str == NULL) + return -1; str_len = wcslen(str); diff --git a/Utilities/cmlibuv/src/win/fs.c b/Utilities/cmlibuv/src/win/fs.c index 6902d4f..2d72cdc 100644 --- a/Utilities/cmlibuv/src/win/fs.c +++ b/Utilities/cmlibuv/src/win/fs.c @@ -114,7 +114,7 @@ const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; const WCHAR UNC_PATH_PREFIX_LEN = 8; -void uv_fs_init() { +void uv_fs_init(void) { _fmode = _O_BINARY; } @@ -220,9 +220,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type, const uv_fs_cb cb) { - uv_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; + UV_REQ_INIT(req, UV_FS); req->loop = loop; req->flags = 0; req->fs_type = fs_type; @@ -1373,7 +1371,7 @@ static void fs__access(uv_fs_t* req) { * - or it's a directory. * (Directories cannot be read-only on Windows.) */ - if (!(req->flags & W_OK) || + if (!(req->fs.info.mode & W_OK) || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { SET_REQ_RESULT(req, 0); @@ -2400,7 +2398,7 @@ int uv_fs_access(uv_loop_t* loop, if (err) return uv_translate_sys_error(err); - req->flags = flags; + req->fs.info.mode = flags; if (cb) { QUEUE_FS_TP_JOB(loop, req); diff --git a/Utilities/cmlibuv/src/win/getaddrinfo.c b/Utilities/cmlibuv/src/win/getaddrinfo.c index c13bfec..baab838 100644 --- a/Utilities/cmlibuv/src/win/getaddrinfo.c +++ b/Utilities/cmlibuv/src/win/getaddrinfo.c @@ -265,11 +265,9 @@ int uv_getaddrinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); - + UV_REQ_INIT(req, UV_GETADDRINFO); req->getaddrinfo_cb = getaddrinfo_cb; req->addrinfo = NULL; - req->type = UV_GETADDRINFO; req->loop = loop; req->retcode = 0; diff --git a/Utilities/cmlibuv/src/win/getnameinfo.c b/Utilities/cmlibuv/src/win/getnameinfo.c index 66b64b8..9f10cd2 100644 --- a/Utilities/cmlibuv/src/win/getnameinfo.c +++ b/Utilities/cmlibuv/src/win/getnameinfo.c @@ -127,12 +127,11 @@ int uv_getnameinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); + UV_REQ_INIT(req, UV_GETNAMEINFO); uv__req_register(loop, req); req->getnameinfo_cb = getnameinfo_cb; req->flags = flags; - req->type = UV_GETNAMEINFO; req->loop = loop; req->retcode = 0; diff --git a/Utilities/cmlibuv/src/win/internal.h b/Utilities/cmlibuv/src/win/internal.h index 8a17e94..83601d5 100644 --- a/Utilities/cmlibuv/src/win/internal.h +++ b/Utilities/cmlibuv/src/win/internal.h @@ -210,7 +210,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); /* * TTY */ -void uv_console_init(); +void uv_console_init(void); int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb); @@ -263,7 +263,7 @@ void uv_prepare_invoke(uv_loop_t* loop); void uv_check_invoke(uv_loop_t* loop); void uv_idle_invoke(uv_loop_t* loop); -void uv__once_init(); +void uv__once_init(void); /* @@ -279,7 +279,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, /* * Signal watcher */ -void uv_signals_init(); +void uv_signals_init(void); int uv__signal_dispatch(int signum); void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); @@ -306,7 +306,7 @@ int uv_translate_sys_error(int sys_errno); /* * FS */ -void uv_fs_init(); +void uv_fs_init(void); /* @@ -327,14 +327,15 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); /* * Utilities. */ -void uv__util_init(); +void uv__util_init(void); uint64_t uv__hrtime(double scale); -int uv_parent_pid(); -int uv_current_pid(); +int uv_parent_pid(void); +int uv_current_pid(void); __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); int uv__getpwuid_r(uv_passwd_t* pwd); int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16); /* @@ -353,13 +354,13 @@ HANDLE uv__stdio_handle(BYTE* buffer, int fd); /* * Winapi and ntapi utility functions */ -void uv_winapi_init(); +void uv_winapi_init(void); /* * Winsock utility functions */ -void uv_winsock_init(); +void uv_winsock_init(void); int uv_ntstatus_to_winsock_error(NTSTATUS status); @@ -388,11 +389,11 @@ extern struct sockaddr_in6 uv_addr_ip6_any_; /* * Wake all loops with fake message */ -void uv__wake_all_loops(); +void uv__wake_all_loops(void); /* * Init system wake-up detection */ -void uv__init_detect_system_wakeup(); +void uv__init_detect_system_wakeup(void); #endif /* UV_WIN_INTERNAL_H_ */ diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c index 2442be7..edf3002 100644 --- a/Utilities/cmlibuv/src/win/pipe.c +++ b/Utilities/cmlibuv/src/win/pipe.c @@ -103,7 +103,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { handle->pipe.conn.non_overlapped_writes_tail = NULL; handle->pipe.conn.readfile_thread = NULL; - uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req); + UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ); return 0; } @@ -505,8 +505,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) { req = &handle->pipe.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->data = handle; req->pipeHandle = INVALID_HANDLE_VALUE; req->next_pending = NULL; @@ -626,8 +625,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, HANDLE pipeHandle = INVALID_HANDLE_VALUE; DWORD duplex_flags; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; @@ -962,7 +960,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */ if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hThread, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { + 0, FALSE, DUPLICATE_SAME_ACCESS)) { handle->pipe.conn.readfile_thread = hThread; } else { hThread = NULL; @@ -1239,8 +1237,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, assert(handle->handle != INVALID_HANDLE_VALUE); - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; req->ipc_header = 0; @@ -1301,8 +1298,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, } } - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; + UV_REQ_INIT(ipc_header_req, UV_WRITE); ipc_header_req->handle = (uv_stream_t*) handle; ipc_header_req->cb = NULL; ipc_header_req->ipc_header = 1; @@ -2076,7 +2072,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) buffer[addrlen] = '\0'; err = 0; - goto cleanup; error: uv__free(name_info); diff --git a/Utilities/cmlibuv/src/win/poll.c b/Utilities/cmlibuv/src/win/poll.c index d479e52..a648ba7 100644 --- a/Utilities/cmlibuv/src/win/poll.c +++ b/Utilities/cmlibuv/src/win/poll.c @@ -61,13 +61,13 @@ static void uv__init_overlapped_dummy(void) { } -static OVERLAPPED* uv__get_overlapped_dummy() { +static OVERLAPPED* uv__get_overlapped_dummy(void) { uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); return &overlapped_dummy_; } -static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() { +static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) { return &afd_poll_info_dummy_; } @@ -572,13 +572,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, /* Initialize 2 poll reqs. */ handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ); handle->poll_req_1.data = handle; handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ); handle->poll_req_2.data = handle; return 0; diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index bdf88d2..d141601 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -148,8 +148,7 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { handle->child_stdio_buffer = NULL; handle->exit_cb_pending = 0; - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; + UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT); handle->exit_req.data = handle; } diff --git a/Utilities/cmlibuv/src/win/req-inl.h b/Utilities/cmlibuv/src/win/req-inl.h index b5e502e..f2513b7 100644 --- a/Utilities/cmlibuv/src/win/req-inl.h +++ b/Utilities/cmlibuv/src/win/req-inl.h @@ -34,6 +34,9 @@ #define SET_REQ_ERROR(req, error) \ SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) +/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency + * between src/uv-common.h and src/win/internal.h. + */ #define SET_REQ_SUCCESS(req) \ SET_REQ_STATUS((req), STATUS_SUCCESS) @@ -79,12 +82,6 @@ } -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); } diff --git a/Utilities/cmlibuv/src/win/signal.c b/Utilities/cmlibuv/src/win/signal.c index af7974c..7b42dd9 100644 --- a/Utilities/cmlibuv/src/win/signal.c +++ b/Utilities/cmlibuv/src/win/signal.c @@ -34,7 +34,12 @@ static CRITICAL_SECTION uv__signal_lock; static BOOL WINAPI uv__signal_control_handler(DWORD type); -void uv_signals_init() { +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); + +void uv_signals_init(void) { InitializeCriticalSection(&uv__signal_lock); if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) abort(); @@ -70,7 +75,9 @@ RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare int uv__signal_dispatch(int signum) { uv_signal_t lookup; uv_signal_t* handle; - int dispatched = 0; + int dispatched; + + dispatched = 0; EnterCriticalSection(&uv__signal_lock); @@ -83,11 +90,16 @@ int uv__signal_dispatch(int signum) { unsigned long previous = InterlockedExchange( (volatile LONG*) &handle->pending_signum, signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED) + continue; + if (!previous) { POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); } dispatched = 1; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED; } LeaveCriticalSection(&uv__signal_lock); @@ -128,17 +140,13 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) { int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); handle->pending_signum = 0; handle->signum = 0; handle->signal_cb = NULL; - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; + UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ); + handle->signal_req.data = handle; return 0; } @@ -166,6 +174,21 @@ int uv_signal_stop(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { /* Test for invalid signal values. */ if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG)) return UV_EINVAL; @@ -189,6 +212,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { EnterCriticalSection(&uv__signal_lock); handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); LeaveCriticalSection(&uv__signal_lock); @@ -217,6 +243,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, if (dispatched_signum == handle->signum) handle->signal_cb(handle, dispatched_signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv_signal_stop(handle); + if (handle->flags & UV__HANDLE_CLOSING) { /* When it is closing, it must be stopped at this point. */ assert(handle->signum == 0); diff --git a/Utilities/cmlibuv/src/win/stream-inl.h b/Utilities/cmlibuv/src/win/stream-inl.h index b7a3c11..bf12148 100644 --- a/Utilities/cmlibuv/src/win/stream-inl.h +++ b/Utilities/cmlibuv/src/win/stream-inl.h @@ -43,10 +43,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) { handle->flags |= UV_HANDLE_CONNECTION; handle->stream.conn.write_reqs_pending = 0; - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); + UV_REQ_INIT(&handle->read_req, UV_READ); handle->read_req.event_handle = NULL; handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; handle->read_req.data = handle; handle->stream.conn.shutdown_req = NULL; diff --git a/Utilities/cmlibuv/src/win/stream.c b/Utilities/cmlibuv/src/win/stream.c index a2466e5..13cbfdc 100644 --- a/Utilities/cmlibuv/src/win/stream.c +++ b/Utilities/cmlibuv/src/win/stream.c @@ -210,8 +210,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { return UV_EPIPE; } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; + UV_REQ_INIT(req, UV_SHUTDOWN); req->handle = handle; req->cb = cb; diff --git a/Utilities/cmlibuv/src/win/tcp.c b/Utilities/cmlibuv/src/win/tcp.c index 0709696..972539f 100644 --- a/Utilities/cmlibuv/src/win/tcp.c +++ b/Utilities/cmlibuv/src/win/tcp.c @@ -555,7 +555,6 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; unsigned int i, simultaneous_accepts; uv_tcp_accept_t* req; int err; @@ -612,8 +611,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { for (i = 0; i < simultaneous_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; @@ -635,8 +633,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { /* try to clean up {uv_simultaneous_server_accepts} requests. */ for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; req->wait_handle = INVALID_HANDLE_VALUE; @@ -779,8 +776,7 @@ static int uv_tcp_try_connect(uv_connect_t* req, } } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); @@ -863,8 +859,7 @@ int uv_tcp_write(uv_loop_t* loop, int result; DWORD bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/Utilities/cmlibuv/src/win/tty.c b/Utilities/cmlibuv/src/win/tty.c index 1b7adf6..a6f5839 100644 --- a/Utilities/cmlibuv/src/win/tty.c +++ b/Utilities/cmlibuv/src/win/tty.c @@ -138,7 +138,7 @@ typedef enum { static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED; static void uv__determine_vterm_state(HANDLE handle); -void uv_console_init() { +void uv_console_init(void) { if (uv_sem_init(&uv_tty_output_lock, 1)) abort(); } @@ -2126,8 +2126,7 @@ int uv_tty_write(uv_loop_t* loop, uv_write_cb cb) { DWORD error; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/Utilities/cmlibuv/src/win/udp.c b/Utilities/cmlibuv/src/win/udp.c index 9bf1453..2fd15cf 100644 --- a/Utilities/cmlibuv/src/win/udp.c +++ b/Utilities/cmlibuv/src/win/udp.c @@ -142,8 +142,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { handle->func_wsarecvfrom = WSARecvFrom; handle->send_queue_size = 0; handle->send_queue_count = 0; - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; + UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV); handle->recv_req.data = handle; /* If anything fails beyond this point we need to remove the handle from @@ -417,8 +416,7 @@ static int uv__send(uv_udp_send_t* req, uv_loop_t* loop = handle->loop; DWORD result, bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; + UV_REQ_INIT(req, UV_UDP_SEND); req->handle = handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c index 050058a..1d64d4c 100644 --- a/Utilities/cmlibuv/src/win/util.c +++ b/Utilities/cmlibuv/src/win/util.c @@ -59,6 +59,9 @@ # define UNLEN 256 #endif +/* Maximum environment variable size, including the terminating null */ +#define MAX_ENV_VAR_LENGTH 32767 + /* Cached copy of the process title, plus a mutex guarding it. */ static char *process_title; static CRITICAL_SECTION process_title_lock; @@ -74,7 +77,7 @@ static double hrtime_interval_ = 0; /* * One-time initialization code for functionality defined in util.c. */ -void uv__util_init() { +void uv__util_init(void) { LARGE_INTEGER perf_frequency; /* Initialize process title access mutex. */ @@ -320,7 +323,7 @@ uint64_t uv_get_total_memory(void) { } -int uv_parent_pid() { +int uv_parent_pid(void) { int parent_pid = -1; HANDLE handle; PROCESSENTRY32 pe; @@ -343,7 +346,7 @@ int uv_parent_pid() { } -int uv_current_pid() { +int uv_current_pid(void) { if (current_pid == 0) { current_pid = GetCurrentProcessId(); } @@ -405,7 +408,7 @@ done: } -static int uv__get_process_title() { +static int uv__get_process_title(void) { WCHAR title_w[MAX_TITLE_LENGTH]; if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { @@ -1322,6 +1325,47 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) { } +/* + * Converts a UTF-8 string into a UTF-16 one. The resulting string is + * null-terminated. + * + * If utf8 is null terminated, utf8len can be set to -1, otherwise it must + * be specified. + */ +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) { + int bufsize; + + if (utf8 == NULL) + return UV_EINVAL; + + /* Check how much space we need */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + /* Allocate the destination buffer adding an extra byte for the terminating + * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so + * we do it ourselves always, just in case. */ + *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1)); + + if (*utf16 == NULL) + return UV_ENOMEM; + + /* Convert to UTF-16 */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); + + if (bufsize == 0) { + uv__free(*utf16); + *utf16 = NULL; + return uv_translate_sys_error(GetLastError()); + } + + (*utf16)[bufsize] = '\0'; + return 0; +} + + int uv__getpwuid_r(uv_passwd_t* pwd) { HANDLE token; wchar_t username[UNLEN + 1]; @@ -1387,3 +1431,112 @@ int uv__getpwuid_r(uv_passwd_t* pwd) { int uv_os_get_passwd(uv_passwd_t* pwd) { return uv__getpwuid_r(pwd); } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + wchar_t var[MAX_ENV_VAR_LENGTH]; + wchar_t* name_w; + DWORD bufsize; + size_t len; + int r; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH); + uv__free(name_w); + assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */ + + if (len == 0) { + r = GetLastError(); + + if (r == ERROR_ENVVAR_NOT_FOUND) + return UV_ENOENT; + + return uv_translate_sys_error(r); + } + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + *size = bufsize; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + var, + -1, + buffer, + *size, + NULL, + NULL); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + wchar_t* name_w; + wchar_t* value_w; + int r; + + if (name == NULL || value == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = uv__convert_utf8_to_utf16(value, -1, &value_w); + + if (r != 0) { + uv__free(name_w); + return r; + } + + r = SetEnvironmentVariableW(name_w, value_w); + uv__free(name_w); + uv__free(value_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + wchar_t* name_w; + int r; + + if (name == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = SetEnvironmentVariableW(name_w, NULL); + uv__free(name_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} diff --git a/Utilities/cmlibuv/src/win/winapi.c b/Utilities/cmlibuv/src/win/winapi.c index 1fa179b..aa5d719 100644 --- a/Utilities/cmlibuv/src/win/winapi.c +++ b/Utilities/cmlibuv/src/win/winapi.c @@ -53,7 +53,7 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW; sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; -void uv_winapi_init() { +void uv_winapi_init(void) { HMODULE ntdll_module; HMODULE kernel32_module; HMODULE powrprof_module; diff --git a/Utilities/cmlibuv/src/win/winsock.c b/Utilities/cmlibuv/src/win/winsock.c index d2e667e..e86d76b 100644 --- a/Utilities/cmlibuv/src/win/winsock.c +++ b/Utilities/cmlibuv/src/win/winsock.c @@ -80,7 +80,7 @@ static int error_means_no_support(DWORD error) { } -void uv_winsock_init() { +void uv_winsock_init(void) { WSADATA wsa_data; int errorno; SOCKET dummy; |