summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy1
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--Help/command/ctest_submit.rst10
-rw-r--r--Help/command/file.rst23
-rw-r--r--Help/command/find_package.rst5
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst13
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/manual/ctest.1.rst31
-rw-r--r--Help/release/dev/ExternalProject-non-cmake-source-subdir.rst7
-rw-r--r--Help/release/dev/ctest-submit-url.rst7
-rw-r--r--Help/release/dev/find-package-resolve-symlinks.rst6
-rw-r--r--Help/release/dev/findgit-imported-target.rst5
-rw-r--r--Help/release/dev/fortran-compiler-id.rst5
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst10
-rw-r--r--Help/variable/CTEST_SUBMIT_URL.rst5
-rw-r--r--Modules/CTest.cmake18
-rw-r--r--Modules/DartConfiguration.tcl.in7
-rw-r--r--Modules/ExternalProject.cmake10
-rw-r--r--Modules/FindCURL.cmake4
-rw-r--r--Modules/FindGit.cmake11
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx9
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx20
-rw-r--r--Source/CPack/cpack.cxx6
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx4
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx12
-rw-r--r--Source/CTest/cmCTestCVS.cxx4
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx9
-rw-r--r--Source/CTest/cmCTestLaunch.cxx10
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx24
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx5
-rw-r--r--Source/CTest/cmCTestP4.cxx8
-rw-r--r--Source/CTest/cmCTestSVN.cxx4
-rw-r--r--Source/CTest/cmCTestSVN.h2
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx8
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx53
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h2
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx116
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h2
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx18
-rw-r--r--Source/CTest/cmParseDelphiCoverage.cxx2
-rw-r--r--Source/CursesDialog/ccmake.cxx9
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx8
-rw-r--r--Source/QtDialog/CMakeSetup.cxx3
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx1
-rw-r--r--Source/QtDialog/FirstConfigure.cxx80
-rw-r--r--Source/QtDialog/FirstConfigure.h9
-rw-r--r--Source/QtDialog/QCMake.cxx21
-rw-r--r--Source/QtDialog/QCMake.h5
-rw-r--r--Source/cmCPluginAPI.cxx15
-rw-r--r--Source/cmCTest.cxx54
-rw-r--r--Source/cmCTest.h2
-rw-r--r--Source/cmComputeLinkInformation.cxx6
-rw-r--r--Source/cmCoreTryCompile.cxx4
-rw-r--r--Source/cmDepends.cxx23
-rw-r--r--Source/cmDepends.h13
-rw-r--r--Source/cmDependsC.cxx18
-rw-r--r--Source/cmDependsC.h4
-rw-r--r--Source/cmDependsFortran.cxx58
-rw-r--r--Source/cmDependsFortran.h15
-rw-r--r--Source/cmDependsJava.cxx3
-rw-r--r--Source/cmDependsJava.h2
-rw-r--r--Source/cmDependsJavaParserHelper.cxx4
-rw-r--r--Source/cmDocumentation.cxx15
-rw-r--r--Source/cmDocumentationEntry.h1
-rw-r--r--Source/cmDocumentationFormatter.cxx3
-rw-r--r--Source/cmExecProgramCommand.cxx8
-rw-r--r--Source/cmExecuteProcessCommand.cxx18
-rw-r--r--Source/cmFileCommand.cxx119
-rw-r--r--Source/cmFileCommand.h1
-rw-r--r--Source/cmFindCommon.cxx6
-rw-r--r--Source/cmFindPackageCommand.cxx24
-rw-r--r--Source/cmFindPackageCommand.h1
-rw-r--r--Source/cmForEachCommand.cxx2
-rw-r--r--Source/cmGeneratorExpressionLexer.cxx4
-rw-r--r--Source/cmGeneratorExpressionNode.cxx46
-rw-r--r--Source/cmGeneratorTarget.cxx28
-rw-r--r--Source/cmGeneratorTarget.h4
-rw-r--r--Source/cmGlobalGenerator.cxx34
-rw-r--r--Source/cmGlobalGeneratorFactory.h26
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx10
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx12
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx21
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx29
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx21
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx21
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx28
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx71
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx56
-rw-r--r--Source/cmIncludeCommand.cxx3
-rw-r--r--Source/cmJsonObjects.cxx14
-rw-r--r--Source/cmLocalGenerator.cxx26
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx46
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmMacroCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx7
-rw-r--r--Source/cmMakefile.h7
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx6
-rw-r--r--Source/cmNinjaTargetGenerator.cxx7
-rw-r--r--Source/cmParseArgumentsCommand.cxx2
-rw-r--r--Source/cmProcessTools.cxx2
-rw-r--r--Source/cmProjectCommand.cxx26
-rw-r--r--Source/cmQtAutoGenInitializer.cxx13
-rw-r--r--Source/cmQtAutoGenInitializer.h3
-rw-r--r--Source/cmQtAutoGenerator.cxx8
-rw-r--r--Source/cmQtAutoGeneratorMocUic.cxx12
-rw-r--r--Source/cmQtAutoGeneratorRcc.cxx4
-rw-r--r--Source/cmRST.cxx4
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx16
-rw-r--r--Source/cmSiteNameCommand.cxx12
-rw-r--r--Source/cmSourceGroupCommand.cxx2
-rw-r--r--Source/cmStringReplaceHelper.cxx12
-rw-r--r--Source/cmSystemTools.cxx72
-rw-r--r--Source/cmSystemTools.h15
-rw-r--r--Source/cmTarget.cxx46
-rw-r--r--Source/cmTarget.h2
-rw-r--r--Source/cmTestGenerator.cxx2
-rw-r--r--Source/cmTryRunCommand.cxx4
-rw-r--r--Source/cmake.cxx121
-rw-r--r--Source/cmake.h11
-rw-r--r--Source/cmakemain.cxx18
-rw-r--r--Source/cmcmd.cxx16
-rw-r--r--Source/ctest.cxx2
-rw-r--r--Tests/CMakeLists.txt19
-rw-r--r--Tests/CompileOptions/CMakeLists.txt17
-rw-r--r--Tests/CompileOptions/main.cpp15
-rw-r--r--Tests/ExternalProjectSourceSubdirNotCMake/CMakeLists.txt20
-rw-r--r--Tests/ExternalProjectSourceSubdirNotCMake/Example/subdir/Makefile2
-rw-r--r--Tests/FindGit/CMakeLists.txt10
-rw-r--r--Tests/FindGit/Test/CMakeLists.txt13
-rw-r--r--Tests/FindGit/Test/RunGit.cmake20
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt31
-rw-r--r--Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake1
-rw-r--r--Tests/RunCMake/CMakeRoleGlobalProperty/BuildAndTest/CMakeLists.txt10
-rw-r--r--Tests/RunCMake/CMakeRoleGlobalProperty/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/CMakeRoleGlobalProperty/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/CTestCommandLine/show-only_bad-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/show-only_bad-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/show-only_human-stdout.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/show-only_json-v1-check.cmake1
-rw-r--r--Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py (renamed from Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py)6
-rw-r--r--Tests/RunCMake/CTestCommandLine/show_only_json_check.py (renamed from Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py)0
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt5
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt5
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake11
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake4
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake4
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-noarg-result.txt1
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt4
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-noarg.cmake1
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt1
-rw-r--r--Tests/RunCMake/file/CREATE_LINK-noexist.cmake4
-rw-r--r--Tests/RunCMake/file/CREATE_LINK.cmake11
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake1
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/find_package/SetFoundResolved-stderr.txt10
-rw-r--r--Tests/RunCMake/find_package/SetFoundResolved.cmake17
-rw-r--r--Tests/Server/cmakelib.py4
-rw-r--r--Utilities/IWYU/mapping.imp4
-rw-r--r--Utilities/cmlibuv/CMakeLists.txt41
-rw-r--r--Utilities/cmlibuv/include/pthread-barrier.h69
-rw-r--r--Utilities/cmlibuv/include/uv.h86
-rw-r--r--Utilities/cmlibuv/include/uv/aix.h (renamed from Utilities/cmlibuv/include/uv-aix.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/android-ifaddrs.h (renamed from Utilities/cmlibuv/include/android-ifaddrs.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/bsd.h (renamed from Utilities/cmlibuv/include/uv-bsd.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/darwin.h (renamed from Utilities/cmlibuv/include/uv-darwin.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/errno.h (renamed from Utilities/cmlibuv/include/uv-errno.h)6
-rw-r--r--Utilities/cmlibuv/include/uv/linux.h (renamed from Utilities/cmlibuv/include/uv-linux.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/os390.h (renamed from Utilities/cmlibuv/include/uv-os390.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/posix.h (renamed from Utilities/cmlibuv/include/uv-posix.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/stdint-msvc2008.h (renamed from Utilities/cmlibuv/include/stdint-msvc2008.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/sunos.h (renamed from Utilities/cmlibuv/include/uv-sunos.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/threadpool.h (renamed from Utilities/cmlibuv/include/uv-threadpool.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/tree.h (renamed from Utilities/cmlibuv/include/tree.h)0
-rw-r--r--Utilities/cmlibuv/include/uv/unix.h (renamed from Utilities/cmlibuv/include/uv-unix.h)47
-rw-r--r--Utilities/cmlibuv/include/uv/version.h (renamed from Utilities/cmlibuv/include/uv-version.h)4
-rw-r--r--Utilities/cmlibuv/include/uv/win.h (renamed from Utilities/cmlibuv/include/uv-win.h)59
-rw-r--r--Utilities/cmlibuv/src/fs-poll.c4
-rw-r--r--Utilities/cmlibuv/src/idna.c291
-rw-r--r--Utilities/cmlibuv/src/idna.h31
-rw-r--r--Utilities/cmlibuv/src/inet.c13
-rw-r--r--Utilities/cmlibuv/src/strscpy.c17
-rw-r--r--Utilities/cmlibuv/src/strscpy.h18
-rw-r--r--Utilities/cmlibuv/src/threadpool.c96
-rw-r--r--Utilities/cmlibuv/src/timer.c (renamed from Utilities/cmlibuv/src/unix/timer.c)21
-rw-r--r--Utilities/cmlibuv/src/unix/aix-common.c10
-rw-r--r--Utilities/cmlibuv/src/unix/aix.c63
-rw-r--r--Utilities/cmlibuv/src/unix/android-ifaddrs.c2
-rw-r--r--Utilities/cmlibuv/src/unix/bsd-ifaddrs.c23
-rw-r--r--Utilities/cmlibuv/src/unix/bsd-proctitle.c93
-rw-r--r--Utilities/cmlibuv/src/unix/cmake-bootstrap.c1
-rw-r--r--Utilities/cmlibuv/src/unix/core.c136
-rw-r--r--Utilities/cmlibuv/src/unix/cygwin.c2
-rw-r--r--Utilities/cmlibuv/src/unix/darwin-proctitle.c147
-rw-r--r--Utilities/cmlibuv/src/unix/freebsd.c79
-rw-r--r--Utilities/cmlibuv/src/unix/fs.c299
-rw-r--r--Utilities/cmlibuv/src/unix/fsevents.c72
-rw-r--r--Utilities/cmlibuv/src/unix/getaddrinfo.c21
-rw-r--r--Utilities/cmlibuv/src/unix/getnameinfo.c1
-rw-r--r--Utilities/cmlibuv/src/unix/ibmi.c3
-rw-r--r--Utilities/cmlibuv/src/unix/internal.h45
-rw-r--r--Utilities/cmlibuv/src/unix/kqueue.c83
-rw-r--r--Utilities/cmlibuv/src/unix/linux-core.c117
-rw-r--r--Utilities/cmlibuv/src/unix/linux-inotify.c8
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.c133
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.h34
-rw-r--r--Utilities/cmlibuv/src/unix/loop.c6
-rw-r--r--Utilities/cmlibuv/src/unix/netbsd.c71
-rw-r--r--Utilities/cmlibuv/src/unix/openbsd.c69
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.c29
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.h4
-rw-r--r--Utilities/cmlibuv/src/unix/os390.c38
-rw-r--r--Utilities/cmlibuv/src/unix/pipe.c31
-rw-r--r--Utilities/cmlibuv/src/unix/poll.c3
-rw-r--r--Utilities/cmlibuv/src/unix/process.c4
-rw-r--r--Utilities/cmlibuv/src/unix/proctitle.c4
-rw-r--r--Utilities/cmlibuv/src/unix/signal.c59
-rw-r--r--Utilities/cmlibuv/src/unix/stream.c262
-rw-r--r--Utilities/cmlibuv/src/unix/sunos.c15
-rw-r--r--Utilities/cmlibuv/src/unix/tcp.c21
-rw-r--r--Utilities/cmlibuv/src/unix/thread.c146
-rw-r--r--Utilities/cmlibuv/src/unix/tty.c45
-rw-r--r--Utilities/cmlibuv/src/unix/udp.c23
-rw-r--r--Utilities/cmlibuv/src/uv-common.c44
-rw-r--r--Utilities/cmlibuv/src/uv-common.h127
-rw-r--r--Utilities/cmlibuv/src/uv-data-getter-setters.c16
-rw-r--r--Utilities/cmlibuv/src/win/async.c10
-rw-r--r--Utilities/cmlibuv/src/win/atomicops-inl.h8
-rw-r--r--Utilities/cmlibuv/src/win/core.c58
-rw-r--r--Utilities/cmlibuv/src/win/dl.c11
-rw-r--r--Utilities/cmlibuv/src/win/error.c4
-rw-r--r--Utilities/cmlibuv/src/win/fs-event.c25
-rw-r--r--Utilities/cmlibuv/src/win/fs.c184
-rw-r--r--Utilities/cmlibuv/src/win/getaddrinfo.c40
-rw-r--r--Utilities/cmlibuv/src/win/getnameinfo.c50
-rw-r--r--Utilities/cmlibuv/src/win/handle-inl.h25
-rw-r--r--Utilities/cmlibuv/src/win/handle.c12
-rw-r--r--Utilities/cmlibuv/src/win/internal.h114
-rw-r--r--Utilities/cmlibuv/src/win/loop-watcher.c2
-rw-r--r--Utilities/cmlibuv/src/win/pipe.c1130
-rw-r--r--Utilities/cmlibuv/src/win/poll.c55
-rw-r--r--Utilities/cmlibuv/src/win/process-stdio.c59
-rw-r--r--Utilities/cmlibuv/src/win/process.c70
-rw-r--r--Utilities/cmlibuv/src/win/req.c25
-rw-r--r--Utilities/cmlibuv/src/win/signal.c50
-rw-r--r--Utilities/cmlibuv/src/win/stream.c36
-rw-r--r--Utilities/cmlibuv/src/win/tcp.c213
-rw-r--r--Utilities/cmlibuv/src/win/thread.c246
-rw-r--r--Utilities/cmlibuv/src/win/timer.c195
-rw-r--r--Utilities/cmlibuv/src/win/tty.c177
-rw-r--r--Utilities/cmlibuv/src/win/udp.c95
-rw-r--r--Utilities/cmlibuv/src/win/util.c298
-rw-r--r--Utilities/cmlibuv/src/win/winapi.c60
-rw-r--r--Utilities/cmlibuv/src/win/winapi.h80
-rw-r--r--Utilities/cmlibuv/src/win/winsock.c8
-rwxr-xr-xbootstrap8
272 files changed, 5057 insertions, 3845 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 3ae249f..aef99dc 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -15,7 +15,6 @@ modernize-*,\
-modernize-raw-string-literal,\
-modernize-return-braced-init-list,\
-modernize-use-auto,\
--modernize-use-emplace,\
-modernize-use-equals-default,\
-modernize-use-equals-delete,\
-modernize-use-noexcept,\
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 1083036..7e029de 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -2212,6 +2212,8 @@ syn keyword cmakeGeneratorExpressions contained
\ DEBUG_MODE
\ EXPORT
\ FOO_EXTRA_THINGS
+ \ Fortran_COMPILER_ID
+ \ Fortran_COMPILER_VERSION
\ GENEX_EVAL
\ GNU
\ IF
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst
index 426475c..fba03fd 100644
--- a/Help/command/ctest_submit.rst
+++ b/Help/command/ctest_submit.rst
@@ -6,6 +6,7 @@ Perform the :ref:`CTest Submit Step` as a :ref:`Dashboard Client`.
::
ctest_submit([PARTS <part>...] [FILES <file>...]
+ [SUBMIT_URL <url>]
[HTTPHEADER <header>]
[RETRY_COUNT <count>]
[RETRY_DELAY <delay>]
@@ -39,6 +40,10 @@ The options are:
Specify an explicit list of specific files to be submitted.
Each individual file must exist at the time of the call.
+``SUBMIT_URL <url>``
+ The ``http`` or ``https`` URL of the dashboard server to send the submission
+ to. If not given, the :variable:`CTEST_SUBMIT_URL` variable is used.
+
``HTTPHEADER <HTTP-header>``
Specify HTTP header to be included in the request to CDash during submission.
This suboption can be repeated several times.
@@ -68,6 +73,7 @@ Submit to CDash Upload API
::
ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]
+ [SUBMIT_URL <url>]
[HTTPHEADER <header>]
[RETRY_COUNT <count>]
[RETRY_DELAY <delay>]
@@ -80,5 +86,5 @@ with a content hash of the file. If CDash does not already have the file,
then it is uploaded. Along with the file, a CDash type string is specified
to tell CDash which handler to use to process the data.
-This signature accepts the ``HTTPHEADER``, ``RETRY_COUNT``, ``RETRY_DELAY``,
-``RETURN_VALUE`` and ``QUIET`` options as described above.
+This signature accepts the ``SUBMIT_URL``, ``HTTPHEADER``, ``RETRY_COUNT``,
+``RETRY_DELAY``, ``RETURN_VALUE`` and ``QUIET`` options as described above.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 6e2a6dd..db4d6fc 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -27,6 +27,7 @@ Synopsis
file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
file(`SIZE`_ <filename> <out-var>)
file(`READ_SYMLINK`_ <filename> <out-var>)
+ file(`CREATE_LINK`_ <file> <new-file> [...])
`Path Conversion`_
file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
@@ -368,6 +369,28 @@ could do something like this:
set(result "${dir}/${result}")
endif()
+.. _CREATE_LINK:
+
+.. code-block:: cmake
+
+ file(CREATE_LINK <file> <new-file>
+ [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC])
+
+Create a link to ``<file>`` at ``<new-file>``.
+
+It is a hard link by default. This can be changed to symbolic links by
+using ``SYMBOLIC``. The original file needs to exist for hard links.
+
+The ``<result>`` variable, if specified, gets the status of the operation.
+It is set to ``0`` in case of success. Otherwise, it contains the error
+generated. In case of failures, if ``RESULT`` is not specified, a fatal error
+is emitted.
+
+Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if
+creating the link fails.
+
+Overwrites the ``<new-file>`` if it exists.
+
Path Conversion
^^^^^^^^^^^^^^^
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index cafef8c..54d5f68 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -354,6 +354,11 @@ enabled.
.. include:: FIND_XXX_ROOT.txt
.. include:: FIND_XXX_ORDER.txt
+By default the value stored in the result variable will be the path at
+which the file is found. The :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS`
+variable may be set to ``TRUE`` before calling ``find_package`` in order
+to resolve symbolic links and store the real path to the file.
+
Every non-REQUIRED ``find_package`` call can be disabled by setting the
:variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``.
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 63e43e1..7f484a4 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -122,12 +122,19 @@ Variable Queries
``1`` if the CMake-id of the CXX compiler matches ``compiler_id``,
otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<Fortran_COMPILER_ID:compiler_id>``
+ ``1`` if the CMake-id of the Fortran compiler matches ``compiler_id``,
+ otherwise ``0``.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION:version>``
``1`` if the version of the C compiler matches ``version``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<CXX_COMPILER_VERSION:version>``
``1`` if the version of the CXX compiler matches ``version``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<Fortran_COMPILER_VERSION:version>``
+ ``1`` if the version of the Fortran compiler matches ``version``, otherwise ``0``.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<TARGET_POLICY:policy>``
``1`` if the ``policy`` was NEW when the 'head' target was created,
else ``0``. If the ``policy`` was not set, the warning message for the policy
@@ -339,12 +346,18 @@ Variable Queries
``$<CXX_COMPILER_ID>``
The CMake-id of the CXX compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<Fortran_COMPILER_ID>``
+ The CMake-id of the Fortran compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION>``
The version of the C compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<CXX_COMPILER_VERSION>``
The version of the CXX compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<Fortran_COMPILER_VERSION>``
+ The version of the Fortran compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<COMPILE_LANGUAGE>``
The compile language of source files when evaluating compile options.
See :ref:`the related boolean expression
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 122be3a..bd6a58f 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -170,6 +170,7 @@ Variables that Change Behavior
/variable/CMAKE_FIND_NO_INSTALL_PREFIX
/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+ /variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
/variable/CMAKE_FIND_ROOT_PATH
/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
@@ -569,6 +570,7 @@ Variables for CTest
/variable/CTEST_RUN_CURRENT_SCRIPT
/variable/CTEST_SCP_COMMAND
/variable/CTEST_SITE
+ /variable/CTEST_SUBMIT_URL
/variable/CTEST_SOURCE_DIRECTORY
/variable/CTEST_SVN_COMMAND
/variable/CTEST_SVN_OPTIONS
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 8490e3d..bcf75ac 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -1109,38 +1109,45 @@ Configuration settings include:
* :module:`CTest` module variable: ``CTEST_CURL_OPTIONS``
``DropLocation``
- The path on the dashboard server to send the submission.
+ Legacy option. When ``SubmitURL`` is not set, it is constructed from
+ ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and
+ ``DropLocation``.
* `CTest Script`_ variable: :variable:`CTEST_DROP_LOCATION`
* :module:`CTest` module variable: ``DROP_LOCATION`` if set,
else ``CTEST_DROP_LOCATION``
``DropMethod``
- Specify the method by which results should be submitted to the
- dashboard server. The value may be ``http`` or ``https``.
+ Legacy option. When ``SubmitURL`` is not set, it is constructed from
+ ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and
+ ``DropLocation``.
* `CTest Script`_ variable: :variable:`CTEST_DROP_METHOD`
* :module:`CTest` module variable: ``DROP_METHOD`` if set,
else ``CTEST_DROP_METHOD``
``DropSite``
- The dashboard server name.
+ Legacy option. When ``SubmitURL`` is not set, it is constructed from
+ ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and
+ ``DropLocation``.
* `CTest Script`_ variable: :variable:`CTEST_DROP_SITE`
* :module:`CTest` module variable: ``DROP_SITE`` if set,
else ``CTEST_DROP_SITE``
``DropSitePassword``
- The dashboard server login password, if any
- (for ``ftp``, ``http``, and ``https``).
+ Legacy option. When ``SubmitURL`` is not set, it is constructed from
+ ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and
+ ``DropLocation``.
* `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_PASSWORD`
* :module:`CTest` module variable: ``DROP_SITE_PASSWORD`` if set,
else ``CTEST_DROP_SITE_PASWORD``
``DropSiteUser``
- The dashboard server login user name, if any
- (for ``ftp``, ``http``, and ``https``).
+ Legacy option. When ``SubmitURL`` is not set, it is constructed from
+ ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and
+ ``DropLocation``.
* `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_USER`
* :module:`CTest` module variable: ``DROP_SITE_USER`` if set,
@@ -1166,6 +1173,14 @@ Configuration settings include:
* :module:`CTest` module variable: ``SITE``,
initialized by the :command:`site_name` command
+``SubmitURL``
+ The ``http`` or ``https`` URL of the dashboard server to send the submission
+ to.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SUBMIT_URL`
+ * :module:`CTest` module variable: ``SUBMIT_URL`` if set,
+ else ``CTEST_SUBMIT_URL``
+
``TriggerSite``
Legacy option. Not used.
diff --git a/Help/release/dev/ExternalProject-non-cmake-source-subdir.rst b/Help/release/dev/ExternalProject-non-cmake-source-subdir.rst
new file mode 100644
index 0000000..29fe2ad
--- /dev/null
+++ b/Help/release/dev/ExternalProject-non-cmake-source-subdir.rst
@@ -0,0 +1,7 @@
+ExternalProject-non-cmake-source-subdir
+---------------------------------------
+
+* The :module:`ExternalProject` module's ``ExternalProject_Add`` command
+ learned to apply ``SOURCE_SUBDIR`` when ``BUILD_IN_SOURCE`` is also used.
+ The ``BUILD_COMMAND`` is run in the given ``SOURCE_SUBDIR`` of the
+ ``SOURCE_DIR``.
diff --git a/Help/release/dev/ctest-submit-url.rst b/Help/release/dev/ctest-submit-url.rst
new file mode 100644
index 0000000..f848877
--- /dev/null
+++ b/Help/release/dev/ctest-submit-url.rst
@@ -0,0 +1,7 @@
+ctest-submit-url
+----------------
+
+* CTest learned to accept the dashboard server submission URL from a single
+ variable. See the ``SubmitURL`` setting in :manual:`ctest(1)`,
+ the :variable:`CTEST_SUBMIT_URL` variable, and the ``SUBMIT_URL``
+ argument of the :command:`ctest_submit` command.
diff --git a/Help/release/dev/find-package-resolve-symlinks.rst b/Help/release/dev/find-package-resolve-symlinks.rst
new file mode 100644
index 0000000..7adb9fe
--- /dev/null
+++ b/Help/release/dev/find-package-resolve-symlinks.rst
@@ -0,0 +1,6 @@
+find-package-resolve-symlinks
+-----------------------------
+
+* The :command:`find_package` command learned to optionally resolve
+ symbolic links in the paths to package configuration files.
+ See the :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS` variable.
diff --git a/Help/release/dev/findgit-imported-target.rst b/Help/release/dev/findgit-imported-target.rst
new file mode 100644
index 0000000..cabbae5
--- /dev/null
+++ b/Help/release/dev/findgit-imported-target.rst
@@ -0,0 +1,5 @@
+findgit-imported-target
+-----------------------
+
+* The :module:`FindGit` module now provides an ``IMPORTED`` target for the Git
+ executable.
diff --git a/Help/release/dev/fortran-compiler-id.rst b/Help/release/dev/fortran-compiler-id.rst
new file mode 100644
index 0000000..1ea3bf9
--- /dev/null
+++ b/Help/release/dev/fortran-compiler-id.rst
@@ -0,0 +1,5 @@
+Fortran_COMPILER_ID
+-------------------
+
+* The ``$<Fortran_COMPILER_ID:...>`` and ``$<Fortran_COMPILER_VERSION:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
new file mode 100644
index 0000000..dfbde20
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
@@ -0,0 +1,10 @@
+CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
+-----------------------------------
+
+Set to ``TRUE`` to tell :command:`find_package` calls to resolve symbolic
+links in the value of ``<PackageName>_DIR``.
+
+This is helpful in use cases where the package search path points at a
+proxy directory in which symlinks to the real package locations appear.
+This is not enabled by default because there are also common use cases
+in which the symlinks should be preserved.
diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst
new file mode 100644
index 0000000..7d84da4
--- /dev/null
+++ b/Help/variable/CTEST_SUBMIT_URL.rst
@@ -0,0 +1,5 @@
+CTEST_SUBMIT_URL
+----------------
+
+Specify the CTest ``SubmitURL`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 8848bdd..d100704 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -28,10 +28,7 @@ To enable submissions to a CDash server, create a ``CTestConfig.cmake``
file at the top of the project with content such as::
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
- set(CTEST_DROP_METHOD "http")
- set(CTEST_DROP_SITE "my.cdash.org")
- set(CTEST_DROP_LOCATION "/submit.php?project=MyProject")
- set(CTEST_DROP_SITE_CDASH TRUE)
+ set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject")
(the CDash server can provide the file to a project administrator who
configures ``MyProject``). Settings in the config file are shared by
@@ -89,6 +86,7 @@ if(BUILD_TESTING)
if(EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
include("${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
SET_IF_SET_AND_NOT_SET(NIGHTLY_START_TIME "${CTEST_NIGHTLY_START_TIME}")
+ SET_IF_SET_AND_NOT_SET(SUBMIT_URL "${CTEST_SUBMIT_URL}")
SET_IF_SET_AND_NOT_SET(DROP_METHOD "${CTEST_DROP_METHOD}")
SET_IF_SET_AND_NOT_SET(DROP_SITE "${CTEST_DROP_SITE}")
SET_IF_SET_AND_NOT_SET(DROP_SITE_USER "${CTEST_DROP_SITE_USER}")
@@ -111,6 +109,18 @@ if(BUILD_TESTING)
endif()
SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")
+ if(NOT SUBMIT_URL)
+ set(SUBMIT_URL "${DROP_METHOD}://")
+ if(DROP_SITE_USER)
+ string(APPEND SUBMIT_URL "${DROP_SITE_USER}")
+ if(DROP_SITE_PASSWORD)
+ string(APPEND SUBMIT_URL ":${DROP_SITE_PASSWORD}")
+ endif()
+ string(APPEND SUBMIT_URL "@")
+ endif()
+ string(APPEND SUBMIT_URL "${DROP_SITE}${DROP_SITE_LOCATION}")
+ endif()
+
find_program(CVSCOMMAND cvs )
set(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING
"Options passed to the cvs update command.")
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
index 24e7b55..e4513b3 100644
--- a/Modules/DartConfiguration.tcl.in
+++ b/Modules/DartConfiguration.tcl.in
@@ -20,12 +20,7 @@ BuildName: @BUILDNAME@
LabelsForSubprojects: @CTEST_LABELS_FOR_SUBPROJECTS@
# Submission information
-DropSite: @DROP_SITE@
-DropLocation: @DROP_LOCATION@
-DropSiteUser: @DROP_SITE_USER@
-DropSitePassword: @DROP_SITE_PASSWORD@
-DropSiteMode: @DROP_SITE_MODE@
-DropMethod: @DROP_METHOD@
+SubmitURL: @SUBMIT_URL@
# Dashboard start time
NightlyStartTime: @NIGHTLY_START_TIME@
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index e763bab..c5d6b45 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -425,7 +425,9 @@ External Project Definition
can be used to point to an alternative directory within the source tree
to use as the top of the CMake source tree instead. This must be a
relative path and it will be interpreted as being relative to
- ``SOURCE_DIR``.
+ ``SOURCE_DIR``. When ``BUILD_IN_SOURCE 1`` is specified, the
+ ``BUILD_COMMAND`` is used to point to an alternative directory within the
+ source tree.
**Build Step Options:**
If the configure step assumed the external project uses CMake as its build
@@ -1676,7 +1678,11 @@ function(_ep_set_directories name)
endif()
if(build_in_source)
get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
- set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}")
+ if(source_subdir)
+ set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}/${source_subdir}")
+ else()
+ set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}")
+ endif()
endif()
# Make the directories at CMake configure time *and* add a custom command
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index d28dfea..b1989b1 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -110,12 +110,12 @@ if(CURL_FIND_COMPONENTS)
OUTPUT_VARIABLE CURL_CONFIG_FEATURES_STRING
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REPLACE "\n" ";" CURL_CONFIG_FEATURES "${CURL_CONFIG_FEATURES_STRING}")
+ string(REPLACE "\n" ";" CURL_SUPPORTED_FEATURES "${CURL_CONFIG_FEATURES_STRING}")
execute_process(COMMAND ${CURL_CONFIG_EXECUTABLE} --protocols
OUTPUT_VARIABLE CURL_CONFIG_PROTOCOLS_STRING
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REPLACE "\n" ";" CURL_CONFIG_PROTOCOLS "${CURL_CONFIG_PROTOCOLS_STRING}")
+ string(REPLACE "\n" ";" CURL_SUPPORTED_PROTOCOLS "${CURL_CONFIG_PROTOCOLS_STRING}")
endif()
endif()
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
index c447a1a..900e4f5 100644
--- a/Modules/FindGit.cmake
+++ b/Modules/FindGit.cmake
@@ -5,6 +5,11 @@
FindGit
-------
+The module defines the following ``IMPORTED`` targets:
+
+``Git::Git``
+ Executable of the Git command-line client.
+
The module defines the following variables:
``GIT_EXECUTABLE``
@@ -78,6 +83,12 @@ if(GIT_EXECUTABLE)
string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}")
endif()
unset(git_version)
+
+ get_property(_findgit_role GLOBAL PROPERTY CMAKE_ROLE)
+ if(_findgit_role STREQUAL "PROJECT" AND NOT TARGET Git::Git)
+ add_executable(Git::Git IMPORTED)
+ set_property(TARGET Git::Git PROPERTY IMPORTED_LOCATION "${GIT_EXECUTABLE}")
+ endif()
endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 245bd71..497feed 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 13)
-set(CMake_VERSION_PATCH 20190118)
+set(CMake_VERSION_PATCH 20190122)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 326d26c..be4a18e 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -71,8 +71,8 @@ int cmCPackDragNDropGenerator::InitializeInternal()
// Starting with Xcode 4.3, look in "/Applications/Xcode.app" first:
//
std::vector<std::string> paths;
- paths.push_back("/Applications/Xcode.app/Contents/Developer/Tools");
- paths.push_back("/Developer/Tools");
+ paths.emplace_back("/Applications/Xcode.app/Contents/Developer/Tools");
+ paths.emplace_back("/Developer/Tools");
const std::string hdiutil_path =
cmSystemTools::FindProgram("hdiutil", std::vector<std::string>(), false);
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index ff69418..9dc9853 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -68,7 +68,7 @@ int cmCPackExternalGenerator::PackageFiles()
return 0;
}
- int res = this->MakefileMap->ReadListFile(packageScript);
+ bool res = this->MakefileMap->ReadListFile(packageScript);
if (cmSystemTools::GetErrorOccuredFlag() || !res) {
return 0;
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index b205105..4728f69 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -498,7 +498,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
tempInstallDirectory.c_str());
this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
tempInstallDirectory.c_str());
- int res = this->MakefileMap->ReadListFile(installScript.c_str());
+ bool res = this->MakefileMap->ReadListFile(installScript);
if (cmSystemTools::GetErrorOccuredFlag() || !res) {
return 0;
}
@@ -851,7 +851,7 @@ int cmCPackGenerator::InstallCMakeProject(
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
}
// do installation
- int res = mf.ReadListFile(installFile.c_str());
+ bool res = mf.ReadListFile(installFile);
// forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
// to CPack (may be used by generators like CPack RPM or DEB)
// in order to transparently handle ABSOLUTE PATH
@@ -927,7 +927,7 @@ bool cmCPackGenerator::ReadListFile(const char* moduleName)
{
bool retval;
std::string fullPath = this->MakefileMap->GetModulesFile(moduleName);
- retval = this->MakefileMap->ReadListFile(fullPath.c_str());
+ retval = this->MakefileMap->ReadListFile(fullPath);
// include FATAL_ERROR and ERROR in the return status
retval = retval && (!cmSystemTools::GetErrorOccuredFlag());
return retval;
@@ -1036,7 +1036,8 @@ int cmCPackGenerator::DoPackage()
* may update this during PackageFiles.
* (either putting several names or updating the provided one)
*/
- packageFileNames.push_back(tempPackageFileName ? tempPackageFileName : "");
+ packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName
+ : "");
toplevel = tempDirectory;
{ // scope that enables package generators to run internal scripts with
// latest CMake policies enabled
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index d02aa5a..4b865ca 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -610,7 +610,7 @@ bool cmCPackNSISGenerator::GetListOfSubdirectories(
}
}
}
- dirs.push_back(topdir);
+ dirs.emplace_back(topdir);
return true;
}
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index a24dd30..28e0561 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -340,16 +340,16 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
// If found, save result in the CPACK_INSTALLER_PROGRAM variable.
std::vector<std::string> paths;
- paths.push_back("/Applications/Xcode.app/Contents/Applications"
- "/PackageMaker.app/Contents/MacOS");
- paths.push_back("/Applications/Utilities"
- "/PackageMaker.app/Contents/MacOS");
- paths.push_back("/Applications"
- "/PackageMaker.app/Contents/MacOS");
- paths.push_back("/Developer/Applications/Utilities"
- "/PackageMaker.app/Contents/MacOS");
- paths.push_back("/Developer/Applications"
- "/PackageMaker.app/Contents/MacOS");
+ paths.emplace_back("/Applications/Xcode.app/Contents/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.emplace_back("/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.emplace_back("/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.emplace_back("/Developer/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.emplace_back("/Developer/Applications"
+ "/PackageMaker.app/Contents/MacOS");
std::string pkgPath;
const char* inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM");
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index db9a0e7..d4c867b 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -256,7 +256,7 @@ int main(int argc, char const* const* argv)
// paths, so FIND_XXX() commands can be used in scripts
std::string systemFile =
globalMF.GetModulesFile("CMakeDetermineSystem.cmake");
- if (!globalMF.ReadListFile(systemFile.c_str())) {
+ if (!globalMF.ReadListFile(systemFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Error reading CMakeDetermineSystem.cmake" << std::endl);
return 1;
@@ -264,7 +264,7 @@ int main(int argc, char const* const* argv)
systemFile =
globalMF.GetModulesFile("CMakeSystemSpecificInformation.cmake");
- if (!globalMF.ReadListFile(systemFile.c_str())) {
+ if (!globalMF.ReadListFile(systemFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Error reading CMakeSystemSpecificInformation.cmake"
<< std::endl);
@@ -280,7 +280,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Read CPack configuration file: " << cpackConfigFile
<< std::endl);
- if (!globalMF.ReadListFile(cpackConfigFile.c_str())) {
+ if (!globalMF.ReadListFile(cpackConfigFile)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Problem reading CPack config file: \""
<< cpackConfigFile << "\"" << std::endl);
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index d49fba2..312d126 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -164,7 +164,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
- cmake cm(cmake::RoleProject, cmState::CTest);
+ cmake cm(cmake::RoleProject, cmState::Project);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
std::string cmakeOutString;
@@ -232,7 +232,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
// do the build
if (this->BuildTargets.empty()) {
- this->BuildTargets.push_back("");
+ this->BuildTargets.emplace_back();
}
for (std::string const& tar : this->BuildTargets) {
cmDuration remainingTime = std::chrono::seconds(0);
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 361883c..d07bd21 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -341,17 +341,17 @@ int cmCTestBuildHandler::ProcessHandler()
// warnings and warning exceptions.
std::vector<std::string>::size_type cc;
for (cc = 0; cmCTestErrorMatches[cc]; cc++) {
- this->CustomErrorMatches.push_back(cmCTestErrorMatches[cc]);
+ this->CustomErrorMatches.emplace_back(cmCTestErrorMatches[cc]);
}
for (cc = 0; cmCTestErrorExceptions[cc]; cc++) {
- this->CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]);
+ this->CustomErrorExceptions.emplace_back(cmCTestErrorExceptions[cc]);
}
for (cc = 0; cmCTestWarningMatches[cc]; cc++) {
- this->CustomWarningMatches.push_back(cmCTestWarningMatches[cc]);
+ this->CustomWarningMatches.emplace_back(cmCTestWarningMatches[cc]);
}
for (cc = 0; cmCTestWarningExceptions[cc]; cc++) {
- this->CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]);
+ this->CustomWarningExceptions.emplace_back(cmCTestWarningExceptions[cc]);
}
// Pre-compile regular expressions objects for all regular expressions
@@ -365,7 +365,7 @@ int cmCTestBuildHandler::ProcessHandler()
cmCTestOptionalLog(this->CTest, DEBUG, \
"Add " #strings ": " << s << std::endl, \
this->Quiet); \
- (regexes).push_back(s.c_str()); \
+ (regexes).emplace_back(s); \
} \
} while (false)
@@ -1034,7 +1034,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, size_t length,
}
} else {
// Otherwise store pre-context for the next error
- this->PreContext.push_back(line);
+ this->PreContext.emplace_back(line);
if (this->PreContext.size() > this->MaxPreContext) {
this->PreContext.erase(this->PreContext.begin(),
this->PreContext.end() -
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 4fb3273..6e1ada1 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -111,8 +111,8 @@ public:
, Revisions(revs)
, Section(SectionHeader)
{
- this->SetLog(&cvs->Log, prefix),
- this->RegexRevision.compile("^revision +([^ ]*) *$");
+ this->SetLog(&cvs->Log, prefix);
+ this->RegexRevision.compile("^revision +([^ ]*) *$");
this->RegexBranches.compile("^branches: .*$");
this->RegexPerson.compile("^date: +([^;]+); +author: +([^;]+);");
}
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index fbd1038..6c68f46 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -56,12 +56,12 @@ public:
void SetCommand(const char* command)
{
this->CommandLineStrings.clear();
- this->CommandLineStrings.push_back(command);
+ this->CommandLineStrings.emplace_back(command);
}
void AddArgument(const char* arg)
{
if (arg) {
- this->CommandLineStrings.push_back(arg);
+ this->CommandLineStrings.emplace_back(arg);
}
}
void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir; }
@@ -316,8 +316,7 @@ int cmCTestCoverageHandler::ProcessHandler()
// setup the regex exclude stuff
this->CustomCoverageExcludeRegex.clear();
for (std::string const& rex : this->CustomCoverageExclude) {
- this->CustomCoverageExcludeRegex.push_back(
- cmsys::RegularExpression(rex.c_str()));
+ this->CustomCoverageExcludeRegex.emplace_back(rex);
}
if (this->HandleBullseyeCoverage(&cont)) {
@@ -1005,7 +1004,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::vector<std::string> basecovargs =
cmSystemTools::ParseArguments(gcovExtraFlags.c_str());
basecovargs.insert(basecovargs.begin(), gcovCommand);
- basecovargs.push_back("-o");
+ basecovargs.emplace_back("-o");
// files is a list of *.da and *.gcda files with coverage data in them.
// These are binary files that you give as input to gcov so that it will
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 4facea2..ec3307f 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -146,7 +146,7 @@ void cmCTestLaunch::HandleRealArg(const char* arg)
return;
}
#endif
- this->RealArgs.push_back(arg);
+ this->RealArgs.emplace_back(arg);
}
void cmCTestLaunch::ComputeFileNames()
@@ -534,9 +534,9 @@ void cmCTestLaunch::LoadScrapeRules()
// Common compiler warning formats. These are much simpler than the
// full log-scraping expressions because we do not need to extract
// file and line information.
- this->RegexWarning.push_back("(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]");
- this->RegexWarning.push_back("(^|[ :])[Rr][Ee][Mm][Aa][Rr][Kk]");
- this->RegexWarning.push_back("(^|[ :])[Nn][Oo][Tt][Ee]");
+ this->RegexWarning.emplace_back("(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]");
+ this->RegexWarning.emplace_back("(^|[ :])[Rr][Ee][Mm][Aa][Rr][Kk]");
+ this->RegexWarning.emplace_back("(^|[ :])[Nn][Oo][Tt][Ee]");
// Load custom match rules given to us by CTest.
this->LoadScrapeRules("Warning", this->RegexWarning);
@@ -619,7 +619,7 @@ void cmCTestLaunch::LoadConfig()
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
std::string fname = this->LogDir;
fname += "CTestLaunchConfig.cmake";
- if (cmSystemTools::FileExists(fname) && mf.ReadListFile(fname.c_str())) {
+ if (cmSystemTools::FileExists(fname) && mf.ReadListFile(fname)) {
this->SourceDir = mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
cmSystemTools::ConvertToUnixSlashes(this->SourceDir);
}
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 9c9532a..8ba59d3 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -261,8 +261,8 @@ void cmCTestMemCheckHandler::InitializeResultsVectors()
};
this->GlobalResults.clear();
for (int i = 0; cmCTestMemCheckResultStrings[i] != nullptr; ++i) {
- this->ResultStrings.push_back(cmCTestMemCheckResultStrings[i]);
- this->ResultStringsLong.push_back(cmCTestMemCheckResultLongStrings[i]);
+ this->ResultStrings.emplace_back(cmCTestMemCheckResultStrings[i]);
+ this->ResultStringsLong.emplace_back(cmCTestMemCheckResultLongStrings[i]);
this->GlobalResults.push_back(0);
}
}
@@ -528,11 +528,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
switch (this->MemoryTesterStyle) {
case cmCTestMemCheckHandler::VALGRIND: {
if (this->MemoryTesterOptions.empty()) {
- this->MemoryTesterOptions.push_back("-q");
- this->MemoryTesterOptions.push_back("--tool=memcheck");
- this->MemoryTesterOptions.push_back("--leak-check=yes");
- this->MemoryTesterOptions.push_back("--show-reachable=yes");
- this->MemoryTesterOptions.push_back("--num-callers=50");
+ this->MemoryTesterOptions.emplace_back("-q");
+ this->MemoryTesterOptions.emplace_back("--tool=memcheck");
+ this->MemoryTesterOptions.emplace_back("--leak-check=yes");
+ this->MemoryTesterOptions.emplace_back("--show-reachable=yes");
+ this->MemoryTesterOptions.emplace_back("--num-callers=50");
}
if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile")
.empty()) {
@@ -586,11 +586,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
std::string dpbdFile = this->CTest->GetBinaryDir() +
"/Testing/Temporary/MemoryChecker.??.DPbd";
this->BoundsCheckerDPBDFile = dpbdFile;
- this->MemoryTesterDynamicOptions.push_back("/B");
+ this->MemoryTesterDynamicOptions.emplace_back("/B");
this->MemoryTesterDynamicOptions.push_back(std::move(dpbdFile));
- this->MemoryTesterDynamicOptions.push_back("/X");
+ this->MemoryTesterDynamicOptions.emplace_back("/X");
this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
- this->MemoryTesterOptions.push_back("/M");
+ this->MemoryTesterOptions.emplace_back("/M");
break;
}
// these are almost the same but the env var used is different
@@ -604,8 +604,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
// The MemoryTesterDynamicOptions is setup with the -E env
// Then the MemoryTesterEnvironmentVariable gets the
// TSAN_OPTIONS string with the log_path in it.
- this->MemoryTesterDynamicOptions.push_back("-E");
- this->MemoryTesterDynamicOptions.push_back("env");
+ this->MemoryTesterDynamicOptions.emplace_back("-E");
+ this->MemoryTesterDynamicOptions.emplace_back("env");
std::string envVar;
std::string extraOptions;
std::string suppressionsOption;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 8867323..320647a 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -1039,6 +1039,11 @@ void cmCTestMultiProcessHandler::PrintOutputAsJson()
testRun.SetTestProperties(&p);
testRun.ComputeArguments();
+ // Skip tests not available in this configuration.
+ if (p.Args.size() >= 2 && p.Args[1] == "NOT_AVAILABLE") {
+ continue;
+ }
+
Json::Value testInfo = DumpCTestInfo(testRun, p, backtraceGraph);
tests.append(testInfo);
}
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 511dbd2..c0bdc17 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -307,20 +307,20 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
{
if (P4Options.empty()) {
const char* p4 = this->CommandLineTool.c_str();
- P4Options.push_back(p4);
+ P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
// Perforce commands, if it's different from the default one.
std::string client = this->CTest->GetCTestConfiguration("P4Client");
if (!client.empty()) {
- P4Options.push_back("-c");
+ P4Options.emplace_back("-c");
P4Options.push_back(client);
}
// Set the message language to be English, in case the P4 admin
// has localized them
- P4Options.push_back("-L");
- P4Options.push_back("en");
+ P4Options.emplace_back("-L");
+ P4Options.emplace_back("en");
// The CTEST_P4_OPTIONS variable adds additional Perforce command line
// options before the main command
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 6c439e9..afde61c 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -521,7 +521,7 @@ private:
} else {
local_path = path;
}
- this->SVN->Repositories.emplace_back(local_path.c_str());
+ this->SVN->Repositories.emplace_back(local_path);
}
};
@@ -532,7 +532,7 @@ bool cmCTestSVN::LoadRepositories()
}
// Info for root repository
- this->Repositories.emplace_back("");
+ this->Repositories.emplace_back();
this->RootInfo = &(this->Repositories.back());
// Run "svn status" to get the list of external repositories
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index a467ede..5c8505d 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -41,7 +41,7 @@ private:
struct SVNInfo
{
- SVNInfo(const char* path)
+ SVNInfo(std::string const& path = std::string())
: LocalPath(path)
{
}
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index aa37ff9..f417f53 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -135,7 +135,7 @@ cmCTestScriptHandler::~cmCTestScriptHandler()
void cmCTestScriptHandler::AddConfigurationScript(const char* script,
bool pscope)
{
- this->ConfigurationScripts.push_back(script);
+ this->ConfigurationScripts.emplace_back(script);
this->ScriptProcessScope.push_back(pscope);
}
@@ -373,7 +373,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
ctest scripting easier. */
std::string systemFile =
this->Makefile->GetModulesFile("CTestScriptMode.cmake");
- if (!this->Makefile->ReadListFile(systemFile.c_str()) ||
+ if (!this->Makefile->ReadListFile(systemFile) ||
cmSystemTools::GetErrorOccuredFlag()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Error in read:" << systemFile << "\n");
@@ -388,7 +388,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
}
// finally read in the script
- if (!this->Makefile->ReadListFile(script.c_str()) ||
+ if (!this->Makefile->ReadListFile(script) ||
cmSystemTools::GetErrorOccuredFlag()) {
// Reset the error flag so that it can run more than
// one script with an error when you use ctest_run_script.
@@ -450,7 +450,7 @@ int cmCTestScriptHandler::ExtractVariables()
updateVar, " specified without specifying CTEST_CVS_COMMAND.");
return 12;
}
- this->ExtraUpdates.push_back(updateVal);
+ this->ExtraUpdates.emplace_back(updateVal);
}
}
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 76a1830..00c0610 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -15,36 +15,28 @@ class cmExecutionStatus;
cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
{
- const char* ctestDropMethod =
- this->Makefile->GetDefinition("CTEST_DROP_METHOD");
- const char* ctestDropSite = this->Makefile->GetDefinition("CTEST_DROP_SITE");
- const char* ctestDropLocation =
- this->Makefile->GetDefinition("CTEST_DROP_LOCATION");
- if (!ctestDropMethod) {
- ctestDropMethod = "http";
- }
+ const char* submitURL = !this->SubmitURL.empty()
+ ? this->SubmitURL.c_str()
+ : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
- if (!ctestDropSite) {
- // error: CDash requires CTEST_DROP_SITE definition
- // in CTestConfig.cmake
- }
- if (!ctestDropLocation) {
- // error: CDash requires CTEST_DROP_LOCATION definition
- // in CTestConfig.cmake
+ if (submitURL) {
+ this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
+ } else {
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
+ this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSite", "CTEST_DROP_SITE", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropLocation", "CTEST_DROP_LOCATION", this->Quiet);
}
- this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod,
- this->Quiet);
- this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet);
- this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation,
- this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
- this->Quiet);
const char* notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
@@ -184,6 +176,11 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
return true;
}
+ if (arg == "SUBMIT_URL") {
+ this->ArgumentDoing = ArgumentDoingSubmitURL;
+ return true;
+ }
+
if (arg == "INTERNAL_TEST_CHECKSUM") {
this->InternalTest = true;
return true;
@@ -249,6 +246,12 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
return true;
}
+ if (this->ArgumentDoing == ArgumentDoingSubmitURL) {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->SubmitURL = arg;
+ return true;
+ }
+
// Look for other arguments.
return this->Superclass::CheckArgumentValue(arg);
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index c4b84ce..0caccd6 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -71,6 +71,7 @@ protected:
ArgumentDoingCDashUpload,
ArgumentDoingCDashUploadType,
ArgumentDoingHttpHeader,
+ ArgumentDoingSubmitURL,
ArgumentDoingLast2
};
@@ -85,6 +86,7 @@ protected:
std::string CDashUploadFile;
std::string CDashUploadType;
std::vector<std::string> HttpHeaders;
+ std::string SubmitURL;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 3042480..5213bd3 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -162,7 +162,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
- std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
std::vector<std::string> args;
cmSystemTools::ExpandListArgument(curlopt, args);
@@ -495,27 +494,6 @@ void cmCTestSubmitHandler::ParseResponse(
}
}
-void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod,
- std::string& url)
-{
- dropMethod = this->CTest->GetCTestConfiguration("DropMethod");
- url = dropMethod;
- url += "://";
- if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) {
- url += this->CTest->GetCTestConfiguration("DropSiteUser");
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) {
- url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", this->Quiet);
- }
- url += "@";
- }
- url += this->CTest->GetCTestConfiguration("DropSite") +
- this->CTest->GetCTestConfiguration("DropLocation");
-}
-
int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
std::string const& typeString)
{
@@ -536,16 +514,15 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
curl.SetCurlOptions(args);
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
- std::string dropMethod;
- std::string url;
- this->ConstructCDashURL(dropMethod, url);
+ std::string url = this->CTest->GetSubmitURL();
std::string fields;
std::string::size_type pos = url.find('?');
if (pos != std::string::npos) {
fields = url.substr(pos + 1);
url = url.substr(0, pos);
}
- if (!(dropMethod == "http" || dropMethod == "https")) {
+ if (!cmHasLiteralPrefix(url, "http://") &&
+ !cmHasLiteralPrefix(url, "https://")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
@@ -861,7 +838,7 @@ int cmCTestSubmitHandler::ProcessHandler()
// Submit Done.xml last
if (this->SubmitPart[cmCTest::PartDone]) {
- files.push_back("Done.xml");
+ files.emplace_back("Done.xml");
}
if (ofs) {
@@ -872,10 +849,7 @@ int cmCTestSubmitHandler::ProcessHandler()
cnt++;
}
}
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- "Submit files (using "
- << this->CTest->GetCTestConfiguration("DropMethod")
- << ")" << std::endl,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n",
this->Quiet);
const char* specificTrack = this->CTest->GetSpecificTrack();
if (specificTrack) {
@@ -885,72 +859,32 @@ int cmCTestSubmitHandler::ProcessHandler()
}
this->SetLogFile(&ofs);
- std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
-
- if (dropMethod.empty()) {
- dropMethod = "http";
+ std::string url = this->CTest->GetSubmitURL();
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " SubmitURL: " << url << '\n', this->Quiet);
+ if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
+ this->CTest->GetCurrentTag(),
+ files, prefix, url)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when submitting via HTTP\n");
+ ofs << " Problems when submitting via HTTP\n";
+ return -1;
}
-
- if (dropMethod == "http" || dropMethod == "https") {
- std::string url = dropMethod;
- url += "://";
- ofs << "Using drop method: " << dropMethod << std::endl;
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Using HTTP submit method" << std::endl
- << " Drop site:" << url,
- this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) {
- url += this->CTest->GetCTestConfiguration("DropSiteUser");
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSiteUser").c_str(),
- this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) {
- url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******",
- this->Quiet);
- }
- url += "@";
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet);
- }
- url += this->CTest->GetCTestConfiguration("DropSite") +
- this->CTest->GetCTestConfiguration("DropLocation");
+ if (this->HasErrors) {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Errors occurred during submission.\n");
+ ofs << " Errors occurred during submission.\n";
+ } else {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSite")
- << this->CTest->GetCTestConfiguration("DropLocation")
+ " Submission successful"
+ << (this->HasWarnings ? ", with warnings." : "")
<< std::endl,
this->Quiet);
- if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
- this->CTest->GetCurrentTag(),
- files, prefix, url)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- " Problems when submitting via HTTP" << std::endl);
- ofs << " Problems when submitting via HTTP" << std::endl;
- return -1;
- }
- if (this->HasErrors) {
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Errors occurred during "
- "submission."
- << std::endl);
- ofs << " Errors occurred during submission. " << std::endl;
- } else {
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Submission successful"
- << (this->HasWarnings ? ", with warnings." : "")
- << std::endl,
- this->Quiet);
- ofs << " Submission successful"
- << (this->HasWarnings ? ", with warnings." : "") << std::endl;
- }
-
- return 0;
+ ofs << " Submission successful"
+ << (this->HasWarnings ? ", with warnings." : "") << std::endl;
}
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- " Unknown submission method: \"" << dropMethod << "\""
- << std::endl);
- return -1;
+ return 0;
}
std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 393e826..58f4f97 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -48,8 +48,6 @@ public:
this->HttpHeaders = v;
}
- void ConstructCDashURL(std::string& dropMethod, std::string& url);
-
private:
void SetLogFile(std::ostream* ost) { this->LogFile = ost; }
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index acbe465..cf2652a 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -104,7 +104,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
}
fname += "/";
fname += testFilename;
- readit = this->Makefile->ReadDependentFile(fname.c_str());
+ readit = this->Makefile->ReadDependentFile(fname);
}
if (!readit) {
std::string m = "Could not find include file: ";
@@ -170,7 +170,7 @@ bool cmCTestAddSubdirectoryCommand::InitialPass(
}
fname += "/";
fname += testFilename;
- readit = this->Makefile->ReadDependentFile(fname.c_str());
+ readit = this->Makefile->ReadDependentFile(fname);
}
if (!readit) {
std::string m = "Could not find include file: ";
@@ -1524,7 +1524,7 @@ void cmCTestTestHandler::AddConfigurations(
}
tempPath = filepath + filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("");
+ attemptedConfigs.emplace_back();
if (!ctest->GetConfigType().empty()) {
tempPath = filepath;
@@ -1547,32 +1547,32 @@ void cmCTestTestHandler::AddConfigurations(
tempPath += "Release/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("Release");
+ attemptedConfigs.emplace_back("Release");
tempPath = filepath;
tempPath += "Debug/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("Debug");
+ attemptedConfigs.emplace_back("Debug");
tempPath = filepath;
tempPath += "MinSizeRel/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("MinSizeRel");
+ attemptedConfigs.emplace_back("MinSizeRel");
tempPath = filepath;
tempPath += "RelWithDebInfo/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("RelWithDebInfo");
+ attemptedConfigs.emplace_back("RelWithDebInfo");
tempPath = filepath;
tempPath += "Deployment/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("Deployment");
+ attemptedConfigs.emplace_back("Deployment");
tempPath = filepath;
tempPath += "Development/";
tempPath += filename;
attempted.push_back(tempPath);
- attemptedConfigs.push_back("Deployment");
+ attemptedConfigs.emplace_back("Deployment");
}
}
diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx
index cc81979..d99de06 100644
--- a/Source/CTest/cmParseDelphiCoverage.cxx
+++ b/Source/CTest/cmParseDelphiCoverage.cxx
@@ -44,7 +44,7 @@ public:
// Check that the begin is the first non-space string on the line
if ((beginPos == line.find_first_not_of(' ')) &&
beginPos != std::string::npos) {
- beginSet.push_back("begin");
+ beginSet.emplace_back("begin");
coverageVector.push_back(-1);
continue;
}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 6dc692e..dbf4a28 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -5,7 +5,7 @@
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmDocumentation.h"
-#include "cmDocumentationEntry.h"
+#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmState.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -88,15 +88,14 @@ int main(int argc, char const* const* argv)
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
- std::vector<cmDocumentationEntry> generators;
- hcm.GetGeneratorDocumentation(generators);
+ auto generators = hcm.GetGeneratorsDocumentation();
doc.SetName("ccmake");
doc.SetSection("Name", cmDocumentationName);
doc.SetSection("Usage", cmDocumentationUsage);
if (argc == 1) {
doc.AppendSection("Usage", cmDocumentationUsageNote);
}
- doc.SetSection("Generators", generators);
+ doc.AppendSection("Generators", generators);
doc.PrependSection("Options", cmDocumentationOptions);
return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
}
@@ -109,7 +108,7 @@ int main(int argc, char const* const* argv)
if (strcmp(argv[j], "-debug") == 0) {
debug = true;
} else {
- args.push_back(argv[j]);
+ args.emplace_back(argv[j]);
}
}
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index a75d913..55ef375 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -37,10 +37,10 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args,
this->AdvancedMode = false;
this->NumberOfVisibleEntries = 0;
this->OkToGenerate = false;
- this->HelpMessage.push_back(
+ this->HelpMessage.emplace_back(
"Welcome to ccmake, curses based user interface for CMake.");
- this->HelpMessage.push_back("");
- this->HelpMessage.push_back(s_ConstHelpMessage);
+ this->HelpMessage.emplace_back();
+ this->HelpMessage.emplace_back(s_ConstHelpMessage);
this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeCursesCommand());
@@ -652,7 +652,7 @@ int cmCursesMainForm::Generate()
void cmCursesMainForm::AddError(const char* message, const char* /*unused*/)
{
- this->Errors.push_back(message);
+ this->Errors.emplace_back(message);
}
void cmCursesMainForm::RemoveEntry(const char* value)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index b4307bb..9f4e48e 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -69,8 +69,7 @@ int main(int argc, char** argv)
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
- std::vector<cmDocumentationEntry> generators;
- hcm.GetGeneratorDocumentation(generators);
+ auto generators = hcm.GetGeneratorsDocumentation();
doc.SetName("cmake");
doc.SetSection("Name", cmDocumentationName);
doc.SetSection("Usage", cmDocumentationUsage);
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 444a980..72cce9f 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -751,6 +751,7 @@ bool CMakeSetupDialog::setupFirstConfigure()
if (dialog.exec() == QDialog::Accepted) {
dialog.saveToSettings();
this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
+ this->CMakeThread->cmakeInstance()->setPlatform(dialog.getPlatform());
this->CMakeThread->cmakeInstance()->setToolset(dialog.getToolset());
QCMakeCacheModel* m = this->CacheValues->cacheModel();
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index 88ce7cb..ae5179c 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -16,8 +16,12 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p)
this->GeneratorOptions = new QComboBox(this);
l->addWidget(this->GeneratorOptions);
+ // Add the generator platform
+ this->PlatformFrame = CreatePlatformWidgets();
+ l->addWidget(PlatformFrame);
+
// Add the ability to specify toolset (-T parameter)
- ToolsetFrame = CreateToolsetWidgets();
+ this->ToolsetFrame = CreateToolsetWidgets();
l->addWidget(ToolsetFrame);
l->addSpacing(6);
@@ -45,7 +49,7 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p)
SLOT(onSelectionChanged(bool)));
QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)), this,
SLOT(onSelectionChanged(bool)));
- QObject::connect(GeneratorOptions,
+ QObject::connect(this->GeneratorOptions,
SIGNAL(currentIndexChanged(QString const&)), this,
SLOT(onGeneratorChanged(QString const&)));
}
@@ -65,6 +69,23 @@ QFrame* StartCompilerSetup::CreateToolsetWidgets()
return frame;
}
+QFrame* StartCompilerSetup::CreatePlatformWidgets()
+{
+ QFrame* frame = new QFrame(this);
+ QVBoxLayout* l = new QVBoxLayout(frame);
+ l->setContentsMargins(0, 0, 0, 0);
+
+ this->PlatformLabel = new QLabel(tr("Optional platform for generator"));
+ l->addWidget(this->PlatformLabel);
+
+ this->PlatformOptions = new QComboBox(frame);
+ this->PlatformOptions->setEditable(true);
+
+ l->addWidget(this->PlatformOptions);
+
+ return frame;
+}
+
StartCompilerSetup::~StartCompilerSetup()
{
}
@@ -80,6 +101,26 @@ void StartCompilerSetup::setGenerators(
for (it = gens.begin(); it != gens.end(); ++it) {
generator_list.append(QString::fromLocal8Bit(it->name.c_str()));
+ if (it->supportsPlatform) {
+ this->GeneratorsSupportingPlatform.append(
+ QString::fromLocal8Bit(it->name.c_str()));
+
+ this
+ ->GeneratorDefaultPlatform[QString::fromLocal8Bit(it->name.c_str())] =
+ QString::fromLocal8Bit(it->defaultPlatform.c_str());
+
+ std::vector<std::string>::const_iterator platformIt =
+ it->supportedPlatforms.cbegin();
+ while (platformIt != it->supportedPlatforms.cend()) {
+
+ this->GeneratorSupportedPlatforms.insert(
+ QString::fromLocal8Bit(it->name.c_str()),
+ QString::fromLocal8Bit((*platformIt).c_str()));
+
+ platformIt++;
+ }
+ }
+
if (it->supportsToolset) {
this->GeneratorsSupportingToolset.append(
QString::fromLocal8Bit(it->name.c_str()));
@@ -102,6 +143,11 @@ QString StartCompilerSetup::getGenerator() const
return this->GeneratorOptions->currentText();
};
+QString StartCompilerSetup::getPlatform() const
+{
+ return this->PlatformOptions->currentText();
+};
+
QString StartCompilerSetup::getToolset() const
{
return this->Toolset->text();
@@ -136,6 +182,31 @@ void StartCompilerSetup::onSelectionChanged(bool on)
void StartCompilerSetup::onGeneratorChanged(QString const& name)
{
+ // Display the generator platform for the generators supporting it
+ if (GeneratorsSupportingPlatform.contains(name)) {
+
+ // Change the label title to include the default platform
+ std::string label = "Optional platform for generator";
+ label += "(if empty, generator uses: ";
+ label += this->GeneratorDefaultPlatform[name].toStdString();
+ label += ")";
+ this->PlatformLabel->setText(tr(label.c_str()));
+
+ // Regenerate the list of supported platform
+ this->PlatformOptions->clear();
+ QStringList platform_list;
+ platform_list.append("");
+
+ QList<QString> platforms = this->GeneratorSupportedPlatforms.values(name);
+ platform_list.append(platforms);
+
+ this->PlatformOptions->addItems(platform_list);
+ PlatformFrame->show();
+ } else {
+ PlatformFrame->hide();
+ }
+
+ // Display the toolset box for the generators supporting it
if (GeneratorsSupportingToolset.contains(name)) {
ToolsetFrame->show();
} else {
@@ -390,6 +461,11 @@ QString FirstConfigure::getGenerator() const
return this->mStartCompilerSetupPage->getGenerator();
}
+QString FirstConfigure::getPlatform() const
+{
+ return this->mStartCompilerSetupPage->getPlatform();
+}
+
QString FirstConfigure::getToolset() const
{
return this->mStartCompilerSetupPage->getToolset();
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index abfa03f..d1db5bf 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -35,6 +35,7 @@ public:
void setCurrentGenerator(const QString& gen);
QString getGenerator() const;
QString getToolset() const;
+ QString getPlatform() const;
bool defaultSetup() const;
bool compilerSetup() const;
@@ -56,10 +57,17 @@ protected:
QFrame* ToolsetFrame;
QLineEdit* Toolset;
QLabel* ToolsetLabel;
+ QFrame* PlatformFrame;
+ QComboBox* PlatformOptions;
+ QLabel* PlatformLabel;
QStringList GeneratorsSupportingToolset;
+ QStringList GeneratorsSupportingPlatform;
+ QMultiMap<QString, QString> GeneratorSupportedPlatforms;
+ QMap<QString, QString> GeneratorDefaultPlatform;
private:
QFrame* CreateToolsetWidgets();
+ QFrame* CreatePlatformWidgets();
};
//! the page that gives basic options for native compilers
@@ -159,6 +167,7 @@ public:
void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
QString getGenerator() const;
+ QString getPlatform() const;
QString getToolset() const;
bool defaultSetup() const;
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 9a6784e..2eecce6 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -35,7 +35,8 @@ QCMake::QCMake(QObject* p)
cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
std::vector<cmake::GeneratorInfo> generators;
- this->CMakeInstance->GetRegisteredGenerators(generators);
+ this->CMakeInstance->GetRegisteredGenerators(
+ generators, /*includeNamesWithPlatform=*/false);
std::vector<cmake::GeneratorInfo>::const_iterator it;
for (it = generators.begin(); it != generators.end(); ++it) {
@@ -74,6 +75,7 @@ void QCMake::setBinaryDirectory(const QString& _dir)
cmState* state = this->CMakeInstance->GetState();
this->setGenerator(QString());
this->setToolset(QString());
+ this->setPlatform(QString());
if (!this->CMakeInstance->LoadCache(
this->BinaryDirectory.toLocal8Bit().data())) {
QDir testDir(this->BinaryDirectory);
@@ -102,6 +104,12 @@ void QCMake::setBinaryDirectory(const QString& _dir)
this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
}
+ const char* platform =
+ state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
+ if (platform) {
+ this->setPlatform(QString::fromLocal8Bit(platform));
+ }
+
const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
if (toolset) {
this->setToolset(QString::fromLocal8Bit(toolset));
@@ -119,6 +127,14 @@ void QCMake::setGenerator(const QString& gen)
}
}
+void QCMake::setPlatform(const QString& platform)
+{
+ if (this->Platform != platform) {
+ this->Platform = platform;
+ emit this->platformChanged(this->Platform);
+ }
+}
+
void QCMake::setToolset(const QString& toolset)
{
if (this->Toolset != toolset) {
@@ -140,7 +156,8 @@ void QCMake::configure()
this->CMakeInstance->SetGlobalGenerator(
this->CMakeInstance->CreateGlobalGenerator(
this->Generator.toLocal8Bit().data()));
- this->CMakeInstance->SetGeneratorPlatform("");
+ this->CMakeInstance->SetGeneratorPlatform(
+ this->Platform.toLocal8Bit().data());
this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
this->CMakeInstance->LoadCache();
this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 4b3920a..c84da58 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -75,6 +75,8 @@ public slots:
/// set the desired generator to use
void setGenerator(const QString& generator);
/// set the desired generator to use
+ void setPlatform(const QString& platform);
+ /// set the desired generator to use
void setToolset(const QString& toolset);
/// do the configure step
void configure();
@@ -155,6 +157,8 @@ signals:
void debugOutputChanged(bool);
/// signal when the toolset changes
void toolsetChanged(const QString& toolset);
+ /// signal when the platform changes
+ void platformChanged(const QString& platform);
/// signal when open is done
void openDone(bool successful);
/// signal when open is done
@@ -175,6 +179,7 @@ protected:
QString SourceDirectory;
QString BinaryDirectory;
QString Generator;
+ QString Platform;
QString Toolset;
std::vector<cmake::GeneratorInfo> AvailableGenerators;
QString CMakeExecutable;
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 264c63c..8ed43f9 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -181,7 +181,7 @@ void CCONV cmAddExecutable(void* arg, const char* exename, int numSrcs,
std::vector<std::string> srcs2;
int i;
for (i = 0; i < numSrcs; ++i) {
- srcs2.push_back(srcs[i]);
+ srcs2.emplace_back(srcs[i]);
}
cmTarget* tg = mf->AddExecutable(exename, srcs2);
if (win32) {
@@ -393,7 +393,7 @@ void CCONV cmAddLibrary(void* arg, const char* libname, int shared,
std::vector<std::string> srcs2;
int i;
for (i = 0; i < numSrcs; ++i) {
- srcs2.push_back(srcs[i]);
+ srcs2.emplace_back(srcs[i]);
}
mf->AddLibrary(
libname,
@@ -419,8 +419,7 @@ int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs,
lff.Name = name;
for (int i = 0; i < numArgs; ++i) {
// Assume all arguments are quoted.
- lff.Arguments.push_back(
- cmListFileArgument(args[i], cmListFileArgument::Quoted, 0));
+ lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0);
}
cmExecutionStatus status;
return mf->ExecuteCommand(lff, status);
@@ -436,7 +435,7 @@ void CCONV cmExpandSourceListArguments(void* arg, int numArgs,
std::vector<std::string> result;
int i;
for (i = 0; i < numArgs; ++i) {
- result.push_back(args[i]);
+ result.emplace_back(args[i]);
}
int resargc = static_cast<int>(result.size());
char** resargv = nullptr;
@@ -627,7 +626,7 @@ void CCONV cmSourceFileAddDepend(void* arg, const char* depend)
if (cmSourceFile* rsf = sf->RealSourceFile) {
rsf->AddDepend(depend);
} else {
- sf->Depends.push_back(depend);
+ sf->Depends.emplace_back(depend);
}
}
@@ -647,10 +646,10 @@ void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir,
std::vector<std::string> headerExts;
int i;
for (i = 0; i < numSourceExtensions; ++i) {
- sourceExts.push_back(sourceExtensions[i]);
+ sourceExts.emplace_back(sourceExtensions[i]);
}
for (i = 0; i < numHeaderExtensions; ++i) {
- headerExts.push_back(headerExtensions[i]);
+ headerExts.emplace_back(headerExtensions[i]);
}
// Save the original name given.
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 1c0d9f6..4e2f275 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -640,7 +640,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
" Reading ctest configuration file: " << fname
<< std::endl,
command->ShouldBeQuiet());
- bool readit = mf->ReadDependentFile(fname.c_str());
+ bool readit = mf->ReadDependentFile(fname);
if (!readit) {
std::string m = "Could not find include file: ";
m += fname;
@@ -1176,12 +1176,12 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (strcmp(i, "--build-generator") == 0 &&
timeout != cmCTest::MaxDuration() &&
timeout > cmDuration::zero()) {
- args.push_back("--test-timeout");
+ args.emplace_back("--test-timeout");
std::ostringstream msg;
msg << cmDurationTo<unsigned int>(timeout);
args.push_back(msg.str());
}
- args.push_back(i);
+ args.emplace_back(i);
}
}
if (log) {
@@ -1944,6 +1944,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->Quiet = true;
this->OutputAsJson = true;
this->OutputAsJsonVersion = 1;
+ } else if (format != "human") {
+ errormsg = "'--show-only=' given unknown value '" + format + "'";
+ return false;
}
}
@@ -2469,8 +2472,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag();
- if (!mf->ReadListFile(fname.c_str()) ||
- cmSystemTools::GetErrorOccuredFlag()) {
+ if (!mf->ReadListFile(fname) || cmSystemTools::GetErrorOccuredFlag()) {
cmCTestLog(this, ERROR_MESSAGE,
"Problem reading custom configuration: " << fname
<< std::endl);
@@ -2489,15 +2491,13 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
gl.RecurseOn();
gl.FindFiles(rexpr);
std::vector<std::string>& files = gl.GetFiles();
- std::vector<std::string>::iterator fileIt;
- for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
+ for (const std::string& file : files) {
cmCTestLog(this, DEBUG,
- "* Read custom CTest configuration file: " << *fileIt
+ "* Read custom CTest configuration file: " << file
<< std::endl);
- if (!mf->ReadListFile(fileIt->c_str()) ||
- cmSystemTools::GetErrorOccuredFlag()) {
+ if (!mf->ReadListFile(file) || cmSystemTools::GetErrorOccuredFlag()) {
cmCTestLog(this, ERROR_MESSAGE,
- "Problem reading custom configuration: " << *fileIt
+ "Problem reading custom configuration: " << file
<< std::endl);
}
}
@@ -2626,6 +2626,32 @@ void cmCTest::SetCTestConfiguration(const char* name, const char* value,
this->CTestConfiguration[name] = value;
}
+std::string cmCTest::GetSubmitURL()
+{
+ std::string url = this->GetCTestConfiguration("SubmitURL");
+ if (url.empty()) {
+ std::string method = this->GetCTestConfiguration("DropMethod");
+ std::string user = this->GetCTestConfiguration("DropSiteUser");
+ std::string password = this->GetCTestConfiguration("DropSitePassword");
+ std::string site = this->GetCTestConfiguration("DropSite");
+ std::string location = this->GetCTestConfiguration("DropLocation");
+
+ url = method.empty() ? "http" : method;
+ url += "://";
+ if (!user.empty()) {
+ url += user;
+ if (!password.empty()) {
+ url += ':';
+ url += password;
+ }
+ url += '@';
+ }
+ url += site;
+ url += location;
+ }
+ return url;
+}
+
std::string cmCTest::GetCurrentTag()
{
return this->CurrentTag;
@@ -2690,7 +2716,7 @@ void cmCTest::SetSpecificTrack(const char* track)
void cmCTest::AddSubmitFile(Part part, const char* name)
{
- this->Parts[part].SubmitFiles.push_back(name);
+ this->Parts[part].SubmitFiles.emplace_back(name);
}
void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr)
@@ -2781,13 +2807,13 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) &&
this->ExtraVerbose) {
processOutput.DecodeText(data, length, strdata);
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
}
if (this->ExtraVerbose) {
processOutput.DecodeText(std::string(), strdata);
if (!strdata.empty()) {
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 2b40ca3..a82f400 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -176,6 +176,8 @@ public:
bool suppress = false);
void EmptyCTestConfiguration();
+ std::string GetSubmitURL();
+
/**
* constructor and destructor
*/
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 4274cb4..87bc150 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -884,12 +884,12 @@ void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
{
if (e && *e) {
if (type == LinkStatic) {
- this->StaticLinkExtensions.push_back(e);
+ this->StaticLinkExtensions.emplace_back(e);
}
if (type == LinkShared) {
- this->SharedLinkExtensions.push_back(e);
+ this->SharedLinkExtensions.emplace_back(e);
}
- this->LinkExtensions.push_back(e);
+ this->LinkExtensions.emplace_back(e);
}
}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index ef250d7..272535d 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -1023,12 +1023,12 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
tmp += config;
searchDirs.push_back(std::move(tmp));
}
- searchDirs.push_back("/Debug");
+ searchDirs.emplace_back("/Debug");
#if defined(__APPLE__)
std::string app = "/Debug/" + targetName + ".app";
searchDirs.push_back(std::move(app));
#endif
- searchDirs.push_back("/Development");
+ searchDirs.emplace_back("/Development");
for (std::string const& sdir : searchDirs) {
std::string command = this->BinaryDirectory;
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 2acb015..3b3783a 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -13,7 +13,7 @@
#include <string.h>
#include <utility>
-cmDepends::cmDepends(cmLocalGenerator* lg, const char* targetDir)
+cmDepends::cmDepends(cmLocalGenerator* lg, const std::string& targetDir)
: LocalGenerator(lg)
, TargetDirectory(targetDir)
, Dependee(new char[MaxPath])
@@ -65,12 +65,13 @@ bool cmDepends::Finalize(std::ostream& /*unused*/, std::ostream& /*unused*/)
return true;
}
-bool cmDepends::Check(const char* makeFile, const char* internalFile,
+bool cmDepends::Check(const std::string& makeFile,
+ const std::string& internalFile,
std::map<std::string, DependencyVector>& validDeps)
{
// Check whether dependencies must be regenerated.
bool okay = true;
- cmsys::ifstream fin(internalFile);
+ cmsys::ifstream fin(internalFile.c_str());
if (!(fin && this->CheckDependencies(fin, internalFile, validDeps))) {
// Clear all dependencies so they will be regenerated.
this->Clear(makeFile);
@@ -81,13 +82,13 @@ bool cmDepends::Check(const char* makeFile, const char* internalFile,
return okay;
}
-void cmDepends::Clear(const char* file)
+void cmDepends::Clear(const std::string& file)
{
// Print verbose output.
if (this->Verbose) {
std::ostringstream msg;
msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
// Write an empty dependency file.
@@ -107,7 +108,7 @@ bool cmDepends::WriteDependencies(const std::set<std::string>& /*unused*/,
}
bool cmDepends::CheckDependencies(
- std::istream& internalDepends, const char* internalDependsFileName,
+ std::istream& internalDepends, const std::string& internalDependsFileName,
std::map<std::string, DependencyVector>& validDeps)
{
// Parse dependencies from the stream. If any dependee is missing
@@ -170,7 +171,7 @@ bool cmDepends::CheckDependencies(
std::ostringstream msg;
msg << "Dependee \"" << dependee << "\" does not exist for depender \""
<< depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
} else {
if (dependerExists) {
@@ -187,15 +188,15 @@ bool cmDepends::CheckDependencies(
std::ostringstream msg;
msg << "Dependee \"" << dependee << "\" is newer than depender \""
<< depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
}
} else {
// The dependee exists, but the depender doesn't. Regenerate if the
// internalDepends file is older than the dependee.
int result = 0;
- if ((!this->FileComparison->FileTimeCompare(internalDependsFileName,
- dependee, &result) ||
+ if ((!this->FileComparison->FileTimeCompare(
+ internalDependsFileName.c_str(), dependee, &result) ||
result < 0)) {
// The depends-file is older than the dependee.
regenerate = true;
@@ -206,7 +207,7 @@ bool cmDepends::CheckDependencies(
msg << "Dependee \"" << dependee
<< "\" is newer than depends file \""
<< internalDependsFileName << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
}
}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index 705d215..b0b5bb5 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -29,7 +29,7 @@ class cmDepends
public:
/** Instances need to know the build directory name and the relative
path from the build directory to the target file. */
- cmDepends(cmLocalGenerator* lg = nullptr, const char* targetDir = "");
+ cmDepends(cmLocalGenerator* lg = nullptr, const std::string& targetDir = "");
/** Set the local generator for the directory in which we are
scanning dependencies. This is not a full local generator; it
@@ -41,7 +41,10 @@ public:
void SetLanguage(const std::string& lang) { this->Language = lang; }
/** Set the target build directory. */
- void SetTargetDirectory(const char* dir) { this->TargetDirectory = dir; }
+ void SetTargetDirectory(const std::string& dir)
+ {
+ this->TargetDirectory = dir;
+ }
/** should this be verbose in its output */
void SetVerbose(bool verb) { this->Verbose = verb; }
@@ -61,11 +64,11 @@ public:
they must be generated Clear has already been called to wipe out
the old dependencies.
Dependencies which are still valid will be stored in validDeps. */
- bool Check(const char* makeFile, const char* internalFile,
+ bool Check(const std::string& makeFile, const std::string& internalFile,
std::map<std::string, DependencyVector>& validDeps);
/** Clear dependencies for the target file so they will be regenerated. */
- void Clear(const char* file);
+ void Clear(const std::string& file);
/** Set the file comparison object */
void SetFileComparison(cmFileTimeComparison* fc)
@@ -85,7 +88,7 @@ protected:
// Return false if dependencies must be regenerated and true
// otherwise.
virtual bool CheckDependencies(
- std::istream& internalDepends, const char* internalDependsFileName,
+ std::istream& internalDepends, const std::string& internalDependsFileName,
std::map<std::string, DependencyVector>& validDeps);
// Finalize the dependency information for the target.
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 072d116..f6ac4f2 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -24,7 +24,7 @@ cmDependsC::cmDependsC()
}
cmDependsC::cmDependsC(
- cmLocalGenerator* lg, const char* targetDir, const std::string& lang,
+ cmLocalGenerator* lg, const std::string& targetDir, const std::string& lang,
const std::map<std::string, DependencyVector>* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
@@ -53,8 +53,8 @@ cmDependsC::cmDependsC(
}
this->IncludeRegexLine.compile(INCLUDE_REGEX_LINE);
- this->IncludeRegexScan.compile(scanRegex.c_str());
- this->IncludeRegexComplain.compile(complainRegex.c_str());
+ this->IncludeRegexScan.compile(scanRegex);
+ this->IncludeRegexComplain.compile(complainRegex);
this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE;
this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER;
this->IncludeRegexScanString += scanRegex;
@@ -212,7 +212,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Scan this file for new dependencies. Pass the directory
// containing the file to handle double-quote includes.
std::string dir = cmSystemTools::GetFilenamePath(fullName);
- this->Scan(fin, dir.c_str(), fullName);
+ this->Scan(fin, dir, fullName);
} else {
// Skip file with encoding we do not implement.
}
@@ -342,7 +342,7 @@ void cmDependsC::WriteCacheFile() const
}
}
-void cmDependsC::Scan(std::istream& is, const char* directory,
+void cmDependsC::Scan(std::istream& is, const std::string& directory,
const std::string& fullName)
{
cmIncludeLines* newCacheEntry = new cmIncludeLines;
@@ -418,7 +418,7 @@ void cmDependsC::SetupTransforms()
sep = "|";
}
xform += ")[ \t]*\\(([^),]*)\\)";
- this->IncludeRegexTransform.compile(xform.c_str());
+ this->IncludeRegexTransform.compile(xform);
// Build a string that encodes all transformation rules and will
// change when rules are changed.
@@ -460,11 +460,11 @@ void cmDependsC::TransformLine(std::string& line)
// Construct the transformed line.
std::string newline = this->IncludeRegexTransform.match(1);
std::string arg = this->IncludeRegexTransform.match(4);
- for (const char* c = tri->second.c_str(); *c; ++c) {
- if (*c == '%') {
+ for (char c : tri->second) {
+ if (c == '%') {
newline += arg;
} else {
- newline += *c;
+ newline += c;
}
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index f833888..af2b06e 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -28,7 +28,7 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
- cmDependsC(cmLocalGenerator* lg, const char* targetDir,
+ cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
const std::string& lang,
const std::map<std::string, DependencyVector>* validDeps);
@@ -42,7 +42,7 @@ protected:
std::ostream& internalDepends) override;
// Method to scan a single file.
- void Scan(std::istream& is, const char* directory,
+ void Scan(std::istream& is, const std::string& directory,
const std::string& fullName);
// Regular expression to identify C preprocessor include directives.
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index e51f81e..6c5f647 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -7,7 +7,6 @@
#include <iostream>
#include <map>
#include <stdlib.h>
-#include <string.h>
#include <utility>
#include "cmAlgorithms.h"
@@ -54,7 +53,8 @@ public:
typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
ObjectInfoMap ObjectInfo;
- cmFortranSourceInfo& CreateObjectInfo(const char* obj, const char* src)
+ cmFortranSourceInfo& CreateObjectInfo(const std::string& obj,
+ const std::string& src)
{
std::map<std::string, cmFortranSourceInfo>::iterator i =
this->ObjectInfo.find(obj);
@@ -121,8 +121,7 @@ bool cmDependsFortran::WriteDependencies(const std::set<std::string>& sources,
bool okay = true;
for (std::string const& src : sources) {
// Get the information object for this source.
- cmFortranSourceInfo& info =
- this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
+ cmFortranSourceInfo& info = this->Internal->CreateObjectInfo(obj, src);
// Create the parser object. The constructor takes info by reference,
// so we may look into the resulting objects later.
@@ -153,7 +152,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
this->LocateModules();
// Get the directory in which stamp files will be stored.
- const char* stamp_dir = this->TargetDirectory.c_str();
+ const std::string& stamp_dir = this->TargetDirectory;
// Get the directory in which module files will be created.
cmMakefile* mf = this->LocalGenerator->GetMakefile();
@@ -167,9 +166,8 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
for (auto const& i : objInfo) {
- if (!this->WriteDependenciesReal(i.first.c_str(), i.second, mod_dir,
- stamp_dir, makeDepends,
- internalDepends)) {
+ if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir,
+ makeDepends, internalDepends)) {
return false;
}
}
@@ -256,22 +254,22 @@ void cmDependsFortran::LocateModules()
std::string fname = targetDir + "/fortran.internal";
cmsys::ifstream fin(fname.c_str());
if (fin) {
- this->MatchRemoteModules(fin, targetDir.c_str());
+ this->MatchRemoteModules(fin, targetDir);
}
}
}
void cmDependsFortran::MatchLocalModules()
{
- const char* stampDir = this->TargetDirectory.c_str();
+ std::string const& stampDir = this->TargetDirectory;
std::set<std::string> const& provides = this->Internal->TargetProvides;
for (std::string const& i : provides) {
- this->ConsiderModule(i.c_str(), stampDir);
+ this->ConsiderModule(i, stampDir);
}
}
void cmDependsFortran::MatchRemoteModules(std::istream& fin,
- const char* stampDir)
+ const std::string& stampDir)
{
std::string line;
bool doing_provides = false;
@@ -300,7 +298,8 @@ void cmDependsFortran::MatchRemoteModules(std::istream& fin,
}
}
-void cmDependsFortran::ConsiderModule(const char* name, const char* stampDir)
+void cmDependsFortran::ConsiderModule(const std::string& name,
+ const std::string& stampDir)
{
// Locate each required module.
typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
@@ -317,17 +316,17 @@ void cmDependsFortran::ConsiderModule(const char* name, const char* stampDir)
}
}
-bool cmDependsFortran::WriteDependenciesReal(const char* obj,
+bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
cmFortranSourceInfo const& info,
std::string const& mod_dir,
- const char* stamp_dir,
+ std::string const& stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends)
{
typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
// Get the source file for this object.
- const char* src = info.Source.c_str();
+ std::string const& src = info.Source;
// Write the include dependencies to the output stream.
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
@@ -502,8 +501,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
cmFortranModuleAppendUpperLower(cmSystemTools::GetFilenameName(mod),
mod_upper, mod_lower);
if (cmSystemTools::FileExists(mod_upper, true)) {
- if (cmDependsFortran::ModulesDiffer(mod_upper.c_str(), stamp.c_str(),
- compilerId.c_str())) {
+ if (cmDependsFortran::ModulesDiffer(mod_upper, stamp, compilerId)) {
if (!cmSystemTools::CopyFileAlways(mod_upper, stamp)) {
std::cerr << "Error copying Fortran module from \"" << mod_upper
<< "\" to \"" << stamp << "\".\n";
@@ -513,8 +511,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
return true;
}
if (cmSystemTools::FileExists(mod_lower, true)) {
- if (cmDependsFortran::ModulesDiffer(mod_lower.c_str(), stamp.c_str(),
- compilerId.c_str())) {
+ if (cmDependsFortran::ModulesDiffer(mod_lower, stamp, compilerId)) {
if (!cmSystemTools::CopyFileAlways(mod_lower, stamp)) {
std::cerr << "Error copying Fortran module from \"" << mod_lower
<< "\" to \"" << stamp << "\".\n";
@@ -581,9 +578,9 @@ static bool cmFortranStreamsDiffer(std::istream& ifs1, std::istream& ifs2)
return true;
}
-bool cmDependsFortran::ModulesDiffer(const char* modFile,
- const char* stampFile,
- const char* compilerId)
+bool cmDependsFortran::ModulesDiffer(const std::string& modFile,
+ const std::string& stampFile,
+ const std::string& compilerId)
{
/*
gnu >= 4.9:
@@ -617,16 +614,17 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
* source is compiled twice
* -SunPro
*/
- if (strcmp(compilerId, "SunPro") == 0) {
+ if (compilerId == "SunPro") {
return cmSystemTools::FilesDiffer(modFile, stampFile);
}
#if defined(_WIN32) || defined(__CYGWIN__)
- cmsys::ifstream finModFile(modFile, std::ios::in | std::ios::binary);
- cmsys::ifstream finStampFile(stampFile, std::ios::in | std::ios::binary);
+ cmsys::ifstream finModFile(modFile.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream finStampFile(stampFile.c_str(),
+ std::ios::in | std::ios::binary);
#else
- cmsys::ifstream finModFile(modFile);
- cmsys::ifstream finStampFile(stampFile);
+ cmsys::ifstream finModFile(modFile.c_str());
+ cmsys::ifstream finStampFile(stampFile.c_str());
#endif
if (!finModFile || !finStampFile) {
// At least one of the files does not exist. The modules differ.
@@ -641,7 +639,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
* Eat the stream content until all recompile only related changes
* are left behind.
*/
- if (strcmp(compilerId, "GNU") == 0) {
+ if (compilerId == "GNU") {
// GNU Fortran 4.9 and later compress .mod files with gzip
// but also do not include a date so we can fall through to
// compare them without skipping any prefix.
@@ -664,7 +662,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
return true;
}
}
- } else if (strcmp(compilerId, "Intel") == 0) {
+ } else if (compilerId == "Intel") {
const char seq[2] = { '\n', '\0' };
const int seqlen = 2;
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 5d96dd4..f5f5be2 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -44,8 +44,9 @@ public:
/** Determine if a mod file and the corresponding mod.stamp file
are representing different module information. */
- static bool ModulesDiffer(const char* modFile, const char* stampFile,
- const char* compilerId);
+ static bool ModulesDiffer(const std::string& modFile,
+ const std::string& stampFile,
+ const std::string& compilerId);
protected:
// Finalize the dependency information for the target.
@@ -55,8 +56,8 @@ protected:
// Find all the modules required by the target.
void LocateModules();
void MatchLocalModules();
- void MatchRemoteModules(std::istream& fin, const char* stampDir);
- void ConsiderModule(const char* name, const char* stampDir);
+ void MatchRemoteModules(std::istream& fin, const std::string& stampDir);
+ void ConsiderModule(const std::string& name, const std::string& stampDir);
bool FindModule(std::string const& name, std::string& module);
// Implement writing/checking methods required by superclass.
@@ -65,8 +66,10 @@ protected:
std::ostream& internalDepends) override;
// Actually write the dependencies to the streams.
- bool WriteDependenciesReal(const char* obj, cmFortranSourceInfo const& info,
- std::string const& mod_dir, const char* stamp_dir,
+ bool WriteDependenciesReal(std::string const& obj,
+ cmFortranSourceInfo const& info,
+ std::string const& mod_dir,
+ std::string const& stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends);
diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx
index 29938ba..b44b3a2 100644
--- a/Source/cmDependsJava.cxx
+++ b/Source/cmDependsJava.cxx
@@ -27,7 +27,8 @@ bool cmDependsJava::WriteDependencies(const std::set<std::string>& sources,
}
bool cmDependsJava::CheckDependencies(
- std::istream& /*internalDepends*/, const char* /*internalDependsFileName*/,
+ std::istream& /*internalDepends*/,
+ const std::string& /*internalDependsFileName*/,
std::map<std::string, DependencyVector>& /*validDeps*/)
{
return true;
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index d070840..1928c51 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -33,7 +33,7 @@ protected:
const std::string& file, std::ostream& makeDepends,
std::ostream& internalDepends) override;
bool CheckDependencies(
- std::istream& internalDepends, const char* internalDependsFileName,
+ std::istream& internalDepends, const std::string& internalDependsFileName,
std::map<std::string, DependencyVector>& validDeps) override;
};
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 02db119..792db48 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -68,7 +68,7 @@ void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
return;
}
}
- this->ClassesFound.push_back(sclass);
+ this->ClassesFound.emplace_back(sclass);
}
void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
@@ -78,7 +78,7 @@ void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
return;
}
}
- this->PackagesImport.push_back(sclass);
+ this->PackagesImport.emplace_back(sclass);
}
void cmDependsJavaParserHelper::SafePrintMissing(const char* str, int line,
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 6a817b4..d4628fa 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -43,11 +43,18 @@ static const char* cmDocumentationStandardOptions[][2] = {
{ nullptr, nullptr }
};
-static const char* cmDocumentationGeneratorsHeader[][2] = {
+static const char* cmDocumentationCPackGeneratorsHeader[][2] = {
{ nullptr, "The following generators are available on this platform:" },
{ nullptr, nullptr }
};
+static const char* cmDocumentationCMakeGeneratorsHeader[][2] = {
+ { nullptr,
+ "The following generators are available on this platform (* marks "
+ "default):" },
+ { nullptr, nullptr }
+};
+
cmDocumentation::cmDocumentation()
{
this->addCommonStandardDocSections();
@@ -178,7 +185,7 @@ void cmDocumentation::addCommonStandardDocSections()
void cmDocumentation::addCMakeStandardDocSections()
{
cmDocumentationSection sec{ "Generators" };
- sec.Append(cmDocumentationGeneratorsHeader);
+ sec.Append(cmDocumentationCMakeGeneratorsHeader);
this->AllSections.emplace("Generators", std::move(sec));
}
@@ -191,7 +198,9 @@ void cmDocumentation::addCTestStandardDocSections()
void cmDocumentation::addCPackStandardDocSections()
{
- addCMakeStandardDocSections();
+ cmDocumentationSection sec{ "Generators" };
+ sec.Append(cmDocumentationCPackGeneratorsHeader);
+ this->AllSections.emplace("Generators", std::move(sec));
}
bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
diff --git a/Source/cmDocumentationEntry.h b/Source/cmDocumentationEntry.h
index ea43b88..ca323cc 100644
--- a/Source/cmDocumentationEntry.h
+++ b/Source/cmDocumentationEntry.h
@@ -12,6 +12,7 @@ struct cmDocumentationEntry
{
std::string Name;
std::string Brief;
+ char CustomNamePrefix = ' ';
cmDocumentationEntry() {}
cmDocumentationEntry(const char* doc[2])
{
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index 678e408..e573c04 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -5,6 +5,7 @@
#include "cmDocumentationEntry.h"
#include "cmDocumentationSection.h"
+#include <iomanip>
#include <ostream>
#include <string.h>
#include <string>
@@ -168,7 +169,7 @@ void cmDocumentationFormatter::PrintSection(
const std::vector<cmDocumentationEntry>& entries = section.GetEntries();
for (cmDocumentationEntry const& entry : entries) {
if (!entry.Name.empty()) {
- os << " " << entry.Name;
+ os << std::setw(2) << std::left << entry.CustomNamePrefix << entry.Name;
this->TextIndent = " ";
int align = static_cast<int>(strlen(this->TextIndent)) - 4;
for (int i = static_cast<int>(entry.Name.size()); i < align; ++i) {
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index ea4cd40..75a7786 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -217,11 +217,11 @@ bool cmExecProgramCommand::RunCommand(const char* command, std::string& output,
int p;
cmProcessOutput processOutput(encoding);
std::string strdata;
- while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+ while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
if (p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR) {
if (verbose) {
processOutput.DecodeText(data, length, strdata);
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
output.append(data, length);
}
@@ -230,7 +230,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, std::string& output,
if (verbose) {
processOutput.DecodeText(std::string(), strdata);
if (!strdata.empty()) {
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
}
@@ -270,7 +270,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, std::string& output,
}
msg += "\n";
if (verbose) {
- cmSystemTools::Stdout(msg.c_str());
+ cmSystemTools::Stdout(msg);
}
output += msg;
#else
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 679a648..8c67cdb 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -54,7 +54,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
if (args[i] == "COMMAND") {
doing_command = true;
command_index = cmds.size();
- cmds.push_back(std::vector<const char*>());
+ cmds.emplace_back();
} else if (args[i] == "OUTPUT_VARIABLE") {
doing_command = false;
if (++i < args.size()) {
@@ -244,19 +244,19 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
int p;
cmProcessOutput processOutput(encoding);
std::string strdata;
- while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+ while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
// Put the output in the right place.
if (p == cmsysProcess_Pipe_STDOUT && !output_quiet) {
if (output_variable.empty()) {
processOutput.DecodeText(data, length, strdata, 1);
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
} else {
cmExecuteProcessCommandAppend(tempOutput, data, length);
}
} else if (p == cmsysProcess_Pipe_STDERR && !error_quiet) {
if (error_variable.empty()) {
processOutput.DecodeText(data, length, strdata, 2);
- cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+ cmSystemTools::Stderr(strdata);
} else {
cmExecuteProcessCommandAppend(tempError, data, length);
}
@@ -265,13 +265,13 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
if (!output_quiet && output_variable.empty()) {
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
}
if (!error_quiet && error_variable.empty()) {
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
- cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+ cmSystemTools::Stderr(strdata);
}
}
@@ -327,15 +327,15 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
cmsysProcess_GetExitValueByIndex(cp, static_cast<int>(i));
char buf[16];
sprintf(buf, "%d", exitCode);
- res.push_back(buf);
+ res.emplace_back(buf);
} break;
case kwsysProcess_StateByIndex_Exception:
- res.push_back(cmsysProcess_GetExceptionStringByIndex(
+ res.emplace_back(cmsysProcess_GetExceptionStringByIndex(
cp, static_cast<int>(i)));
break;
case kwsysProcess_StateByIndex_Error:
default:
- res.push_back("Error getting the child return code");
+ res.emplace_back("Error getting the child return code");
break;
}
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index db2fde8..999af54 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -185,6 +185,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "READ_SYMLINK") {
return this->HandleReadSymlinkCommand(args);
}
+ if (subCommand == "CREATE_LINK") {
+ return this->HandleCreateLinkCommand(args);
+ }
std::string e = "does not recognize sub-command " + subCommand;
this->SetError(e);
@@ -3670,3 +3673,119 @@ bool cmFileCommand::HandleReadSymlinkCommand(
return true;
}
+
+bool cmFileCommand::HandleCreateLinkCommand(
+ std::vector<std::string> const& args)
+{
+ if (args.size() < 3) {
+ this->SetError("CREATE_LINK must be called with at least two additional "
+ "arguments");
+ return false;
+ }
+
+ cmCommandArgumentsHelper argHelper;
+ cmCommandArgumentGroup group;
+
+ cmCAString linkArg(&argHelper, "CREATE_LINK");
+ cmCAString fileArg(&argHelper, nullptr);
+ cmCAString newFileArg(&argHelper, nullptr);
+
+ cmCAString resultArg(&argHelper, "RESULT", &group);
+ cmCAEnabler copyOnErrorArg(&argHelper, "COPY_ON_ERROR", &group);
+ cmCAEnabler symbolicArg(&argHelper, "SYMBOLIC", &group);
+
+ linkArg.Follows(nullptr);
+ fileArg.Follows(&linkArg);
+ newFileArg.Follows(&fileArg);
+ group.Follows(&newFileArg);
+
+ std::vector<std::string> unconsumedArgs;
+ argHelper.Parse(&args, &unconsumedArgs);
+
+ if (!unconsumedArgs.empty()) {
+ this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
+ return false;
+ }
+
+ std::string fileName = fileArg.GetString();
+ std::string newFileName = newFileArg.GetString();
+
+ // Output variable for storing the result.
+ const std::string& resultVar = resultArg.GetString();
+
+ // The system error message generated in the operation.
+ std::string result;
+
+ // Check if the paths are distinct.
+ if (fileName == newFileName) {
+ result = "CREATE_LINK cannot use same file and newfile";
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ return true;
+ }
+ this->SetError(result);
+ return false;
+ }
+
+ // Hard link requires original file to exist.
+ if (!symbolicArg.IsEnabled() && !cmSystemTools::FileExists(fileName)) {
+ result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ return true;
+ }
+ this->SetError(result);
+ return false;
+ }
+
+ // Check if the new file already exists and remove it.
+ if ((cmSystemTools::FileExists(newFileName) ||
+ cmSystemTools::FileIsSymlink(newFileName)) &&
+ !cmSystemTools::RemoveFile(newFileName)) {
+ std::ostringstream e;
+ e << "Failed to create link '" << newFileName
+ << "' because existing path cannot be removed: "
+ << cmSystemTools::GetLastSystemError() << "\n";
+
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, e.str().c_str());
+ return true;
+ }
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Whether the operation completed successfully.
+ bool completed = false;
+
+ // Check if the command requires a symbolic link.
+ if (symbolicArg.IsEnabled()) {
+ completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result);
+ } else {
+ completed = cmSystemTools::CreateLink(fileName, newFileName, &result);
+ }
+
+ // Check if copy-on-error is enabled in the arguments.
+ if (!completed && copyOnErrorArg.IsEnabled()) {
+ completed =
+ cmSystemTools::cmCopyFile(fileName.c_str(), newFileName.c_str());
+ if (!completed) {
+ result = "Copy failed: " + cmSystemTools::GetLastSystemError();
+ }
+ }
+
+ // Check if the operation was successful.
+ if (completed) {
+ result = "0";
+ } else if (resultVar.empty()) {
+ // The operation failed and the result is not reported in a variable.
+ this->SetError(result);
+ return false;
+ }
+
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ }
+
+ return true;
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index fe05c98..12c5115 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -61,6 +61,7 @@ protected:
bool HandleLockCommand(std::vector<std::string> const& args);
bool HandleSizeCommand(std::vector<std::string> const& args);
bool HandleReadSymlinkCommand(std::vector<std::string> const& args);
+ bool HandleCreateLinkCommand(std::vector<std::string> const& args);
private:
void AddEvaluationFile(const std::string& inputName,
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 009f0e3..39051b9 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -178,13 +178,13 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
cmSystemTools::ExpandListArgument(rootPath, roots);
}
if (sysrootCompile) {
- roots.push_back(sysrootCompile);
+ roots.emplace_back(sysrootCompile);
}
if (sysrootLink) {
- roots.push_back(sysrootLink);
+ roots.emplace_back(sysrootLink);
}
if (sysroot) {
- roots.push_back(sysroot);
+ roots.emplace_back(sysroot);
}
for (std::string& r : roots) {
cmSystemTools::ConvertToUnixSlashes(r);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8dc7ca2..9ae1cb9 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -95,6 +95,7 @@ cmFindPackageCommand::cmFindPackageCommand()
this->UseLib32Paths = false;
this->UseLib64Paths = false;
this->UseLibx32Paths = false;
+ this->UseRealPath = false;
this->PolicyScope = true;
this->VersionMajor = 0;
this->VersionMinor = 0;
@@ -195,6 +196,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->NoSystemRegistry = true;
}
+ // Check whether we should resolve symlinks when finding packages
+ if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS")) {
+ this->UseRealPath = true;
+ }
+
// Check if Sorting should be enabled
if (const char* so =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
@@ -1502,6 +1508,10 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
fprintf(stderr, "Checking file [%s]\n", file.c_str());
}
if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
+ // Allow resolving symlinks when the config file is found through a link
+ if (this->UseRealPath) {
+ file = cmSystemTools::GetRealPath(file);
+ }
return true;
}
}
@@ -1848,7 +1858,7 @@ private:
}
for (std::string const& n : this->Names) {
if (cmsysString_strncasecmp(fname, n.c_str(), n.length()) == 0) {
- matches.push_back(fname);
+ matches.emplace_back(fname);
}
}
}
@@ -1907,7 +1917,7 @@ private:
for (std::string name : this->Names) {
name += this->Extension;
if (cmsysString_strcasecmp(fname, name.c_str()) == 0) {
- matches.push_back(fname);
+ matches.emplace_back(fname);
}
}
}
@@ -2070,16 +2080,16 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
common.push_back("lib/" + this->LibraryArchitecture);
}
if (this->UseLib32Paths) {
- common.push_back("lib32");
+ common.emplace_back("lib32");
}
if (this->UseLib64Paths) {
- common.push_back("lib64");
+ common.emplace_back("lib64");
}
if (this->UseLibx32Paths) {
- common.push_back("libx32");
+ common.emplace_back("libx32");
}
- common.push_back("lib");
- common.push_back("share");
+ common.emplace_back("lib");
+ common.emplace_back("share");
// PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
{
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 05bad49..83d8431 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -178,6 +178,7 @@ private:
bool UseLib32Paths;
bool UseLib64Paths;
bool UseLibx32Paths;
+ bool UseRealPath;
bool PolicyScope;
std::string LibraryArchitecture;
std::vector<std::string> Names;
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 3047167..e359def 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -164,7 +164,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
break;
}
sprintf(buffer, "%d", cc);
- range.push_back(buffer);
+ range.emplace_back(buffer);
if (cc == stop) {
break;
}
diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx
index 242915d..dd1e243 100644
--- a/Source/cmGeneratorExpressionLexer.cxx
+++ b/Source/cmGeneratorExpressionLexer.cxx
@@ -20,8 +20,8 @@ std::vector<cmGeneratorExpressionToken> cmGeneratorExpressionLexer::Tokenize(
std::vector<cmGeneratorExpressionToken> result;
if (input.find('$') == std::string::npos) {
- result.push_back(cmGeneratorExpressionToken(
- cmGeneratorExpressionToken::Text, input.c_str(), input.size()));
+ result.emplace_back(cmGeneratorExpressionToken::Text, input.c_str(),
+ input.size());
return result;
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index fe1b055..6a3f73d 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -692,6 +692,28 @@ static const struct CXXCompilerIdNode : public CompilerIdNode
}
} cxxCompilerIdNode;
+static const struct FortranCompilerIdNode : public CompilerIdNode
+{
+ FortranCompilerIdNode() {}
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<Fortran_COMPILER_ID> may only be used with binary targets. It may "
+ "not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
+ "Fortran");
+ }
+} fortranCompilerIdNode;
+
struct CompilerVersionNode : public cmGeneratorExpressionNode
{
CompilerVersionNode() {}
@@ -773,6 +795,28 @@ static const struct CxxCompilerVersionNode : public CompilerVersionNode
}
} cxxCompilerVersionNode;
+static const struct FortranCompilerVersionNode : public CompilerVersionNode
+{
+ FortranCompilerVersionNode() {}
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<Fortran_COMPILER_VERSION> may only be used with binary targets. "
+ "It may not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
+ "Fortran");
+ }
+} fortranCompilerVersionNode;
+
struct PlatformIdNode : public cmGeneratorExpressionNode
{
PlatformIdNode() {}
@@ -2024,6 +2068,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["NOT"] = &notNode;
nodeMap["C_COMPILER_ID"] = &cCompilerIdNode;
nodeMap["CXX_COMPILER_ID"] = &cxxCompilerIdNode;
+ nodeMap["Fortran_COMPILER_ID"] = &fortranCompilerIdNode;
nodeMap["VERSION_GREATER"] = &versionGreaterNode;
nodeMap["VERSION_GREATER_EQUAL"] = &versionGreaterEqNode;
nodeMap["VERSION_LESS"] = &versionLessNode;
@@ -2031,6 +2076,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["VERSION_EQUAL"] = &versionEqualNode;
nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode;
nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode;
+ nodeMap["Fortran_COMPILER_VERSION"] = &fortranCompilerVersionNode;
nodeMap["PLATFORM_ID"] = &platformIdNode;
nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode;
nodeMap["CONFIGURATION"] = &configurationNode;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6515dfa..eb3d4af 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -319,7 +319,7 @@ std::string cmGeneratorTarget::GetOutputName(
props.push_back(configUpper + "_OUTPUT_NAME");
}
// OUTPUT_NAME
- props.push_back("OUTPUT_NAME");
+ props.emplace_back("OUTPUT_NAME");
std::string outName;
for (std::string const& p : props) {
@@ -355,20 +355,22 @@ void cmGeneratorTarget::ClearSourcesCache()
this->Objects.clear();
}
-void cmGeneratorTarget::AddSourceCommon(const std::string& src)
+void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
cge->SetEvaluateForBuildsystem(true);
- this->SourceEntries.push_back(new TargetPropertyEntry(std::move(cge)));
+ this->SourceEntries.insert(before ? this->SourceEntries.begin()
+ : this->SourceEntries.end(),
+ new TargetPropertyEntry(std::move(cge)));
this->ClearSourcesCache();
}
-void cmGeneratorTarget::AddSource(const std::string& src)
+void cmGeneratorTarget::AddSource(const std::string& src, bool before)
{
- this->Target->AddSource(src);
- this->AddSourceCommon(src);
+ this->Target->AddSource(src, before);
+ this->AddSourceCommon(src, before);
}
void cmGeneratorTarget::AddTracedSources(std::vector<std::string> const& srcs)
@@ -387,12 +389,10 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
cmGeneratorExpression ge(lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
cge->SetEvaluateForBuildsystem(true);
- // Insert before begin/end
- std::vector<TargetPropertyEntry*>::iterator pos = before
- ? this->IncludeDirectoriesEntries.begin()
- : this->IncludeDirectoriesEntries.end();
this->IncludeDirectoriesEntries.insert(
- pos, new TargetPropertyEntry(std::move(cge)));
+ before ? this->IncludeDirectoriesEntries.begin()
+ : this->IncludeDirectoriesEntries.end(),
+ new TargetPropertyEntry(std::move(cge)));
}
std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
@@ -988,7 +988,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
item.back() == '>') {
continue;
}
- files.push_back(item);
+ files.emplace_back(item);
}
}
return files;
@@ -3260,7 +3260,7 @@ void processLinkDirectories(
// in case projects set the LINK_DIRECTORIES property directly.
cmSystemTools::ConvertToUnixSlashes(entryDirectory);
if (uniqueDirectories.insert(entryDirectory).second) {
- directories.push_back(entryDirectory);
+ directories.emplace_back(entryDirectory);
if (debugDirectories) {
usedDirectories += " * " + entryDirectory + "\n";
}
@@ -3838,7 +3838,7 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
}
// PDB_NAME
- props.push_back("PDB_NAME");
+ props.emplace_back("PDB_NAME");
for (std::string const& p : props) {
if (const char* outName = this->GetProperty(p)) {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index cfd1df0..d9221f0 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -536,7 +536,7 @@ public:
*/
void ClearSourcesCache();
- void AddSource(const std::string& src);
+ void AddSource(const std::string& src, bool before = false);
void AddTracedSources(std::vector<std::string> const& srcs);
/**
@@ -694,7 +694,7 @@ public:
const char* GetSourcesProperty() const;
private:
- void AddSourceCommon(const std::string& src);
+ void AddSourceCommon(const std::string& src, bool before = false);
std::string CreateFortranModuleDirectory(
std::string const& working_dir) const;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a5c90bf..2d36315 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -356,7 +356,7 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
std::string setMakeProgram =
mf->GetModulesFile(this->FindMakeProgramFile.c_str());
if (!setMakeProgram.empty()) {
- mf->ReadListFile(setMakeProgram.c_str());
+ mf->ReadListFile(setMakeProgram);
}
}
if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
@@ -523,7 +523,7 @@ void cmGlobalGenerator::EnableLanguage(
if (readCMakeSystem) {
fpath += "/CMakeSystem.cmake";
if (cmSystemTools::FileExists(fpath)) {
- mf->ReadListFile(fpath.c_str());
+ mf->ReadListFile(fpath);
}
}
// Load the CMakeDetermineSystem.cmake file and find out
@@ -552,12 +552,12 @@ void cmGlobalGenerator::EnableLanguage(
#endif
// Read the DetermineSystem file
std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
- mf->ReadListFile(systemFile.c_str());
+ mf->ReadListFile(systemFile);
// load the CMakeSystem.cmake from the binary directory
// this file is configured by the CMakeDetermineSystem.cmake file
fpath = rootBin;
fpath += "/CMakeSystem.cmake";
- mf->ReadListFile(fpath.c_str());
+ mf->ReadListFile(fpath);
}
if (readCMakeSystem) {
@@ -604,7 +604,7 @@ void cmGlobalGenerator::EnableLanguage(
// **** Load the system specific initialization if not yet loaded
if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INITIALIZE_LOADED")) {
fpath = mf->GetModulesFile("CMakeSystemSpecificInitialize.cmake");
- if (!mf->ReadListFile(fpath.c_str())) {
+ if (!mf->ReadListFile(fpath)) {
cmSystemTools::Error("Could not find cmake module file: "
"CMakeSystemSpecificInitialize.cmake");
}
@@ -636,7 +636,7 @@ void cmGlobalGenerator::EnableLanguage(
// version of CMake then try to load the configured file first
// to avoid duplicate compiler tests.
if (cmSystemTools::FileExists(fpath)) {
- if (!mf->ReadListFile(fpath.c_str())) {
+ if (!mf->ReadListFile(fpath)) {
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
}
@@ -663,7 +663,7 @@ void cmGlobalGenerator::EnableLanguage(
determineCompiler += "Compiler.cmake";
std::string determineFile =
mf->GetModulesFile(determineCompiler.c_str());
- if (!mf->ReadListFile(determineFile.c_str())) {
+ if (!mf->ReadListFile(determineFile)) {
cmSystemTools::Error("Could not find cmake module file: ",
determineCompiler.c_str());
}
@@ -697,7 +697,7 @@ void cmGlobalGenerator::EnableLanguage(
fpath += "/CMake";
fpath += lang;
fpath += "Compiler.cmake";
- if (!mf->ReadListFile(fpath.c_str())) {
+ if (!mf->ReadListFile(fpath)) {
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
}
@@ -714,7 +714,7 @@ void cmGlobalGenerator::EnableLanguage(
// **** Load the system specific information if not yet loaded
if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED")) {
fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
- if (!mf->ReadListFile(fpath.c_str())) {
+ if (!mf->ReadListFile(fpath)) {
cmSystemTools::Error("Could not find cmake module file: "
"CMakeSystemSpecificInformation.cmake");
}
@@ -794,7 +794,7 @@ void cmGlobalGenerator::EnableLanguage(
if (informationFile.empty()) {
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
- } else if (!mf->ReadListFile(informationFile.c_str())) {
+ } else if (!mf->ReadListFile(informationFile)) {
cmSystemTools::Error("Could not process cmake module file: ",
informationFile.c_str());
}
@@ -815,7 +815,7 @@ void cmGlobalGenerator::EnableLanguage(
testLang += lang;
testLang += "Compiler.cmake";
std::string ifpath = mf->GetModulesFile(testLang.c_str());
- if (!mf->ReadListFile(ifpath.c_str())) {
+ if (!mf->ReadListFile(ifpath)) {
cmSystemTools::Error("Could not find cmake module file: ",
testLang.c_str());
}
@@ -853,7 +853,7 @@ void cmGlobalGenerator::EnableLanguage(
projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME");
projectCompatibility += "Compatibility.cmake";
if (cmSystemTools::FileExists(projectCompatibility)) {
- mf->ReadListFile(projectCompatibility.c_str());
+ mf->ReadListFile(projectCompatibility);
}
// Inform any extra generator of the new language.
if (this->ExtraGenerator) {
@@ -1762,7 +1762,7 @@ void cmGlobalGenerator::GenerateBuildCommand(
bool /*unused*/, int /*unused*/, bool /*unused*/,
std::vector<std::string> const& /*unused*/)
{
- makeCommand.push_back(
+ makeCommand.emplace_back(
"cmGlobalGenerator::GenerateBuildCommand not implemented");
}
@@ -2314,12 +2314,12 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
singleLine.push_back("./CPackConfig.cmake");
gti.CommandLines.push_back(std::move(singleLine));
if (this->GetPreinstallTargetName()) {
- gti.Depends.push_back(this->GetPreinstallTargetName());
+ gti.Depends.emplace_back(this->GetPreinstallTargetName());
} else {
const char* noPackageAll =
mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
if (!noPackageAll || cmSystemTools::IsOff(noPackageAll)) {
- gti.Depends.push_back(this->GetAllTargetName());
+ gti.Depends.emplace_back(this->GetAllTargetName());
}
}
targets.push_back(std::move(gti));
@@ -2484,12 +2484,12 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
gti.UsesTerminal = true;
cmCustomCommandLine singleLine;
if (this->GetPreinstallTargetName()) {
- gti.Depends.push_back(this->GetPreinstallTargetName());
+ gti.Depends.emplace_back(this->GetPreinstallTargetName());
} else {
const char* noall =
mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
if (!noall || cmSystemTools::IsOff(noall)) {
- gti.Depends.push_back(this->GetAllTargetName());
+ gti.Depends.emplace_back(this->GetAllTargetName());
}
}
if (mf->GetDefinition("CMake_BINARY_DIR") &&
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index 4e3e770..d4f772b 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -30,13 +30,20 @@ public:
virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
/** Get the names of the current registered generators */
- virtual void GetGenerators(std::vector<std::string>& names) const = 0;
+ virtual std::vector<std::string> GetGeneratorNames() const = 0;
+ virtual std::vector<std::string> GetGeneratorNamesWithPlatform() const = 0;
/** Determine whether or not this generator supports toolsets */
virtual bool SupportsToolset() const = 0;
/** Determine whether or not this generator supports platforms */
virtual bool SupportsPlatform() const = 0;
+
+ /** Get the list of supported platforms name for this generator */
+ virtual std::vector<std::string> GetKnownPlatforms() const = 0;
+
+ /** If the generator suports platforms, get its default. */
+ virtual std::string GetDefaultPlatformName() const = 0;
};
template <class T>
@@ -60,9 +67,15 @@ public:
}
/** Get the names of the current registered generators */
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(T::GetActualName());
+ return names;
+ }
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ return std::vector<std::string>();
}
/** Determine whether or not this generator supports toolsets */
@@ -70,6 +83,15 @@ public:
/** Determine whether or not this generator supports platforms */
bool SupportsPlatform() const override { return T::SupportsPlatform(); }
+
+ /** Get the list of supported platforms name for this generator */
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ // default is no platform supported
+ return std::vector<std::string>();
+ }
+
+ std::string GetDefaultPlatformName() const override { return std::string(); }
};
#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index e7b0981..23dbd76 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -550,7 +550,7 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
this->NinjaCommand = ninjaCommand;
std::vector<std::string> command;
command.push_back(this->NinjaCommand);
- command.push_back("--version");
+ command.emplace_back("--version");
std::string version;
std::string error;
if (!cmSystemTools::RunSingleCommand(command, &version, &error, nullptr,
@@ -681,12 +681,12 @@ void cmGlobalNinjaGenerator::GenerateBuildCommand(
makeCommand.push_back(this->SelectMakeProgram(makeProgram));
if (verbose) {
- makeCommand.push_back("-v");
+ makeCommand.emplace_back("-v");
}
if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
(jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
- makeCommand.push_back("-j");
+ makeCommand.emplace_back("-j");
makeCommand.push_back(std::to_string(jobs));
}
@@ -694,8 +694,8 @@ void cmGlobalNinjaGenerator::GenerateBuildCommand(
makeOptions.end());
if (!targetName.empty()) {
if (targetName == "clean") {
- makeCommand.push_back("-t");
- makeCommand.push_back("clean");
+ makeCommand.emplace_back("-t");
+ makeCommand.emplace_back("clean");
} else {
makeCommand.push_back(targetName);
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index ceee500..52bb046 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -216,7 +216,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
// Just depend on the all target to drive the build.
std::vector<std::string> depends;
std::vector<std::string> no_commands;
- depends.push_back("all");
+ depends.emplace_back("all");
// Write the rule.
lg->WriteMakeRule(makefileStream,
@@ -513,7 +513,7 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
makeCommand.push_back(this->SelectMakeProgram(makeProgram));
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
- makeCommand.push_back("-j");
+ makeCommand.emplace_back("-j");
if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
makeCommand.push_back(std::to_string(jobs));
}
@@ -542,7 +542,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
if (regenerate) {
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
// write the target convenience rules
@@ -577,7 +577,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
commands.push_back(lg->GetRecursiveMakeCall(tmp.c_str(), name));
depends.clear();
if (regenerate) {
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
lg->WriteMakeRule(ruleFileStream, "Build rule for target.", name,
depends, commands, true);
@@ -631,7 +631,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
if (regenerate) {
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
// for each target Generate the rule files for each target.
@@ -740,7 +740,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
depends.clear();
if (regenerate) {
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
localName = lg->GetRelativeTargetDirectory(gtarget);
localName += "/rule";
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 79757a8..dbe582b 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -74,15 +74,34 @@ public:
"Optional [arch] can be \"Win64\" or \"IA64\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs10generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs10generatorName + std::string(" IA64"));
names.push_back(vs10generatorName + std::string(" Win64"));
+ return names;
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("Itanium");
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 36eb492..4eb78ba 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -69,9 +69,16 @@ public:
"Optional [arch] can be \"Win64\" or \"ARM\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs11generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs11generatorName + std::string(" ARM"));
names.push_back(vs11generatorName + std::string(" Win64"));
@@ -80,10 +87,30 @@ public:
for (std::string const& i : installedSDKs) {
names.push_back(std::string(vs11generatorName) + " " + i);
}
+
+ return names;
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("ARM");
+
+ std::set<std::string> installedSDKs =
+ cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
+ for (std::string const& i : installedSDKs) {
+ platforms.emplace_back(i);
+ }
+
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 61034a7..8b50684 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -58,15 +58,34 @@ public:
"Optional [arch] can be \"Win64\" or \"ARM\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs12generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs12generatorName + std::string(" ARM"));
names.push_back(vs12generatorName + std::string(" Win64"));
+ return names;
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("ARM");
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 5ea5e67..a0a9558 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -58,15 +58,34 @@ public:
"Optional [arch] can be \"Win64\" or \"ARM\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs14generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs14generatorName + std::string(" ARM"));
names.push_back(vs14generatorName + std::string(" Win64"));
+ return names;
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("ARM");
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 445b40c..6e61d26 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -59,9 +59,16 @@ public:
"Optional [arch] can be \"Win64\" or \"IA64\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs9generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs9generatorName + std::string(" Win64"));
names.push_back(vs9generatorName + std::string(" IA64"));
cmVisualStudioWCEPlatformParser parser;
@@ -71,10 +78,29 @@ public:
for (std::string const& i : availablePlatforms) {
names.push_back("Visual Studio 9 2008 " + i);
}
+ return names;
}
bool SupportsToolset() const override { return false; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("Itanium");
+ cmVisualStudioWCEPlatformParser parser;
+ parser.ParseVersion("9.0");
+ const std::vector<std::string>& availablePlatforms =
+ parser.GetAvailablePlatforms();
+ for (std::string const& i : availablePlatforms) {
+ platforms.emplace_back(i);
+ }
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 99f9503..31f585c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -19,6 +19,20 @@
# include "cmsys/SystemInformation.hxx"
#endif
+static std::string VSHostPlatformName()
+{
+#ifdef HOST_PLATFORM_NAME
+ return HOST_PLATFORM_NAME;
+#else
+ cmsys::SystemInformation info;
+ if (info.Is64Bits()) {
+ return "x64";
+ } else {
+ return "Win32";
+ }
+#endif
+}
+
static unsigned int VSVersionToMajor(
cmGlobalVisualStudioGenerator::VSVersion v)
{
@@ -118,15 +132,35 @@ public:
"Optional [arch] can be \"Win64\" or \"ARM\".";
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs15generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ std::vector<std::string> names;
names.push_back(vs15generatorName + std::string(" ARM"));
names.push_back(vs15generatorName + std::string(" Win64"));
+ return names;
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("ARM");
+ platforms.emplace_back("ARM64");
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override { return "Win32"; }
};
cmGlobalGeneratorFactory*
@@ -178,13 +212,35 @@ public:
"Use -A option to specify architecture.";
}
- virtual void GetGenerators(std::vector<std::string>& names) const
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(vs16generatorName);
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ return std::vector<std::string>();
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ std::vector<std::string> platforms;
+ platforms.emplace_back("x64");
+ platforms.emplace_back("Win32");
+ platforms.emplace_back("ARM");
+ platforms.emplace_back("ARM64");
+ return platforms;
+ }
+
+ std::string GetDefaultPlatformName() const override
+ {
+ return VSHostPlatformName();
+ }
};
cmGlobalGeneratorFactory*
@@ -206,16 +262,7 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
if (this->Version >= cmGlobalVisualStudioGenerator::VS16) {
-#ifdef HOST_PLATFORM_NAME
- this->DefaultPlatformName = HOST_PLATFORM_NAME;
-#else
- cmsys::SystemInformation info;
- if (info.Is64Bits()) {
- this->DefaultPlatformName = "x64";
- } else {
- this->DefaultPlatformName = "Win32";
- }
-#endif
+ this->DefaultPlatformName = VSHostPlatformName();
}
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 6618351..79d77e7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -133,13 +133,27 @@ public:
cmGlobalXCodeGenerator::GetDocumentation(entry);
}
- void GetGenerators(std::vector<std::string>& names) const override
+ std::vector<std::string> GetGeneratorNames() const override
{
+ std::vector<std::string> names;
names.push_back(cmGlobalXCodeGenerator::GetActualName());
+ return names;
+ }
+
+ std::vector<std::string> GetGeneratorNamesWithPlatform() const override
+ {
+ return std::vector<std::string>();
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return false; }
+
+ std::vector<std::string> GetKnownPlatforms() const override
+ {
+ return std::vector<std::string>();
+ }
+
+ std::string GetDefaultPlatformName() const override { return std::string(); }
};
cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(
@@ -177,12 +191,14 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
std::string versionFile;
{
std::string out;
- std::string::size_type pos = 0;
- if (cmSystemTools::RunSingleCommand("xcode-select --print-path", &out,
- nullptr, nullptr, nullptr,
- cmSystemTools::OUTPUT_NONE) &&
- (pos = out.find(".app/"), pos != std::string::npos)) {
- versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
+ bool commandResult = cmSystemTools::RunSingleCommand(
+ "xcode-select --print-path", &out, nullptr, nullptr, nullptr,
+ cmSystemTools::OUTPUT_NONE);
+ if (commandResult) {
+ std::string::size_type pos = out.find(".app/");
+ if (pos != std::string::npos) {
+ versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
+ }
}
}
if (!versionFile.empty() && cmSystemTools::FileExists(versionFile.c_str())) {
@@ -329,14 +345,14 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand(
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
{
// now build the test
- makeCommand.push_back(
+ makeCommand.emplace_back(
this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand()));
- makeCommand.push_back("-project");
+ makeCommand.emplace_back("-project");
std::string projectArg = projectName;
projectArg += ".xcode";
projectArg += "proj";
- makeCommand.push_back(projectArg);
+ makeCommand.emplace_back(projectArg);
bool clean = false;
std::string realTarget = targetName;
@@ -345,23 +361,23 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand(
realTarget = "ALL_BUILD";
}
if (clean) {
- makeCommand.push_back("clean");
+ makeCommand.emplace_back("clean");
} else {
- makeCommand.push_back("build");
+ makeCommand.emplace_back("build");
}
- makeCommand.push_back("-target");
+ makeCommand.emplace_back("-target");
if (!realTarget.empty()) {
- makeCommand.push_back(realTarget);
+ makeCommand.emplace_back(realTarget);
} else {
- makeCommand.push_back("ALL_BUILD");
+ makeCommand.emplace_back("ALL_BUILD");
}
- makeCommand.push_back("-configuration");
- makeCommand.push_back(!config.empty() ? config : "Debug");
+ makeCommand.emplace_back("-configuration");
+ makeCommand.emplace_back(!config.empty() ? config : "Debug");
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
- makeCommand.push_back("-jobs");
+ makeCommand.emplace_back("-jobs");
if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
- makeCommand.push_back(std::to_string(jobs));
+ makeCommand.emplace_back(std::to_string(jobs));
}
}
@@ -1051,7 +1067,7 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
this->CurrentConfigurationTypes.clear();
this->CurrentMakefile->GetConfigurations(this->CurrentConfigurationTypes);
if (this->CurrentConfigurationTypes.empty()) {
- this->CurrentConfigurationTypes.push_back("");
+ this->CurrentConfigurationTypes.emplace_back();
}
}
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 594c310..a67d09e 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -120,8 +120,7 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
- bool readit =
- this->Makefile->ReadDependentFile(listFile.c_str(), noPolicyScope);
+ bool readit = this->Makefile->ReadDependentFile(listFile, noPolicyScope);
// add the location of the included file if a result variable was given
if (!resultVarName.empty()) {
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index bb56714..135fd25 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -49,7 +49,7 @@ std::vector<std::string> getConfigurations(const cmake* cm)
makefiles[0]->GetConfigurations(configurations);
if (configurations.empty()) {
- configurations.push_back("");
+ configurations.emplace_back();
}
return configurations;
}
@@ -292,10 +292,10 @@ static Json::Value DumpSourceFilesList(
lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
for (const auto& include : includes) {
- fileData.IncludePathList.push_back(
- std::make_pair(include,
- target->IsSystemIncludeDirectory(
- include, config, fileData.Language)));
+ fileData.IncludePathList.emplace_back(
+ include,
+ target->IsSystemIncludeDirectory(include, config,
+ fileData.Language));
}
}
@@ -580,8 +580,8 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
std::vector<std::string> includePathList;
lg->GetIncludeDirectories(includePathList, target, lang, config, true);
for (std::string const& i : includePathList) {
- ld.IncludePathList.push_back(
- std::make_pair(i, target->IsSystemIncludeDirectory(i, config, lang)));
+ ld.IncludePathList.emplace_back(
+ i, target->IsSystemIncludeDirectory(i, config, lang));
}
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 54f1c7f..23afbd0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1692,19 +1692,19 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
static std::map<std::string, std::vector<std::string>> langStdMap;
if (langStdMap.empty()) {
// Maintain sorted order, most recent first.
- langStdMap["CXX"].push_back("20");
- langStdMap["CXX"].push_back("17");
- langStdMap["CXX"].push_back("14");
- langStdMap["CXX"].push_back("11");
- langStdMap["CXX"].push_back("98");
-
- langStdMap["C"].push_back("11");
- langStdMap["C"].push_back("99");
- langStdMap["C"].push_back("90");
-
- langStdMap["CUDA"].push_back("14");
- langStdMap["CUDA"].push_back("11");
- langStdMap["CUDA"].push_back("98");
+ langStdMap["CXX"].emplace_back("20");
+ langStdMap["CXX"].emplace_back("17");
+ langStdMap["CXX"].emplace_back("14");
+ langStdMap["CXX"].emplace_back("11");
+ langStdMap["CXX"].emplace_back("98");
+
+ langStdMap["C"].emplace_back("11");
+ langStdMap["C"].emplace_back("99");
+ langStdMap["C"].emplace_back("90");
+
+ langStdMap["CUDA"].emplace_back("14");
+ langStdMap["CUDA"].emplace_back("11");
+ langStdMap["CUDA"].emplace_back("98");
}
std::string standard(standardProp);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 707a1b5..5b9d108 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -318,7 +318,7 @@ void cmLocalUnixMakefileGenerator3::WriteObjectConvenienceRule(
// Add a rule to drive the rule below.
std::vector<std::string> depends;
- depends.push_back(output);
+ depends.emplace_back(output);
std::vector<std::string> no_commands;
this->WriteMakeRule(ruleFileStream, nullptr, outNoExt, depends,
no_commands, true, true);
@@ -685,7 +685,7 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
}
// Add a fake suffix to keep HP happy. Must be max 32 chars for SGI make.
std::vector<std::string> depends;
- depends.push_back(".hpux_make_needs_suffix_list");
+ depends.emplace_back(".hpux_make_needs_suffix_list");
this->WriteMakeRule(makefileStream, nullptr, ".SUFFIXES", depends,
no_commands, false);
if (this->IsWatcomWMake()) {
@@ -852,7 +852,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepend(
const char* nodep =
this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
if (!nodep || cmSystemTools::IsOff(nodep)) {
- depends.push_back(ruleFileName);
+ depends.emplace_back(ruleFileName);
}
}
@@ -1286,7 +1286,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
std::ostringstream msg;
msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
<< internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
needRescanDependInfo = true;
}
@@ -1307,7 +1307,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
std::ostringstream msg;
msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \""
<< internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
needRescanDirInfo = true;
}
@@ -1333,8 +1333,8 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
// dependency vector. This means that in the normal case, when only
// few or one file have been edited, then also only this one file is
// actually scanned again, instead of all files for this target.
- needRescanDependencies = !checker.Check(
- dependFile.c_str(), internalDependFile.c_str(), validDependencies);
+ needRescanDependencies =
+ !checker.Check(dependFile, internalDependFile, validDependencies);
}
if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
@@ -1347,7 +1347,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, color);
- return this->ScanDependencies(dir.c_str(), validDependencies);
+ return this->ScanDependencies(dir, validDependencies);
}
// The dependencies are already up-to-date.
@@ -1355,7 +1355,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
}
bool cmLocalUnixMakefileGenerator3::ScanDependencies(
- const char* targetDir,
+ const std::string& targetDir,
std::map<std::string, cmDepends::DependencyVector>& validDeps)
{
// Read the directory information file.
@@ -1364,8 +1364,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
std::string dirInfoFile = this->GetCurrentBinaryDirectory();
dirInfoFile += cmake::GetCMakeFilesDirectory();
dirInfoFile += "/CMakeDirectoryInformation.cmake";
- if (mf->ReadListFile(dirInfoFile.c_str()) &&
- !cmSystemTools::GetErrorOccuredFlag()) {
+ if (mf->ReadListFile(dirInfoFile) && !cmSystemTools::GetErrorOccuredFlag()) {
haveDirectoryInfo = true;
}
@@ -1393,12 +1392,9 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
cmSystemTools::Error("Directory Information file not found");
}
- // create the file stream for the depends file
- std::string dir = targetDir;
-
// Open the make depends file. This should be copy-if-different
// because the make tool may try to reload it needlessly otherwise.
- std::string ruleFileNameFull = dir;
+ std::string ruleFileNameFull = targetDir;
ruleFileNameFull += "/depend.make";
cmGeneratedFileStream ruleFileStream(
ruleFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
@@ -1410,7 +1406,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
// Open the cmake dependency tracking file. This should not be
// copy-if-different because dependencies are re-scanned when it is
// older than the DependInfo.cmake.
- std::string internalRuleFileNameFull = dir;
+ std::string internalRuleFileNameFull = targetDir;
internalRuleFileNameFull += "/depend.internal";
cmGeneratedFileStream internalRuleFileStream(
internalRuleFileNameFull, false,
@@ -1451,7 +1447,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
scanner->SetFileComparison(
this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
scanner->SetLanguage(lang);
- scanner->SetTargetDirectory(dir.c_str());
+ scanner->SetTargetDirectory(targetDir);
scanner->Write(ruleFileStream, internalRuleFileStream);
// free the scanner for this language
@@ -1489,7 +1485,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
msg << "Deleting primary custom command output \"" << dependee
<< "\" because another output \"" << depender
<< "\" does not exist." << std::endl;
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
cmSystemTools::RemoveFile(dependee);
}
@@ -1507,7 +1503,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
// Just depend on the all target to drive the build.
std::vector<std::string> depends;
std::vector<std::string> no_commands;
- depends.push_back("all");
+ depends.emplace_back("all");
// Write the rule.
this->WriteMakeRule(ruleFileStream,
@@ -1571,7 +1567,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
(targetName == "install/strip")) {
// Provide a fast install target that does not depend on all
// but has the same command.
- depends.push_back("preinstall/fast");
+ depends.emplace_back("preinstall/fast");
} else {
// Just forward to the real target so at least it will work.
depends.push_back(targetName);
@@ -1593,7 +1589,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
bool regenerate =
!this->GlobalGenerator->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
if (regenerate) {
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
std::string progressDir = this->GetBinaryDirectory();
@@ -1643,7 +1639,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
depends, commands, true);
commands.clear();
depends.clear();
- depends.push_back("clean");
+ depends.emplace_back("clean");
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean/fast",
depends, commands, true);
@@ -1656,10 +1652,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
if (!noall || cmSystemTools::IsOff(noall)) {
// Drive the build before installing.
- depends.push_back("all");
+ depends.emplace_back("all");
} else if (regenerate) {
// At least make sure the build system is up to date.
- depends.push_back("cmake_check_build_system");
+ depends.emplace_back("cmake_check_build_system");
}
commands.push_back(
this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget));
@@ -1720,7 +1716,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
// Clear the implicit dependency makefile.
std::string dependFile = dir + "/depend.make";
- clearer.Clear(dependFile.c_str());
+ clearer.Clear(dependFile);
// Remove the internal dependency check file to force
// regeneration.
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index ee6b37b..c0d0e13 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -245,7 +245,7 @@ protected:
// Helper methods for dependency updates.
bool ScanDependencies(
- const char* targetDir,
+ const std::string& targetDir,
std::map<std::string, cmDepends::DependencyVector>& validDeps);
void CheckMultipleOutputs(bool verbose);
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 23d93a3..411c0c3 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -94,7 +94,7 @@ bool cmMacroHelperCommand::InvokeInitialPass(
char argvName[60];
for (unsigned int j = 0; j < expandedArgs.size(); ++j) {
sprintf(argvName, "${ARGV%u}", j);
- argVs.push_back(argvName);
+ argVs.emplace_back(argvName);
}
// Invoke all the functions that were collected in the block.
cmListFileFunction newLFF;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3ff576e..9589b7f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -533,7 +533,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
}
}
-bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
+bool cmMakefile::ReadDependentFile(const std::string& filename,
+ bool noPolicyScope)
{
this->AddDefinition("CMAKE_PARENT_LIST_FILE",
this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
@@ -586,7 +587,7 @@ private:
bool ReportError;
};
-bool cmMakefile::ReadListFile(const char* filename)
+bool cmMakefile::ReadListFile(const std::string& filename)
{
std::string filenametoread = cmSystemTools::CollapseFullPath(
filename, this->GetCurrentSourceDirectory());
@@ -2099,7 +2100,7 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
if (i == -1) {
// group does not exist nor belong to any existing group
// add its first component
- this->SourceGroups.push_back(cmSourceGroup(name[0], regex));
+ this->SourceGroups.emplace_back(name[0], regex);
sg = this->GetSourceGroup(currentName);
i = 0; // last component found
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index ec36972..abe2cd1 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -86,11 +86,10 @@ public:
cmDirectoryId GetDirectoryId() const;
- bool ReadListFile(const char* filename);
+ bool ReadListFile(const std::string& filename);
- bool ReadDependentFile(const char* filename, bool noPolicyScope = true);
-
- bool ProcessBuildsystemFile(const char* filename);
+ bool ReadDependentFile(const std::string& filename,
+ bool noPolicyScope = true);
/**
* Add a function blocker to this makefile
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index d1dcd81..1207646 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -816,7 +816,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
lang_has_assembly && this->LocalGenerator->GetCreateAssemblySourceRules();
if (do_preprocess_rules || do_assembly_rules) {
std::vector<std::string> force_depends;
- force_depends.push_back("cmake_force");
+ force_depends.emplace_back("cmake_force");
std::string::size_type dot_pos = relativeObj.rfind('.');
std::string relativeObjBase = relativeObj.substr(0, dot_pos);
dot_pos = obj.rfind('.');
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index b62da66..8f6a23a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -377,7 +377,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
- linkCmds.push_back("$POST_BUILD");
+ linkCmds.emplace_back("$POST_BUILD");
std::string linkCmd =
this->GetLocalGenerator()->BuildCommandLine(linkCmds);
@@ -405,7 +405,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::vector<std::string> commandLines;
commandLines.push_back(cmakeCommand +
" -E cmake_symlink_executable $in $out");
- commandLines.push_back("$POST_BUILD");
+ commandLines.emplace_back("$POST_BUILD");
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_EXECUTABLE",
@@ -423,7 +423,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::vector<std::string> commandLines;
commandLines.push_back(cmakeCommand +
" -E cmake_symlink_library $in $SONAME $out");
- commandLines.push_back("$POST_BUILD");
+ commandLines.emplace_back("$POST_BUILD");
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_LIBRARY",
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5013be5..c959a04 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -433,6 +433,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
vars.ObjectFileDir = "$OBJECT_FILE_DIR";
if (lang == "Swift") {
vars.SwiftAuxiliarySources = "$SWIFT_AUXILIARY_SOURCES";
+ vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
}
// For some cases we do an explicit preprocessor invocation.
@@ -904,9 +905,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
vars["DEFINES"] = this->ComputeDefines(source, language);
vars["INCLUDES"] = this->ComputeIncludes(source, language);
- // The swift compiler needs all the sources besides the one being compiled in
- // order to do the type checking. List all these "auxiliary" sources.
if (language == "Swift") {
+ // The swift compiler needs all the sources besides the one being compiled
+ // in order to do the type checking. List all these "auxiliary" sources.
std::string aux_sources;
cmGeneratorTarget::KindedSources const& sources =
this->GeneratorTarget->GetKindedSources(this->GetConfigName());
@@ -917,6 +918,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
aux_sources += " " + this->GetSourceFilePath(src.Source.Value);
}
vars["SWIFT_AUXILIARY_SOURCES"] = aux_sources;
+
+ vars["SWIFT_MODULE_NAME"] = this->GeneratorTarget->GetName();
}
if (!this->NeedDepTypeMSVC(language)) {
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index a2bf841..796974c 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -151,7 +151,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
cmSystemTools::SetFatalErrorOccured();
return true;
}
- list.push_back(arg);
+ list.emplace_back(arg);
}
}
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index facde5d..a2bc16f 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -16,7 +16,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
cmProcessOutput processOutput(encoding);
std::string strdata;
while ((out || err) &&
- (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
+ (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
if (out && p == cmsysProcess_Pipe_STDOUT) {
processOutput.DecodeText(data, length, strdata, 1);
if (!out->Process(strdata.c_str(), int(strdata.size()))) {
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 14e92c6..2fe9fe8 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -198,7 +198,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
if (haveLanguages && languages.empty()) {
- languages.push_back("NONE");
+ languages.emplace_back("NONE");
}
cmPolicies::PolicyStatus cmp0048 =
@@ -264,22 +264,22 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
} else if (cmp0048 != cmPolicies::OLD) {
// Set project VERSION variables to empty
std::vector<std::string> vv;
- vv.push_back("PROJECT_VERSION");
- vv.push_back("PROJECT_VERSION_MAJOR");
- vv.push_back("PROJECT_VERSION_MINOR");
- vv.push_back("PROJECT_VERSION_PATCH");
- vv.push_back("PROJECT_VERSION_TWEAK");
+ vv.emplace_back("PROJECT_VERSION");
+ vv.emplace_back("PROJECT_VERSION_MAJOR");
+ vv.emplace_back("PROJECT_VERSION_MINOR");
+ vv.emplace_back("PROJECT_VERSION_PATCH");
+ vv.emplace_back("PROJECT_VERSION_TWEAK");
vv.push_back(projectName + "_VERSION");
vv.push_back(projectName + "_VERSION_MAJOR");
vv.push_back(projectName + "_VERSION_MINOR");
vv.push_back(projectName + "_VERSION_PATCH");
vv.push_back(projectName + "_VERSION_TWEAK");
if (this->Makefile->IsRootMakefile()) {
- vv.push_back("CMAKE_PROJECT_VERSION");
- vv.push_back("CMAKE_PROJECT_VERSION_MAJOR");
- vv.push_back("CMAKE_PROJECT_VERSION_MINOR");
- vv.push_back("CMAKE_PROJECT_VERSION_PATCH");
- vv.push_back("CMAKE_PROJECT_VERSION_TWEAK");
+ vv.emplace_back("CMAKE_PROJECT_VERSION");
+ vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR");
+ vv.emplace_back("CMAKE_PROJECT_VERSION_MINOR");
+ vv.emplace_back("CMAKE_PROJECT_VERSION_PATCH");
+ vv.emplace_back("CMAKE_PROJECT_VERSION_TWEAK");
}
std::string vw;
for (std::string const& i : vv) {
@@ -315,8 +315,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
if (languages.empty()) {
// if no language is specified do c and c++
- languages.push_back("C");
- languages.push_back("CXX");
+ languages.emplace_back("C");
+ languages.emplace_back("CXX");
}
this->Makefile->EnableLanguage(languages, false);
std::string extraInclude = "CMAKE_PROJECT_" + projectName + "_INCLUDE";
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 9fa8a89..47f7d73 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -963,7 +963,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Files provided by the autogen target
std::vector<std::string> autogenProvides;
if (this->Moc.Enabled) {
- this->AddGeneratedSource(this->Moc.MocsCompilation, GeneratorT::MOC);
+ this->AddGeneratedSource(this->Moc.MocsCompilation, GeneratorT::MOC, true);
autogenProvides.push_back(this->Moc.MocsCompilation);
}
@@ -1356,7 +1356,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
}
void cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
- GeneratorT genType)
+ GeneratorT genType,
+ bool prepend)
{
// Register source file in makefile
cmMakefile* makefile = this->Target->Target->GetMakefile();
@@ -1370,7 +1371,7 @@ void cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
AddToSourceGroup(makefile, filename, genType);
// Add source file to target
- this->Target->AddSource(filename);
+ this->Target->AddSource(filename, prepend);
}
static unsigned int CharPtrToInt(const char* const input)
@@ -1482,7 +1483,7 @@ std::pair<bool, std::string> GetQtExecutable(
if (cmSystemTools::FileExists(result, true)) {
std::vector<std::string> command;
command.push_back(result);
- command.push_back("-h");
+ command.emplace_back("-h");
std::string stdOut;
std::string stdErr;
int retVal = 0;
@@ -1546,9 +1547,9 @@ bool cmQtAutoGenInitializer::GetRccExecutable()
if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) {
if (stdOut.find("--list") != std::string::npos) {
- this->Rcc.ListOptions.push_back("--list");
+ this->Rcc.ListOptions.emplace_back("--list");
} else {
- this->Rcc.ListOptions.push_back("-list");
+ this->Rcc.ListOptions.emplace_back("-list");
}
}
return true;
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 47f157c..eefbaf0 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -102,7 +102,8 @@ private:
bool SetupWriteAutogenInfo();
bool SetupWriteRccInfo();
- void AddGeneratedSource(std::string const& filename, GeneratorT genType);
+ void AddGeneratedSource(std::string const& filename, GeneratorT genType,
+ bool prepend = false);
bool GetMocExecutable();
bool GetUicExecutable();
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index c5d5d7c..e2d7deb 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -54,7 +54,7 @@ void cmQtAutoGenerator::Logger::Info(GeneratorT genType,
}
{
std::lock_guard<std::mutex> lock(Mutex_);
- cmSystemTools::Stdout(msg.c_str(), msg.size());
+ cmSystemTools::Stdout(msg);
}
}
@@ -78,7 +78,7 @@ void cmQtAutoGenerator::Logger::Warning(GeneratorT genType,
msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
- cmSystemTools::Stdout(msg.c_str(), msg.size());
+ cmSystemTools::Stdout(msg);
}
}
@@ -107,7 +107,7 @@ void cmQtAutoGenerator::Logger::Error(GeneratorT genType,
msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
- cmSystemTools::Stderr(msg.c_str(), msg.size());
+ cmSystemTools::Stderr(msg);
}
}
@@ -149,7 +149,7 @@ void cmQtAutoGenerator::Logger::ErrorCommand(
msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
- cmSystemTools::Stderr(msg.c_str(), msg.size());
+ cmSystemTools::Stderr(msg);
}
}
diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx
index 9658e97..068f65c 100644
--- a/Source/cmQtAutoGeneratorMocUic.cxx
+++ b/Source/cmQtAutoGeneratorMocUic.cxx
@@ -844,10 +844,10 @@ void cmQtAutoGeneratorMocUic::JobMocT::GenerateMoc(WorkerT& wrk)
wrk.Moc().AllOptions.end());
// Add predefs include
if (!wrk.Moc().PredefsFileAbs.empty()) {
- cmd.push_back("--include");
+ cmd.emplace_back("--include");
cmd.push_back(wrk.Moc().PredefsFileAbs);
}
- cmd.push_back("-o");
+ cmd.emplace_back("-o");
cmd.push_back(BuildFile);
cmd.push_back(SourceFile);
@@ -963,7 +963,7 @@ void cmQtAutoGeneratorMocUic::JobUicT::GenerateUic(WorkerT& wrk)
}
cmd.insert(cmd.end(), allOpts.begin(), allOpts.end());
}
- cmd.push_back("-o");
+ cmd.emplace_back("-o");
cmd.push_back(BuildFile);
cmd.push_back(SourceFile);
@@ -1213,7 +1213,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
};
// -- Read info file
- if (!makefile->ReadListFile(InfoFile().c_str())) {
+ if (!makefile->ReadListFile(InfoFile())) {
Log().ErrorFile(GeneratorT::GEN, InfoFile(), "File processing failed");
return false;
}
@@ -1288,7 +1288,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
std::string& error) {
if (!key.empty()) {
if (!exp.empty()) {
- Moc_.DependFilters.push_back(KeyExpT());
+ Moc_.DependFilters.emplace_back();
KeyExpT& filter(Moc_.DependFilters.back());
if (filter.Exp.compile(exp)) {
filter.Key = key;
@@ -1506,7 +1506,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
}
// Append framework includes
for (std::string const& path : frameworkPaths) {
- Moc_.Includes.push_back("-F");
+ Moc_.Includes.emplace_back("-F");
Moc_.Includes.push_back(path);
}
}
diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx
index 29dc7a0..87c8d18 100644
--- a/Source/cmQtAutoGeneratorRcc.cxx
+++ b/Source/cmQtAutoGeneratorRcc.cxx
@@ -58,7 +58,7 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile)
};
// -- Read info file
- if (!makefile->ReadListFile(InfoFile().c_str())) {
+ if (!makefile->ReadListFile(InfoFile())) {
Log().ErrorFile(GeneratorT::RCC, InfoFile(), "File processing failed");
return false;
}
@@ -603,7 +603,7 @@ bool cmQtAutoGeneratorRcc::GenerateRcc()
std::vector<std::string> cmd;
cmd.push_back(RccExecutable_);
cmd.insert(cmd.end(), Options_.begin(), Options_.end());
- cmd.push_back("-o");
+ cmd.emplace_back("-o");
cmd.push_back(RccFileOutput_);
cmd.push_back(QrcFile_);
// We're done here if the process fails to start
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index f0f92aa..2866a39 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -178,7 +178,7 @@ void cmRST::ProcessLine(std::string const& line)
// Record the literal lines to output after whole block.
// Ignore the language spec and record the opening line as blank.
this->Directive = DirectiveCodeBlock;
- this->MarkupLines.push_back("");
+ this->MarkupLines.emplace_back();
} else if (this->ReplaceDirective.find(line)) {
// Record the replace directive content.
this->Directive = DirectiveReplace;
@@ -221,7 +221,7 @@ void cmRST::ProcessLine(std::string const& line)
// Record the literal lines to output after whole block.
this->Markup = MarkupNormal;
this->Directive = DirectiveLiteralBlock;
- this->MarkupLines.push_back("");
+ this->MarkupLines.emplace_back();
this->OutputLine("", false);
}
// Print non-markup lines.
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 4b74ff0..c3e8ff5 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -167,6 +167,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.SwiftAuxiliarySources;
}
}
+ if (replaceValues.SwiftModuleName) {
+ if (variable == "SWIFT_MODULE_NAME") {
+ return replaceValues.SwiftModuleName;
+ }
+ }
if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
variable == "TARGET_INSTALLNAME_DIR") {
// All these variables depend on TargetSOName
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index a936747..7aa63db 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -59,6 +59,7 @@ public:
const char* DependencyFile;
const char* FilterPrefix;
const char* SwiftAuxiliarySources;
+ const char* SwiftModuleName;
};
// Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 8445b02..9388e7c 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -53,17 +53,17 @@ bool cmSetSourceFilesPropertiesCommand::RunCommand(
for (j = propbeg; j != propend; ++j) {
// old style allows for specifier before PROPERTIES keyword
if (*j == "ABSTRACT") {
- propertyPairs.push_back("ABSTRACT");
- propertyPairs.push_back("1");
+ propertyPairs.emplace_back("ABSTRACT");
+ propertyPairs.emplace_back("1");
} else if (*j == "WRAP_EXCLUDE") {
- propertyPairs.push_back("WRAP_EXCLUDE");
- propertyPairs.push_back("1");
+ propertyPairs.emplace_back("WRAP_EXCLUDE");
+ propertyPairs.emplace_back("1");
} else if (*j == "GENERATED") {
generated = true;
- propertyPairs.push_back("GENERATED");
- propertyPairs.push_back("1");
+ propertyPairs.emplace_back("GENERATED");
+ propertyPairs.emplace_back("1");
} else if (*j == "COMPILE_FLAGS") {
- propertyPairs.push_back("COMPILE_FLAGS");
+ propertyPairs.emplace_back("COMPILE_FLAGS");
++j;
if (j == propend) {
errors = "called with incorrect number of arguments "
@@ -72,7 +72,7 @@ bool cmSetSourceFilesPropertiesCommand::RunCommand(
}
propertyPairs.push_back(*j);
} else if (*j == "OBJECT_DEPENDS") {
- propertyPairs.push_back("OBJECT_DEPENDS");
+ propertyPairs.emplace_back("OBJECT_DEPENDS");
++j;
if (j == propend) {
errors = "called with incorrect number of arguments "
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index 7f33b7a..01758ee 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -19,12 +19,12 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
std::vector<std::string> paths;
- paths.push_back("/usr/bsd");
- paths.push_back("/usr/sbin");
- paths.push_back("/usr/bin");
- paths.push_back("/bin");
- paths.push_back("/sbin");
- paths.push_back("/usr/local/bin");
+ paths.emplace_back("/usr/bsd");
+ paths.emplace_back("/usr/sbin");
+ paths.emplace_back("/usr/bin");
+ paths.emplace_back("/bin");
+ paths.emplace_back("/sbin");
+ paths.emplace_back("/usr/local/bin");
const char* cacheValue = this->Makefile->GetDefinition(args[0]);
if (cacheValue) {
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 08f4d1a..34ded38 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -105,7 +105,7 @@ bool addFilesToItsSourceGroups(const std::string& root,
tokenizedPath.pop_back();
if (tokenizedPath.empty()) {
- tokenizedPath.push_back("");
+ tokenizedPath.emplace_back();
}
sg = makefile.GetOrCreateSourceGroup(tokenizedPath);
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
index 69b7ced..f50cf58 100644
--- a/Source/cmStringReplaceHelper.cxx
+++ b/Source/cmStringReplaceHelper.cxx
@@ -85,10 +85,12 @@ void cmStringReplaceHelper::ParseReplaceExpression()
auto r = this->ReplaceExpression.find('\\', l);
if (r == std::string::npos) {
r = this->ReplaceExpression.length();
- this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ this->Replacements.emplace_back(
+ this->ReplaceExpression.substr(l, r - l));
} else {
if (r - l > 0) {
- this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ this->Replacements.emplace_back(
+ this->ReplaceExpression.substr(l, r - l));
}
if (r == (this->ReplaceExpression.length() - 1)) {
this->ValidReplaceExpression = false;
@@ -97,11 +99,11 @@ void cmStringReplaceHelper::ParseReplaceExpression()
}
if ((this->ReplaceExpression[r + 1] >= '0') &&
(this->ReplaceExpression[r + 1] <= '9')) {
- this->Replacements.push_back(this->ReplaceExpression[r + 1] - '0');
+ this->Replacements.emplace_back(this->ReplaceExpression[r + 1] - '0');
} else if (this->ReplaceExpression[r + 1] == 'n') {
- this->Replacements.push_back("\n");
+ this->Replacements.emplace_back("\n");
} else if (this->ReplaceExpression[r + 1] == '\\') {
- this->Replacements.push_back("\\");
+ this->Replacements.emplace_back("\\");
} else {
this->ValidReplaceExpression = false;
std::ostringstream error;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index be65853..9abc5f3 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -302,33 +302,21 @@ void cmSystemTools::SetStderrCallback(OutputCallback f, void* clientData)
s_StderrCallbackClientData = clientData;
}
-void cmSystemTools::Stdout(const char* s)
-{
- cmSystemTools::Stdout(s, strlen(s));
-}
-
-void cmSystemTools::Stderr(const char* s)
-{
- cmSystemTools::Stderr(s, strlen(s));
-}
-
-void cmSystemTools::Stderr(const char* s, size_t length)
+void cmSystemTools::Stderr(const std::string& s)
{
if (s_StderrCallback) {
- (*s_StderrCallback)(s, length, s_StderrCallbackClientData);
+ (*s_StderrCallback)(s.c_str(), s.length(), s_StderrCallbackClientData);
} else {
- std::cerr.write(s, length);
- std::cerr.flush();
+ std::cerr << s << std::flush;
}
}
-void cmSystemTools::Stdout(const char* s, size_t length)
+void cmSystemTools::Stdout(const std::string& s)
{
if (s_StdoutCallback) {
- (*s_StdoutCallback)(s, length, s_StdoutCallbackClientData);
+ (*s_StdoutCallback)(s.c_str(), s.length(), s_StdoutCallbackClientData);
} else {
- std::cout.write(s, length);
- std::cout.flush();
+ std::cout << s << std::flush;
}
}
@@ -534,7 +522,7 @@ public:
void Store(std::vector<std::string>& args) const
{
for (char** arg = this->ArgV; arg && *arg; ++arg) {
- args.push_back(*arg);
+ args.emplace_back(*arg);
}
}
};
@@ -792,7 +780,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
if (pipe == cmsysProcess_Pipe_STDOUT) {
if (outputflag != OUTPUT_NONE) {
processOutput.DecodeText(data, length, strdata, 1);
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
if (captureStdOut) {
tempStdOut.insert(tempStdOut.end(), data, data + length);
@@ -800,7 +788,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
} else if (pipe == cmsysProcess_Pipe_STDERR) {
if (outputflag != OUTPUT_NONE) {
processOutput.DecodeText(data, length, strdata, 2);
- cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+ cmSystemTools::Stderr(strdata);
}
if (captureStdErr) {
tempStdErr.insert(tempStdErr.end(), data, data + length);
@@ -811,11 +799,11 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
if (outputflag != OUTPUT_NONE) {
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
- cmSystemTools::Stdout(strdata.c_str(), strdata.size());
+ cmSystemTools::Stdout(strdata);
}
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
- cmSystemTools::Stderr(strdata.c_str(), strdata.size());
+ cmSystemTools::Stderr(strdata);
}
}
}
@@ -1586,7 +1574,7 @@ std::vector<std::string> cmSystemTools::GetEnvironmentVariables()
std::vector<std::string> env;
int cc;
for (cc = 0; environ[cc]; ++cc) {
- env.push_back(environ[cc]);
+ env.emplace_back(environ[cc]);
}
return env;
}
@@ -1899,13 +1887,13 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract)
if (verbose) {
if (extract) {
cmSystemTools::Stdout("x ");
- cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry));
} else {
list_item_verbose(stdout, entry);
}
cmSystemTools::Stdout("\n");
} else if (!extract) {
- cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry));
cmSystemTools::Stdout("\n");
}
if (extract) {
@@ -3063,7 +3051,7 @@ std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
} while (tokend != std::string::npos);
if (tokens.empty()) {
- tokens.push_back("");
+ tokens.emplace_back();
}
return tokens;
}
@@ -3114,7 +3102,8 @@ std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
}
bool cmSystemTools::CreateSymlink(const std::string& origName,
- const std::string& newName)
+ const std::string& newName,
+ std::string* errorMessage)
{
uv_fs_t req;
int flags = 0;
@@ -3128,7 +3117,32 @@ bool cmSystemTools::CreateSymlink(const std::string& origName,
if (err) {
std::string e =
"failed to create symbolic link '" + newName + "': " + uv_strerror(err);
- cmSystemTools::Error(e.c_str());
+ if (errorMessage) {
+ *errorMessage = std::move(e);
+ } else {
+ cmSystemTools::Error(e.c_str());
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool cmSystemTools::CreateLink(const std::string& origName,
+ const std::string& newName,
+ std::string* errorMessage)
+{
+ uv_fs_t req;
+ int err =
+ uv_fs_link(nullptr, &req, origName.c_str(), newName.c_str(), nullptr);
+ if (err) {
+ std::string e =
+ "failed to create link '" + newName + "': " + uv_strerror(err);
+ if (errorMessage) {
+ *errorMessage = std::move(e);
+ } else {
+ cmSystemTools::Error(e.c_str());
+ }
return false;
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index c0999e7..7a209c6 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -79,13 +79,11 @@ public:
typedef void (*OutputCallback)(const char*, size_t length, void*);
///! Send a string to stdout
- static void Stdout(const char* s);
- static void Stdout(const char* s, size_t length);
+ static void Stdout(const std::string& s);
static void SetStdoutCallback(OutputCallback, void* clientData = nullptr);
///! Send a string to stderr
- static void Stderr(const char* s);
- static void Stderr(const char* s, size_t length);
+ static void Stderr(const std::string& s);
static void SetStderrCallback(OutputCallback, void* clientData = nullptr);
typedef bool (*InterruptCallback)(void*);
@@ -528,7 +526,14 @@ public:
/** Create a symbolic link if the platform supports it. Returns whether
creation succeeded. */
static bool CreateSymlink(const std::string& origName,
- const std::string& newName);
+ const std::string& newName,
+ std::string* errorMessage = nullptr);
+
+ /** Create a hard link if the platform supports it. Returns whether
+ creation succeeded. */
+ static bool CreateLink(const std::string& origName,
+ const std::string& newName,
+ std::string* errorMessage = nullptr);
private:
static bool s_ForceUnixPaths;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a94cf6a..fe48934 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -662,7 +662,7 @@ public:
}
};
-cmSourceFile* cmTarget::AddSource(const std::string& src)
+cmSourceFile* cmTarget::AddSource(const std::string& src, bool before)
{
cmSourceFileLocation sfl(this->Makefile, src,
cmSourceFileLocationKind::Known);
@@ -671,8 +671,14 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
TargetPropertyEntryFinder(sfl)) ==
this->Internal->SourceEntries.end()) {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- this->Internal->SourceEntries.push_back(src);
- this->Internal->SourceBacktraces.push_back(lfbt);
+ this->Internal->SourceEntries.insert(
+ before ? this->Internal->SourceEntries.begin()
+ : this->Internal->SourceEntries.end(),
+ src);
+ this->Internal->SourceBacktraces.insert(
+ before ? this->Internal->SourceBacktraces.begin()
+ : this->Internal->SourceBacktraces.end(),
+ lfbt);
}
if (cmGeneratorExpression::Find(src) != std::string::npos) {
return nullptr;
@@ -731,7 +737,7 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
}
}
if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc) {
- this->TLLCommands.push_back(std::make_pair(signature, lfc));
+ this->TLLCommands.emplace_back(signature, lfc);
}
return ret;
}
@@ -975,7 +981,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->IncludeDirectoriesEntries.clear();
this->Internal->IncludeDirectoriesBacktraces.clear();
if (value) {
- this->Internal->IncludeDirectoriesEntries.push_back(value);
+ this->Internal->IncludeDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
}
@@ -983,7 +989,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->CompileOptionsEntries.clear();
this->Internal->CompileOptionsBacktraces.clear();
if (value) {
- this->Internal->CompileOptionsEntries.push_back(value);
+ this->Internal->CompileOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileOptionsBacktraces.push_back(lfbt);
}
@@ -991,7 +997,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->CompileFeaturesEntries.clear();
this->Internal->CompileFeaturesBacktraces.clear();
if (value) {
- this->Internal->CompileFeaturesEntries.push_back(value);
+ this->Internal->CompileFeaturesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
}
@@ -999,7 +1005,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->CompileDefinitionsEntries.clear();
this->Internal->CompileDefinitionsBacktraces.clear();
if (value) {
- this->Internal->CompileDefinitionsEntries.push_back(value);
+ this->Internal->CompileDefinitionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
@@ -1007,7 +1013,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->LinkOptionsEntries.clear();
this->Internal->LinkOptionsBacktraces.clear();
if (value) {
- this->Internal->LinkOptionsEntries.push_back(value);
+ this->Internal->LinkOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->LinkOptionsBacktraces.push_back(lfbt);
}
@@ -1015,7 +1021,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->LinkDirectoriesEntries.clear();
this->Internal->LinkDirectoriesBacktraces.clear();
if (value) {
- this->Internal->LinkDirectoriesEntries.push_back(value);
+ this->Internal->LinkDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->LinkDirectoriesBacktraces.push_back(lfbt);
}
@@ -1024,7 +1030,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->LinkImplementationPropertyBacktraces.clear();
if (value) {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- this->Internal->LinkImplementationPropertyEntries.push_back(value);
+ this->Internal->LinkImplementationPropertyEntries.emplace_back(value);
this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == propSOURCES) {
@@ -1032,7 +1038,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->SourceBacktraces.clear();
if (value) {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- this->Internal->SourceEntries.push_back(value);
+ this->Internal->SourceEntries.emplace_back(value);
this->Internal->SourceBacktraces.push_back(lfbt);
}
} else if (prop == propIMPORTED_GLOBAL) {
@@ -1102,49 +1108,49 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
}
if (prop == "INCLUDE_DIRECTORIES") {
if (value && *value) {
- this->Internal->IncludeDirectoriesEntries.push_back(value);
+ this->Internal->IncludeDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_OPTIONS") {
if (value && *value) {
- this->Internal->CompileOptionsEntries.push_back(value);
+ this->Internal->CompileOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_FEATURES") {
if (value && *value) {
- this->Internal->CompileFeaturesEntries.push_back(value);
+ this->Internal->CompileFeaturesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_DEFINITIONS") {
if (value && *value) {
- this->Internal->CompileDefinitionsEntries.push_back(value);
+ this->Internal->CompileDefinitionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_OPTIONS") {
if (value && *value) {
- this->Internal->LinkOptionsEntries.push_back(value);
+ this->Internal->LinkOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->LinkOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_DIRECTORIES") {
if (value && *value) {
- this->Internal->LinkDirectoriesEntries.push_back(value);
+ this->Internal->LinkDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->LinkDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_LIBRARIES") {
if (value && *value) {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- this->Internal->LinkImplementationPropertyEntries.push_back(value);
+ this->Internal->LinkImplementationPropertyEntries.emplace_back(value);
this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == "SOURCES") {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- this->Internal->SourceEntries.push_back(value);
+ this->Internal->SourceEntries.emplace_back(value);
this->Internal->SourceBacktraces.push_back(lfbt);
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 655cefd..24b3742 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -123,7 +123,7 @@ public:
void AddSources(std::vector<std::string> const& srcs);
void AddTracedSources(std::vector<std::string> const& srcs);
cmSourceFile* AddSourceCMP0049(const std::string& src);
- cmSourceFile* AddSource(const std::string& src);
+ cmSourceFile* AddSource(const std::string& src, bool before = false);
//* how we identify a library, by name and type
typedef std::pair<std::string, cmTargetLinkLibraryType> LibraryID;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 1e2ddc7..6032701 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -90,7 +90,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Prepend with the emulator when cross compiling if required.
const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
- if (emulator != nullptr) {
+ if (emulator != nullptr && *emulator) {
std::vector<std::string> emulatorWithArgs;
cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
std::string emulatorExe(emulatorWithArgs[0]);
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index e224a27..10a6d9a 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -101,11 +101,11 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
bool captureRunOutput = false;
if (!this->OutputVariable.empty()) {
captureRunOutput = true;
- tryCompile.push_back("OUTPUT_VARIABLE");
+ tryCompile.emplace_back("OUTPUT_VARIABLE");
tryCompile.push_back(this->OutputVariable);
}
if (!this->CompileOutputVariable.empty()) {
- tryCompile.push_back("OUTPUT_VARIABLE");
+ tryCompile.emplace_back("OUTPUT_VARIABLE");
tryCompile.push_back(this->CompileOutputVariable);
}
if (!this->RunOutputVariable.empty()) {
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 9fcfbde..065f6df 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -179,31 +179,31 @@ cmake::cmake(Role role, cmState::Mode mode)
// these are used to find files when the extension
// is not given
// The "c" extension MUST precede the "C" extension.
- this->SourceFileExtensions.push_back("c");
- this->SourceFileExtensions.push_back("C");
-
- this->SourceFileExtensions.push_back("c++");
- this->SourceFileExtensions.push_back("cc");
- this->SourceFileExtensions.push_back("cpp");
- this->SourceFileExtensions.push_back("cxx");
- this->SourceFileExtensions.push_back("cu");
- this->SourceFileExtensions.push_back("m");
- this->SourceFileExtensions.push_back("M");
- this->SourceFileExtensions.push_back("mm");
+ this->SourceFileExtensions.emplace_back("c");
+ this->SourceFileExtensions.emplace_back("C");
+
+ this->SourceFileExtensions.emplace_back("c++");
+ this->SourceFileExtensions.emplace_back("cc");
+ this->SourceFileExtensions.emplace_back("cpp");
+ this->SourceFileExtensions.emplace_back("cxx");
+ this->SourceFileExtensions.emplace_back("cu");
+ this->SourceFileExtensions.emplace_back("m");
+ this->SourceFileExtensions.emplace_back("M");
+ this->SourceFileExtensions.emplace_back("mm");
std::copy(this->SourceFileExtensions.begin(),
this->SourceFileExtensions.end(),
std::inserter(this->SourceFileExtensionsSet,
this->SourceFileExtensionsSet.end()));
- this->HeaderFileExtensions.push_back("h");
- this->HeaderFileExtensions.push_back("hh");
- this->HeaderFileExtensions.push_back("h++");
- this->HeaderFileExtensions.push_back("hm");
- this->HeaderFileExtensions.push_back("hpp");
- this->HeaderFileExtensions.push_back("hxx");
- this->HeaderFileExtensions.push_back("in");
- this->HeaderFileExtensions.push_back("txx");
+ this->HeaderFileExtensions.emplace_back("h");
+ this->HeaderFileExtensions.emplace_back("hh");
+ this->HeaderFileExtensions.emplace_back("h++");
+ this->HeaderFileExtensions.emplace_back("hm");
+ this->HeaderFileExtensions.emplace_back("hpp");
+ this->HeaderFileExtensions.emplace_back("hxx");
+ this->HeaderFileExtensions.emplace_back("in");
+ this->HeaderFileExtensions.emplace_back("txx");
std::copy(this->HeaderFileExtensions.begin(),
this->HeaderFileExtensions.end(),
@@ -533,7 +533,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
mf->SetArgcArgv(args);
std::string systemFile = mf->GetModulesFile("CMakeFindPackageMode.cmake");
- mf->ReadListFile(systemFile.c_str());
+ mf->ReadListFile(systemFile);
std::string language = mf->GetSafeDefinition("LANGUAGE");
std::string mode = mf->GetSafeDefinition("MODE");
@@ -959,17 +959,25 @@ void cmake::AddDefaultExtraGenerators()
#endif
}
-void cmake::GetRegisteredGenerators(
- std::vector<GeneratorInfo>& generators) const
+void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
+ bool includeNamesWithPlatform) const
{
for (cmGlobalGeneratorFactory* gen : this->Generators) {
- std::vector<std::string> names;
- gen->GetGenerators(names);
+ std::vector<std::string> names = gen->GetGeneratorNames();
+
+ if (includeNamesWithPlatform) {
+ std::vector<std::string> namesWithPlatform =
+ gen->GetGeneratorNamesWithPlatform();
+ names.insert(names.end(), namesWithPlatform.begin(),
+ namesWithPlatform.end());
+ }
for (std::string const& name : names) {
GeneratorInfo info;
info.supportsToolset = gen->SupportsToolset();
info.supportsPlatform = gen->SupportsPlatform();
+ info.supportedPlatforms = gen->GetKnownPlatforms();
+ info.defaultPlatform = gen->GetDefaultPlatformName();
info.name = name;
info.baseName = name;
info.isAlias = false;
@@ -1519,7 +1527,7 @@ int cmake::ActualConfigure()
return 0;
}
-void cmake::CreateDefaultGlobalGenerator()
+std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
{
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
std::string found;
@@ -1572,11 +1580,20 @@ void cmake::CreateDefaultGlobalGenerator()
if (!gen) {
gen = new cmGlobalNMakeMakefileGenerator(this);
}
- this->SetGlobalGenerator(gen);
- std::cout << "-- Building for: " << gen->GetName() << "\n";
+ return std::unique_ptr<cmGlobalGenerator>(gen);
#else
- this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
+ return cm::make_unique<cmGlobalUnixMakefileGenerator3>(this);
+#endif
+}
+
+void cmake::CreateDefaultGlobalGenerator()
+{
+ auto gen = this->EvaluateDefaultGlobalGenerator();
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
+ // This print could be unified for all platforms
+ std::cout << "-- Building for: " << gen->GetName() << "\n";
#endif
+ this->SetGlobalGenerator(gen.release());
}
void cmake::PreLoadCMakeFiles()
@@ -1924,13 +1941,28 @@ void cmake::SetIsInTryCompile(bool b)
this->State->SetIsInTryCompile(b);
}
-void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
+void cmake::AppendGlobalGeneratorsDocumentation(
+ std::vector<cmDocumentationEntry>& v)
{
+ const auto defaultGenerator = this->EvaluateDefaultGlobalGenerator();
+ const std::string defaultName = defaultGenerator->GetName();
+ bool foundDefaultOne = false;
+
for (cmGlobalGeneratorFactory* g : this->Generators) {
cmDocumentationEntry e;
g->GetDocumentation(e);
+ if (!foundDefaultOne &&
+ cmSystemTools::StringStartsWith(e.Name, defaultName.c_str())) {
+ e.CustomNamePrefix = '*';
+ foundDefaultOne = true;
+ }
v.push_back(std::move(e));
}
+}
+
+void cmake::AppendExtraGeneratorsDocumentation(
+ std::vector<cmDocumentationEntry>& v)
+{
for (cmExternalMakefileProjectGeneratorFactory* eg : this->ExtraGenerators) {
const std::string doc = eg->GetDocumentation();
const std::string name = eg->GetName();
@@ -1956,12 +1988,19 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
}
}
+std::vector<cmDocumentationEntry> cmake::GetGeneratorsDocumentation()
+{
+ std::vector<cmDocumentationEntry> v;
+ this->AppendGlobalGeneratorsDocumentation(v);
+ this->AppendExtraGeneratorsDocumentation(v);
+ return v;
+}
+
void cmake::PrintGeneratorList()
{
#ifdef CMAKE_BUILD_WITH_CMAKE
cmDocumentation doc;
- std::vector<cmDocumentationEntry> generators;
- this->GetGeneratorDocumentation(generators);
+ auto generators = this->GetGeneratorsDocumentation();
doc.AppendSection("Generators", generators);
std::cerr << "\n";
doc.PrintDocumentation(cmDocumentation::ListGenerators, std::cerr);
@@ -2006,7 +2045,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake no build system arguments\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2017,7 +2056,7 @@ int cmake::CheckBuildSystem()
std::ostringstream msg;
msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument
<< "\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2031,13 +2070,13 @@ int cmake::CheckBuildSystem()
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
- if (!mf.ReadListFile(this->CheckBuildSystemArgument.c_str()) ||
+ if (!mf.ReadListFile(this->CheckBuildSystemArgument) ||
cmSystemTools::GetErrorOccuredFlag()) {
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake error reading : " << this->CheckBuildSystemArgument
<< "\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
// There was an error reading the file. Just rerun.
return 1;
@@ -2071,7 +2110,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake, missing byproduct: " << p << "\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2092,7 +2131,7 @@ int cmake::CheckBuildSystem()
std::ostringstream msg;
msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
"or CMAKE_MAKEFILE_OUTPUTS :\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2111,7 +2150,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake: build system dependency is missing\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2131,7 +2170,7 @@ int cmake::CheckBuildSystem()
if (verbose) {
std::ostringstream msg;
msg << "Re-run cmake: build system output is missing\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2147,7 +2186,7 @@ int cmake::CheckBuildSystem()
std::ostringstream msg;
msg << "Re-run cmake file: " << out_oldest
<< " older than: " << dep_newest << "\n";
- cmSystemTools::Stdout(msg.str().c_str());
+ cmSystemTools::Stdout(msg.str());
}
return 1;
}
@@ -2485,7 +2524,7 @@ std::vector<std::string> cmake::GetDebugConfigs()
}
// If no configurations were specified, use a default list.
if (configs.empty()) {
- configs.push_back("DEBUG");
+ configs.emplace_back("DEBUG");
}
return configs;
}
diff --git a/Source/cmake.h b/Source/cmake.h
index cd8c622..9478ad0e 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -104,6 +104,8 @@ public:
std::string extraName;
bool supportsToolset;
bool supportsPlatform;
+ std::vector<std::string> supportedPlatforms;
+ std::string defaultPlatform;
bool isAlias;
};
@@ -196,7 +198,8 @@ public:
void SetGlobalGenerator(cmGlobalGenerator*);
///! Get the names of the current registered generators
- void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators) const;
+ void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
+ bool includeNamesWithPlatform = true) const;
///! Set the name of the selected generator-specific instance.
void SetGeneratorInstance(std::string const& instance)
@@ -292,7 +295,7 @@ public:
cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
#endif
- void GetGeneratorDocumentation(std::vector<cmDocumentationEntry>&);
+ std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();
///! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
@@ -531,8 +534,12 @@ private:
// Print a list of valid generators to stderr.
void PrintGeneratorList();
+ std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
void CreateDefaultGlobalGenerator();
+ void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+ void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+
/**
* Convert a message type between a warning and an error, based on the state
* of the error output CMake variables, in the cache.
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 84d1414..10655d5 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAlgorithms.h"
-#include "cmDocumentationEntry.h"
+#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -106,7 +106,7 @@ static int do_command(int ac, char const* const* av)
{
std::vector<std::string> args;
args.reserve(ac - 1);
- args.push_back(av[0]);
+ args.emplace_back(av[0]);
args.insert(args.end(), av + 2, av + ac);
return cmcmd::ExecuteCMakeCommand(args);
}
@@ -227,9 +227,7 @@ int do_cmake(int ac, char const* const* av)
std::vector<std::string> args(av, av + ac);
hcm.SetCacheArgs(args);
- std::vector<cmDocumentationEntry> generators;
-
- hcm.GetGeneratorDocumentation(generators);
+ auto generators = hcm.GetGeneratorsDocumentation();
doc.SetName("cmake");
doc.SetSection("Name", cmDocumentationName);
@@ -288,14 +286,14 @@ int do_cmake(int ac, char const* const* av)
return 1;
}
workingMode = cmake::SCRIPT_MODE;
- args.push_back(av[i]);
+ args.emplace_back(av[i]);
i++;
- args.push_back(av[i]);
+ args.emplace_back(av[i]);
} else if (cmHasLiteralPrefix(av[i], "--find-package")) {
workingMode = cmake::FIND_PACKAGE_MODE;
- args.push_back(av[i]);
+ args.emplace_back(av[i]);
} else {
- args.push_back(av[i]);
+ args.emplace_back(av[i]);
}
}
if (sysinfo) {
@@ -386,7 +384,7 @@ static int do_build(int ac, char const* const* av)
Doing doing = DoingDir;
for (int i = 2; i < ac; ++i) {
if (doing == DoingNative) {
- nativeOptions.push_back(av[i]);
+ nativeOptions.emplace_back(av[i]);
} else if ((strcmp(av[i], "-j") == 0) ||
(strcmp(av[i], "--parallel") == 0)) {
jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index ee8df35..26f7509 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -201,7 +201,7 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
std::vector<std::string> tidy_cmd;
cmSystemTools::ExpandListArgument(runCmd, tidy_cmd, true);
tidy_cmd.push_back(sourceFile);
- tidy_cmd.push_back("--");
+ tidy_cmd.emplace_back("--");
tidy_cmd.insert(tidy_cmd.end(), orig_cmd.begin(), orig_cmd.end());
// Run the tidy command line. Capture its stdout and hide its stderr.
@@ -228,9 +228,9 @@ static int HandleLWYU(const std::string& runCmd,
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
std::vector<std::string> lwyu_cmd;
- lwyu_cmd.push_back("ldd");
- lwyu_cmd.push_back("-u");
- lwyu_cmd.push_back("-r");
+ lwyu_cmd.emplace_back("ldd");
+ lwyu_cmd.emplace_back("-u");
+ lwyu_cmd.emplace_back("-r");
lwyu_cmd.push_back(runCmd);
// Run the ldd -u -r command line.
@@ -1733,7 +1733,7 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
}
if (this->LinkGeneratesManifest) {
- this->LinkCommand.push_back("/MANIFEST");
+ this->LinkCommand.emplace_back("/MANIFEST");
this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
}
@@ -1881,8 +1881,8 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
{
std::vector<std::string> mtCommand;
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
- mtCommand.push_back("/nologo");
- mtCommand.push_back("/manifest");
+ mtCommand.emplace_back("/nologo");
+ mtCommand.emplace_back("/manifest");
if (this->LinkGeneratesManifest) {
mtCommand.push_back(this->LinkerManifestFile);
}
@@ -1892,7 +1892,7 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
if (notify) {
// Add an undocumented option that enables a special return
// code to notify us when the manifest is modified.
- mtCommand.push_back("/notify_update");
+ mtCommand.emplace_back("/notify_update");
}
int mtRet = 0;
if (!RunCommand("MT", mtCommand, this->Verbose, FORMAT_HEX, &mtRet,
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 8ba126f..4a2531a 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -208,7 +208,7 @@ int main(int argc, char const* const* argv)
std::vector<std::string> args;
args.reserve(argc);
for (int i = 0; i < argc; ++i) {
- args.push_back(argv[i]);
+ args.emplace_back(argv[i]);
}
// run ctest
std::string output;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 7338993..c1703cc 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -436,6 +436,9 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(PolicyScope PolicyScope)
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
+ if(CMAKE_Fortran_COMPILER)
+ set(CompileOptions_BUILD_OPTIONS -DTEST_FORTRAN=1)
+ endif()
ADD_TEST_MACRO(CompileOptions CompileOptions)
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
ADD_TEST_MACRO(AliasTarget AliasTarget)
@@ -1434,6 +1437,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindGIF)
endif()
+ if(CMake_TEST_FindGit)
+ add_subdirectory(FindGit)
+ endif()
+
if(CMake_TEST_FindGSL)
add_subdirectory(FindGSL)
endif()
@@ -1635,6 +1642,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir")
+ add_test(NAME ExternalProjectSourceSubdirNotCMake
+ COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ExternalProjectSourceSubdirNotCMake"
+ "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake"
+ ${build_generator_args}
+ --build-project ExternalProjectSourceSubdirNotCMake
+ --force-new-ctest-process
+ --build-options ${build_options}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake")
+
add_test(ExternalProjectLocal ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/ExternalProjectLocal"
diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt
index c9f1710..15a993c 100644
--- a/Tests/CompileOptions/CMakeLists.txt
+++ b/Tests/CompileOptions/CMakeLists.txt
@@ -4,6 +4,10 @@ project(CompileOptions)
add_library(testlib other.cpp)
+if(TEST_FORTRAN)
+ enable_language(Fortran)
+endif()
+
add_executable(CompileOptions main.cpp)
macro(get_compiler_test_genex lst lang)
@@ -13,6 +17,9 @@ endmacro()
get_compiler_test_genex(c_tests C)
get_compiler_test_genex(cxx_tests CXX)
+if(TEST_FORTRAN)
+ get_compiler_test_genex(fortran_tests Fortran)
+endif()
set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
"-DTEST_DEFINE"
@@ -21,6 +28,7 @@ set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
"SHELL:" # produces no options
${c_tests}
${cxx_tests}
+ ${fortran_tests}
)
if(BORLAND OR WATCOM)
# these compilers do not support separate -D flags
@@ -54,3 +62,12 @@ target_compile_definitions(CompileOptions
"EXPECTED_C_COMPILER_VERSION=\"${CMAKE_C_COMPILER_VERSION}\""
"EXPECTED_CXX_COMPILER_VERSION=\"${CMAKE_CXX_COMPILER_VERSION}\""
)
+
+if(TEST_FORTRAN)
+ # Definitions for the C++ code to test the values
+ target_compile_definitions(CompileOptions
+ PRIVATE
+ "TEST_FORTRAN"
+ "EXPECTED_Fortran_COMPILER_VERSION=\"${CMAKE_Fortran_COMPILER_VERSION}\""
+ )
+endif()
diff --git a/Tests/CompileOptions/main.cpp b/Tests/CompileOptions/main.cpp
index 1379940..d94a169 100644
--- a/Tests/CompileOptions/main.cpp
+++ b/Tests/CompileOptions/main.cpp
@@ -47,10 +47,17 @@ int main()
#endif
&&
strcmp(EXPECTED_C_COMPILER_VERSION, TEST_C_COMPILER_VERSION) == 0 &&
- strcmp(EXPECTED_CXX_COMPILER_VERSION, TEST_CXX_COMPILER_VERSION) ==
- 0 &&
- TEST_C_COMPILER_VERSION_EQUALITY == 1 &&
- TEST_CXX_COMPILER_VERSION_EQUALITY == 1)
+ strcmp(EXPECTED_CXX_COMPILER_VERSION, TEST_CXX_COMPILER_VERSION) == 0
+#ifdef TEST_FORTRAN
+ && strcmp(EXPECTED_Fortran_COMPILER_VERSION,
+ TEST_Fortran_COMPILER_VERSION) == 0
+#endif
+ && TEST_C_COMPILER_VERSION_EQUALITY == 1 &&
+ TEST_CXX_COMPILER_VERSION_EQUALITY == 1
+#ifdef TEST_FORTRAN
+ && TEST_Fortran_COMPILER_VERSION_EQUALITY == 1
+#endif
+ )
? 0
: 1;
}
diff --git a/Tests/ExternalProjectSourceSubdirNotCMake/CMakeLists.txt b/Tests/ExternalProjectSourceSubdirNotCMake/CMakeLists.txt
new file mode 100644
index 0000000..f64df1a
--- /dev/null
+++ b/Tests/ExternalProjectSourceSubdirNotCMake/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.6)
+project(ExternalProjectSourceSubdirNotCMake NONE)
+include(ExternalProject)
+
+find_program(MAKE_EXECUTABLE
+ NAMES gmake make)
+
+if (NOT MAKE_EXECUTABLE)
+ message("No `make` executable found; skipping")
+ return ()
+endif ()
+
+ExternalProject_Add(Example
+ SOURCE_SUBDIR subdir
+ BUILD_IN_SOURCE 1
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Example
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND "${MAKE_EXECUTABLE}"
+ INSTALL_COMMAND ""
+ )
diff --git a/Tests/ExternalProjectSourceSubdirNotCMake/Example/subdir/Makefile b/Tests/ExternalProjectSourceSubdirNotCMake/Example/subdir/Makefile
new file mode 100644
index 0000000..cab3b8f
--- /dev/null
+++ b/Tests/ExternalProjectSourceSubdirNotCMake/Example/subdir/Makefile
@@ -0,0 +1,2 @@
+all:
+ echo "complete"
diff --git a/Tests/FindGit/CMakeLists.txt b/Tests/FindGit/CMakeLists.txt
new file mode 100644
index 0000000..5d061f4
--- /dev/null
+++ b/Tests/FindGit/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindGit.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGit/Test"
+ "${CMake_BINARY_DIR}/Tests/FindGit/Test"
+ ${build_generator_args}
+ --build-project TestFindGit
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindGit/Test/CMakeLists.txt b/Tests/FindGit/Test/CMakeLists.txt
new file mode 100644
index 0000000..26fb372
--- /dev/null
+++ b/Tests/FindGit/Test/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.12)
+project(TestFindGit NONE)
+include(CTest)
+
+find_package(Git REQUIRED)
+
+add_test(NAME test_git
+ COMMAND ${CMAKE_COMMAND}
+ "-DGIT_EXECUTABLE=${GIT_EXECUTABLE}"
+ "-DGIT_EXECUTABLE_TARGET=$<TARGET_FILE:Git::Git>"
+ "-DGIT_VERSION_STRING=${GIT_VERSION_STRING}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/RunGit.cmake"
+ )
diff --git a/Tests/FindGit/Test/RunGit.cmake b/Tests/FindGit/Test/RunGit.cmake
new file mode 100644
index 0000000..f798cd3
--- /dev/null
+++ b/Tests/FindGit/Test/RunGit.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.12)
+
+function(run_git exe exe_display)
+ execute_process(COMMAND ${exe} --version
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result EQUAL 0)
+ message(SEND_ERROR "Result of ${exe_display} --version is ${result}, should be 0")
+ endif()
+
+ if(NOT output STREQUAL "git version ${GIT_VERSION_STRING}")
+ message(SEND_ERROR "Output of ${exe_display} --version is \"${output}\", should be \"git version ${GIT_VERSION_STRING}\"")
+ endif()
+endfunction()
+
+run_git("${GIT_EXECUTABLE}" "\${GIT_EXECUTABLE}")
+run_git("${GIT_EXECUTABLE_TARGET}" "Git::Git")
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 6a80df5..f8b36c5 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -188,6 +188,37 @@ find_package(ArchC 3.1 EXACT NAMES zot)
find_package(ArchD 4.0 EXACT NAMES zot)
unset(CMAKE_LIBRARY_ARCHITECTURE)
+# Test find_package() with CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS enabled
+if(UNIX)
+ # Create ./symlink pointing back here.
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
+ . "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
+ # Make find_package search through the symlink
+ set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
+
+ # First, test the default behavior where symlinks are preserved.
+ set(SetFoundResolved_DIR "")
+ find_package(SetFoundResolved)
+ # The result must preserve the /symlink/ path.
+ set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/symlink/cmake")
+ if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
+ message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+ endif()
+
+ # Resolve symlinks when finding the package.
+ set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS TRUE)
+ set(SetFoundResolved_DIR "")
+ find_package(SetFoundResolved)
+ # ./symlink points back here so it should be gone when resolved.
+ set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+ if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
+ message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+ endif()
+ # Cleanup.
+ unset(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS)
+ file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
+endif()
+
# Test <PackageName>_DIR environment variable.
# We erase the main prefix path to ensure the env var is used.
set(CMAKE_PREFIX_PATH)
diff --git a/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake
new file mode 100644
index 0000000..b2cf87c
--- /dev/null
+++ b/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundResolved_DIR "${CMAKE_CURRENT_LIST_DIR}")
diff --git a/Tests/RunCMake/CMakeRoleGlobalProperty/BuildAndTest/CMakeLists.txt b/Tests/RunCMake/CMakeRoleGlobalProperty/BuildAndTest/CMakeLists.txt
new file mode 100644
index 0000000..332b023
--- /dev/null
+++ b/Tests/RunCMake/CMakeRoleGlobalProperty/BuildAndTest/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.12)
+project(CMakeRoleGlobalPropertyBuildAndTest NONE)
+include(CTest)
+
+get_property(role GLOBAL PROPERTY CMAKE_ROLE)
+if(NOT role STREQUAL "PROJECT")
+ message(SEND_ERROR "CMAKE_ROLE property is \"${role}\", should be \"PROJECT\"")
+endif()
+
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/CMakeRoleGlobalProperty/CMakeLists.txt.in b/Tests/RunCMake/CMakeRoleGlobalProperty/CMakeLists.txt.in
index 913239c..bb8f9c1 100644
--- a/Tests/RunCMake/CMakeRoleGlobalProperty/CMakeLists.txt.in
+++ b/Tests/RunCMake/CMakeRoleGlobalProperty/CMakeLists.txt.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
-project(CTestStart@CASE_NAME@ NONE)
+cmake_minimum_required(VERSION 3.12)
+project(CMakeRoleGlobalProperty@CASE_NAME@ NONE)
include(CTest)
add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/CMakeRoleGlobalProperty/RunCMakeTest.cmake b/Tests/RunCMake/CMakeRoleGlobalProperty/RunCMakeTest.cmake
index b840317..3cbd51d 100644
--- a/Tests/RunCMake/CMakeRoleGlobalProperty/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakeRoleGlobalProperty/RunCMakeTest.cmake
@@ -5,3 +5,10 @@ run_cmake(Project)
run_cmake_command(Script "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/Script.cmake")
run_cmake_command(FindPackage "${CMAKE_COMMAND}" --find-package -DNAME=DummyPackage -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}")
run_ctest(CTest)
+run_cmake_command(BuildAndTest "${CMAKE_CTEST_COMMAND}"
+ --build-and-test
+ "${RunCMake_SOURCE_DIR}/BuildAndTest"
+ "${RunCMake_BINARY_DIR}/BuildAndTest-build"
+ --build-project CMakeRoleGlobalPropertyBuildAndTest
+ --build-generator "${RunCMake_GENERATOR}"
+ )
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index cae14b1..d524f41 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -174,12 +174,15 @@ function(run_TestStdin)
endfunction()
run_TestStdin()
-function(ShowAsJson_check_python v)
+function(show_only_json_check_python v)
+ if(RunCMake_TEST_FAILED OR NOT PYTHON_EXECUTABLE)
+ return()
+ endif()
set(json_file "${RunCMake_TEST_BINARY_DIR}/ctest.json")
file(WRITE "${json_file}" "${actual_stdout}")
set(actual_stdout "" PARENT_SCOPE)
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/ShowAsJson${v}-check.py" "${json_file}"
+ COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/show-only_json-v${v}_check.py" "${json_file}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE output
@@ -190,15 +193,18 @@ function(ShowAsJson_check_python v)
endif()
endfunction()
-function(run_ShowAsJson)
- set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ShowAsJson)
+function(run_ShowOnly)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ShowOnly)
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
- add_test(ShowAsJson \"${CMAKE_COMMAND}\" -E echo)
- set_tests_properties(ShowAsJson PROPERTIES WILL_FAIL true _BACKTRACE_TRIPLES \"file1;1;add_test;file0;;\")
+ add_test(ShowOnly \"${CMAKE_COMMAND}\" -E echo)
+ set_tests_properties(ShowOnly PROPERTIES WILL_FAIL true _BACKTRACE_TRIPLES \"file1;1;add_test;file0;;\")
+ add_test(ShowOnlyNotAvailable NOT_AVAILABLE)
")
- run_cmake_command(ShowAsJsonVersionOne ${CMAKE_CTEST_COMMAND} --show-only=json-v1)
+ run_cmake_command(show-only_human ${CMAKE_CTEST_COMMAND} --show-only=human)
+ run_cmake_command(show-only_bad ${CMAKE_CTEST_COMMAND} --show-only=bad)
+ run_cmake_command(show-only_json-v1 ${CMAKE_CTEST_COMMAND} --show-only=json-v1)
endfunction()
-run_ShowAsJson()
+run_ShowOnly()
diff --git a/Tests/RunCMake/CTestCommandLine/show-only_bad-result.txt b/Tests/RunCMake/CTestCommandLine/show-only_bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/show-only_bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/show-only_bad-stderr.txt b/Tests/RunCMake/CTestCommandLine/show-only_bad-stderr.txt
new file mode 100644
index 0000000..cc55ab3
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/show-only_bad-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--show-only=' given unknown value 'bad'$
diff --git a/Tests/RunCMake/CTestCommandLine/show-only_human-stdout.txt b/Tests/RunCMake/CTestCommandLine/show-only_human-stdout.txt
new file mode 100644
index 0000000..1332149
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/show-only_human-stdout.txt
@@ -0,0 +1 @@
+Test #1: ShowOnly
diff --git a/Tests/RunCMake/CTestCommandLine/show-only_json-v1-check.cmake b/Tests/RunCMake/CTestCommandLine/show-only_json-v1-check.cmake
new file mode 100644
index 0000000..f9234f8
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/show-only_json-v1-check.cmake
@@ -0,0 +1 @@
+show_only_json_check_python(1)
diff --git a/Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py b/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py
index d794e7d..4dff90c 100644
--- a/Tests/RunCMake/CTestCommandLine/ShowAsJson1-check.py
+++ b/Tests/RunCMake/CTestCommandLine/show-only_json-v1_check.py
@@ -1,4 +1,4 @@
-from ShowAsJson_check import *
+from show_only_json_check import *
def check_kind(k):
assert is_string(k)
@@ -77,7 +77,7 @@ def check_workingdir_property(p):
assert is_string(p["name"])
assert is_string(p["value"])
assert p["name"] == "WORKING_DIRECTORY"
- assert p["value"].endswith("Tests/RunCMake/CTestCommandLine/ShowAsJson")
+ assert p["value"].endswith("Tests/RunCMake/CTestCommandLine/ShowOnly")
def check_properties(p):
assert is_list(p)
@@ -95,7 +95,7 @@ def check_tests(t):
assert test["backtrace"] == 1
check_command(test["command"])
assert is_string(test["name"])
- assert test["name"] == "ShowAsJson"
+ assert test["name"] == "ShowOnly"
check_properties(test["properties"])
assert is_dict(ctest_json)
diff --git a/Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py b/Tests/RunCMake/CTestCommandLine/show_only_json_check.py
index 493c9e5..493c9e5 100644
--- a/Tests/RunCMake/CTestCommandLine/ShowAsJson_check.py
+++ b/Tests/RunCMake/CTestCommandLine/show_only_json_check.py
diff --git a/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake
index 1aeb510..2fdefc4 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake
@@ -26,3 +26,9 @@ get_property(emulator TARGET target_without_emulator
if(NOT "${emulator}" STREQUAL "")
message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set to null")
endif()
+
+add_executable(target_with_empty_emulator simple_src_exiterror.cxx)
+set_property(TARGET target_with_empty_emulator PROPERTY CROSSCOMPILING_EMULATOR "")
+
+enable_testing()
+add_test(NAME test_target_with_empty_emulator COMMAND target_with_empty_emulator)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-stderr.txt
new file mode 100644
index 0000000..fc13248
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-Fortran_COMPILER_ID.cmake:1 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<Fortran_COMPILER_ID>
+
+ \$<Fortran_COMPILER_ID> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID.cmake
new file mode 100644
index 0000000..88a0bfb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_ID.cmake
@@ -0,0 +1,4 @@
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.c" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<Fortran_COMPILER_ID>.c"
+)
+add_custom_target(drive DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-stderr.txt
new file mode 100644
index 0000000..f8a4120
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-Fortran_COMPILER_VERSION.cmake:1 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<Fortran_COMPILER_VERSION>
+
+ \$<Fortran_COMPILER_VERSION> may only be used with binary targets. It may
+ not be used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION.cmake
new file mode 100644
index 0000000..34a4884
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-Fortran_COMPILER_VERSION.cmake
@@ -0,0 +1,4 @@
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.c" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<Fortran_COMPILER_VERSION>.c"
+)
+add_custom_target(drive DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c")
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 013117e..8a5604c 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -15,8 +15,10 @@ run_cmake(BadSHELL_PATH)
run_cmake(CMP0044-WARN)
run_cmake(NonValidTarget-C_COMPILER_ID)
run_cmake(NonValidTarget-CXX_COMPILER_ID)
+run_cmake(NonValidTarget-Fortran_COMPILER_ID)
run_cmake(NonValidTarget-C_COMPILER_VERSION)
run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
+run_cmake(NonValidTarget-Fortran_COMPILER_VERSION)
run_cmake(NonValidTarget-TARGET_BUNDLE_DIR)
run_cmake(NonValidTarget-TARGET_BUNDLE_CONTENT_DIR)
run_cmake(NonValidTarget-TARGET_PROPERTY)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt
index c7f35c5..c9111b0 100644
--- a/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt
+++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt
@@ -1,3 +1,2 @@
-Submit files \(using http\)
- Using HTTP submit method
- Drop site:http://
+Submit files
+ SubmitURL: http://-no-site-
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt
index 19f8234..2c67eb9 100644
--- a/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt
+++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt
@@ -1,3 +1,2 @@
-Submit files \(using https\)
- Using HTTP submit method
- Drop site:https://
+Submit files
+ SubmitURL: https://-no-site-
diff --git a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake b/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake
new file mode 100644
index 0000000..777ef4e
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake
@@ -0,0 +1,11 @@
+# Use COPY_ON_ERROR to handle the case where the source and destination
+# directory are on different devices. Cross-device links are not permitted
+# and the following command falls back to copying the file if link fails.
+file(CREATE_LINK
+ ${CMAKE_CURRENT_LIST_FILE} TestCreateLink.cmake
+ RESULT result
+ COPY_ON_ERROR
+ )
+if(NOT result STREQUAL "0")
+ message(SEND_ERROR "COPY_ON_ERROR failed: '${result}'")
+endif()
diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake
new file mode 100644
index 0000000..61aaf38
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake
@@ -0,0 +1,4 @@
+file(CREATE_LINK does_not_exist.txt TestSymLink.txt RESULT sym_result SYMBOLIC)
+if(NOT sym_result STREQUAL "0")
+ message("Symlink fail: ${sym_result}")
+endif()
diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake
new file mode 100644
index 0000000..77b899c
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake
@@ -0,0 +1,4 @@
+file(CREATE_LINK ${CMAKE_CURRENT_LIST_FILE} TestSymLink.cmake RESULT sym_result SYMBOLIC)
+if(NOT sym_result STREQUAL "0")
+ message(SEND_ERROR "Symlink result='${sym_result}'")
+endif()
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt b/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt
new file mode 100644
index 0000000..12494f8
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CREATE_LINK-noarg\.cmake:[0-9]+ \(file\):
+ file CREATE_LINK must be called with at least two additional arguments
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg.cmake b/Tests/RunCMake/file/CREATE_LINK-noarg.cmake
new file mode 100644
index 0000000..65002fa
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-noarg.cmake
@@ -0,0 +1 @@
+file(CREATE_LINK ${CMAKE_CURRENT_LIST_FILE})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt b/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt
new file mode 100644
index 0000000..97eee4f
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt
@@ -0,0 +1 @@
+Hard link error: Cannot hard link 'does_not_exist.txt' as it does not exist.
diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist.cmake b/Tests/RunCMake/file/CREATE_LINK-noexist.cmake
new file mode 100644
index 0000000..5ee2580
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK-noexist.cmake
@@ -0,0 +1,4 @@
+file(CREATE_LINK does_not_exist.txt TestLink.txt RESULT result)
+if(NOT result STREQUAL "0")
+ message("Hard link error: ${result}")
+endif()
diff --git a/Tests/RunCMake/file/CREATE_LINK.cmake b/Tests/RunCMake/file/CREATE_LINK.cmake
new file mode 100644
index 0000000..ca61646
--- /dev/null
+++ b/Tests/RunCMake/file/CREATE_LINK.cmake
@@ -0,0 +1,11 @@
+# start with a file in the same directory to avoid cross-device links
+set(test_file ${CMAKE_CURRENT_BINARY_DIR}/CreateLinkTest.txt)
+file(TOUCH ${test_file})
+
+file(CREATE_LINK
+ ${test_file} ${CMAKE_CURRENT_BINARY_DIR}/TestCreateLink.txt
+ RESULT result
+ )
+if(NOT result STREQUAL "0")
+ message(SEND_ERROR "Hard link result='${result}'")
+endif()
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index b872824..128e8f3 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+run_cmake(CREATE_LINK)
+run_cmake(CREATE_LINK-COPY_ON_ERROR)
+run_cmake(CREATE_LINK-noarg)
+run_cmake(CREATE_LINK-noexist)
run_cmake(DOWNLOAD-hash-mismatch)
run_cmake(DOWNLOAD-unused-argument)
run_cmake(DOWNLOAD-httpheader-not-set)
@@ -53,6 +57,8 @@ run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P
${RunCMake_SOURCE_DIR}/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake)
if(NOT WIN32 OR CYGWIN)
+ run_cmake(CREATE_LINK-SYMBOLIC)
+ run_cmake(CREATE_LINK-SYMBOLIC-noexist)
run_cmake(GLOB_RECURSE-cyclic-recursion)
run_cmake(INSTALL-SYMLINK)
run_cmake(READ_SYMLINK)
diff --git a/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake b/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake
new file mode 100644
index 0000000..4496a05
--- /dev/null
+++ b/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake
@@ -0,0 +1 @@
+set(Resolved_DIR "${CMAKE_CURRENT_LIST_DIR}")
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index e9f3558..066523e 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -26,3 +26,6 @@ run_cmake(WrongVersionConfig)
run_cmake(CMP0084-OLD)
run_cmake(CMP0084-WARN)
run_cmake(CMP0084-NEW)
+if(UNIX)
+ run_cmake(SetFoundResolved)
+endif()
diff --git a/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt b/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt
new file mode 100644
index 0000000..ea94be5
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning at SetFoundResolved.cmake:10 \(message\):
+ .*/Tests/RunCMake/find_package/symlink
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning at SetFoundResolved.cmake:15 \(message\):
+ .*/Tests/RunCMake/find_package/PackageRoot
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/SetFoundResolved.cmake b/Tests/RunCMake/find_package/SetFoundResolved.cmake
new file mode 100644
index 0000000..8d56513
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundResolved.cmake
@@ -0,0 +1,17 @@
+# Create ./symlink pointing back here.
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
+ PackageRoot "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
+
+# Make find_package search through the symlink.
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
+
+# Test preservation of symlinks.
+find_package(Resolved)
+message(WARNING "${Resolved_DIR}")
+
+# Test resolving symlinks.
+set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS ON)
+find_package(Resolved)
+message(WARNING "${Resolved_DIR}")
+
+file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/symlink")
diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py
index edb5af6..546ae4c 100644
--- a/Tests/Server/cmakelib.py
+++ b/Tests/Server/cmakelib.py
@@ -276,6 +276,10 @@ def validateGlobalSettings(cmakeCommand, cmakeCommandPath, data):
index = cmakeoutput.index('\nGenerators\n\n')
cmakeGenerators = []
for line in cmakeoutput[index + 12:].splitlines():
+ if not line:
+ continue
+ if line[0] == '*': # default generator marker
+ line = ' ' + line[1:]
if not line.startswith(' '):
continue
if line.startswith(' '):
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index aee8a69..482a08d 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -97,7 +97,7 @@
{ include: [ "<json/writer.h>", private, "\"cm_jsoncpp_writer.h\"", public ] },
{ include: [ "<rhash.h>", private, "\"cm_rhash.h\"", public ] },
{ include: [ "<uv.h>", private, "\"cm_uv.h\"", public ] },
- { include: [ "@<uv-.+\\.h>", private, "\"cm_uv.h\"", public ] },
+ { include: [ "@<uv[/-].+\\.h>", private, "\"cm_uv.h\"", public ] },
{ include: [ "<kwiml/abi.h>", private, "\"cm_kwiml.h\"", public ] },
{ include: [ "<kwiml/int.h>", private, "\"cm_kwiml.h\"", public ] },
{ include: [ "<zconf.h>", private, "\"cm_zlib.h\"", public ] },
@@ -114,7 +114,7 @@
{ include: [ "\"cmjsoncpp/include/json/writer.h\"", private, "\"cm_jsoncpp_writer.h\"", public ] },
{ include: [ "\"cmlibrhash/librhash/rhash.h\"", private, "\"cm_rhash.h\"", public ] },
{ include: [ "\"cmlibuv/include/uv.h\"", private, "\"cm_uv.h\"", public ] },
- { include: [ "@\"cmlibuv/include/uv-.+\\.h\"", private, "\"cm_uv.h\"", public ] },
+ { include: [ "@\"cmlibuv/include/uv/.+\\.h\"", private, "\"cm_uv.h\"", public ] },
{ include: [ "\"KWIML/include/kwiml/abi.h\"", private, "\"cm_kwiml.h\"", public ] },
{ include: [ "\"KWIML/include/kwiml/int.h\"", private, "\"cm_kwiml.h\"", public ] },
{ include: [ "\"cmzlib/cm_zlib_mangle.h\"", private, "\"cm_zlib.h\"", public ] },
diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt
index a503041..a62c516 100644
--- a/Utilities/cmlibuv/CMakeLists.txt
+++ b/Utilities/cmlibuv/CMakeLists.txt
@@ -14,16 +14,21 @@ set(uv_libraries ${CMAKE_THREAD_LIBS_INIT})
set(uv_includes include src)
set(uv_headers
include/uv.h
- include/uv-errno.h
- include/uv-threadpool.h
- include/uv-version.h
+ include/uv/errno.h
+ include/uv/threadpool.h
+ include/uv/version.h
)
set(uv_sources
src/fs-poll.c
src/heap-inl.h
+ src/idna.c
+ src/idna.h
src/inet.c
src/queue.h
+ src/strscpy.c
+ src/strscpy.h
src/threadpool.c
+ src/timer.c
src/uv-common.c
src/uv-common.h
src/uv-data-getter-setters.c
@@ -45,7 +50,7 @@ if(WIN32)
_WIN32_WINNT=0x0600
)
list(APPEND uv_headers
- include/uv-win.h
+ include/uv/win.h
include/tree.h
)
list(APPEND uv_sources
@@ -67,7 +72,6 @@ if(WIN32)
src/win/poll.c
src/win/process-stdio.c
src/win/process.c
- src/win/req.c
src/win/req-inl.h
src/win/signal.c
src/win/snprintf.c
@@ -75,7 +79,6 @@ if(WIN32)
src/win/stream-inl.h
src/win/tcp.c
src/win/thread.c
- src/win/timer.c
src/win/tty.c
src/win/udp.c
src/win/util.c
@@ -89,7 +92,7 @@ else()
src/unix
)
list(APPEND uv_headers
- include/uv-unix.h
+ include/uv/unix.h
)
list(APPEND uv_sources
src/unix/async.c
@@ -110,7 +113,6 @@ else()
src/unix/stream.c
src/unix/tcp.c
src/unix/thread.c
- src/unix/timer.c
src/unix/tty.c
src/unix/udp.c
)
@@ -121,7 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
perfstat
)
list(APPEND uv_headers
- include/uv-aix.h
+ include/uv/aix.h
)
list(APPEND uv_defines
_ALL_SOURCE
@@ -139,7 +141,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
list(APPEND uv_libraries
)
list(APPEND uv_headers
- include/uv-posix.h
+ include/uv/posix.h
)
list(APPEND uv_defines
)
@@ -158,8 +160,7 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(APPEND uv_headers
- include/uv-darwin.h
- include/pthread-barrier.h
+ include/uv/darwin.h
)
list(APPEND uv_defines
_DARWIN_USE_64_BIT_INODE=1
@@ -178,7 +179,7 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND uv_libraries dl rt)
list(APPEND uv_headers
- include/uv-linux.h
+ include/uv/linux.h
)
list(APPEND uv_defines _GNU_SOURCE)
list(APPEND uv_sources
@@ -198,10 +199,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
kvm
)
list(APPEND uv_headers
- include/uv-bsd.h
+ include/uv/bsd.h
)
list(APPEND uv_sources
src/unix/bsd-ifaddrs.c
+ src/unix/bsd-proctitle.c
src/unix/freebsd.c
src/unix/kqueue.c
src/unix/posix-hrtime.c
@@ -214,10 +216,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD")
kvm
)
list(APPEND uv_headers
- include/uv-bsd.h
+ include/uv/bsd.h
)
list(APPEND uv_sources
src/unix/bsd-ifaddrs.c
+ src/unix/bsd-proctitle.c
src/unix/freebsd.c
src/unix/kqueue.c
src/unix/posix-hrtime.c
@@ -229,10 +232,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
kvm
)
list(APPEND uv_headers
- include/uv-bsd.h
+ include/uv/bsd.h
)
list(APPEND uv_sources
src/unix/bsd-ifaddrs.c
+ src/unix/bsd-proctitle.c
src/unix/netbsd.c
src/unix/kqueue.c
src/unix/posix-hrtime.c
@@ -244,10 +248,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
kvm
)
list(APPEND uv_headers
- include/uv-bsd.h
+ include/uv/bsd.h
)
list(APPEND uv_sources
src/unix/bsd-ifaddrs.c
+ src/unix/bsd-proctitle.c
src/unix/openbsd.c
src/unix/kqueue.c
src/unix/posix-hrtime.c
@@ -263,7 +268,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
rt
)
list(APPEND uv_headers
- include/uv-sunos.h
+ include/uv/sunos.h
)
list(APPEND uv_defines
__EXTENSIONS__
diff --git a/Utilities/cmlibuv/include/pthread-barrier.h b/Utilities/cmlibuv/include/pthread-barrier.h
deleted file mode 100644
index 07db9b8a..0000000
--- a/Utilities/cmlibuv/include/pthread-barrier.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright (c) 2016, Kari Tristan Helgason <kthelgason@gmail.com>
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#ifndef _UV_PTHREAD_BARRIER_
-#define _UV_PTHREAD_BARRIER_
-#include <errno.h>
-#include <pthread.h>
-#if !defined(__MVS__)
-#include <semaphore.h> /* sem_t */
-#endif
-
-#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345
-#define UV__PTHREAD_BARRIER_FALLBACK 1
-
-/*
- * To maintain ABI compatibility with
- * libuv v1.x struct is padded according
- * to target platform
- */
-#if defined(__ANDROID__)
-# define UV_BARRIER_STRUCT_PADDING \
- sizeof(pthread_mutex_t) + \
- sizeof(pthread_cond_t) + \
- sizeof(unsigned int) - \
- sizeof(void *)
-#elif defined(__APPLE__)
-# define UV_BARRIER_STRUCT_PADDING \
- sizeof(pthread_mutex_t) + \
- 2 * sizeof(sem_t) + \
- 2 * sizeof(unsigned int) - \
- sizeof(void *)
-#else
-# define UV_BARRIER_STRUCT_PADDING 0
-#endif
-
-typedef struct {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- unsigned threshold;
- unsigned in;
- unsigned out;
-} _uv_barrier;
-
-typedef struct {
- _uv_barrier* b;
- char _pad[UV_BARRIER_STRUCT_PADDING];
-} pthread_barrier_t;
-
-int pthread_barrier_init(pthread_barrier_t* barrier,
- const void* barrier_attr,
- unsigned count);
-
-int pthread_barrier_wait(pthread_barrier_t* barrier);
-int pthread_barrier_destroy(pthread_barrier_t *barrier);
-
-#endif /* _UV_PTHREAD_BARRIER_ */
diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h
index 74fa00d..e6dc736 100644
--- a/Utilities/cmlibuv/include/uv.h
+++ b/Utilities/cmlibuv/include/uv.h
@@ -49,21 +49,21 @@ extern "C" {
# define UV_EXTERN /* nothing */
#endif
-#include "uv-errno.h"
-#include "uv-version.h"
+#include "uv/errno.h"
+#include "uv/version.h"
#include <stddef.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
-# include "stdint-msvc2008.h"
+# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#if defined(_WIN32)
-# include "uv-win.h"
+# include "uv/win.h"
#else
-# include "uv-unix.h"
+# include "uv/unix.h"
#endif
/* Expand this list if necessary. */
@@ -146,6 +146,7 @@ extern "C" {
XX(EHOSTDOWN, "host is down") \
XX(EREMOTEIO, "remote I/O error") \
XX(ENOTTY, "inappropriate ioctl for device") \
+ XX(EFTYPE, "inappropriate file type or format") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
@@ -237,6 +238,7 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;
typedef struct uv_passwd_s uv_passwd_t;
+typedef struct uv_utsname_s uv_utsname_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL
@@ -373,7 +375,10 @@ typedef enum {
UV_EXTERN int uv_translate_sys_error(int sys_errno);
UV_EXTERN const char* uv_strerror(int err);
+UV_EXTERN char* uv_strerror_r(int err, char* buf, size_t buflen);
+
UV_EXTERN const char* uv_err_name(int err);
+UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen);
#define UV_REQ_FIELDS \
@@ -507,7 +512,7 @@ UV_EXTERN int uv_try_write(uv_stream_t* handle,
struct uv_write_s {
UV_REQ_FIELDS
uv_write_cb cb;
- uv_stream_t* send_handle;
+ uv_stream_t* send_handle; /* TODO: make private and unix-only in v2.x. */
uv_stream_t* handle;
UV_WRITE_PRIVATE_FIELDS
};
@@ -869,7 +874,13 @@ typedef enum {
* flags may be specified to create a duplex data stream.
*/
UV_READABLE_PIPE = 0x10,
- UV_WRITABLE_PIPE = 0x20
+ UV_WRITABLE_PIPE = 0x20,
+
+ /*
+ * Open the child pipe handle in overlapped mode on Windows.
+ * On Unix it is silently ignored.
+ */
+ UV_OVERLAPPED_PIPE = 0x40
} uv_stdio_flags;
typedef struct uv_stdio_container_s {
@@ -970,11 +981,22 @@ enum uv_process_flags {
*/
UV_PROCESS_DETACHED = (1 << 3),
/*
+ * Hide the subprocess window that would normally be created. This option is
+ * only meaningful on Windows systems. On Unix it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4),
+ /*
* Hide the subprocess console window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
- UV_PROCESS_WINDOWS_HIDE = (1 << 4)
+ UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5),
+ /*
+ * Hide the subprocess GUI window that would normally be created. This
+ * option is only meaningful on Windows systems. On Unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6)
};
/*
@@ -1014,16 +1036,18 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop,
UV_EXTERN int uv_cancel(uv_req_t* req);
+struct uv_cpu_times_s {
+ uint64_t user;
+ uint64_t nice;
+ uint64_t sys;
+ uint64_t idle;
+ uint64_t irq;
+};
+
struct uv_cpu_info_s {
char* model;
int speed;
- struct uv_cpu_times_s {
- uint64_t user;
- uint64_t nice;
- uint64_t sys;
- uint64_t idle;
- uint64_t irq;
- } cpu_times;
+ struct uv_cpu_times_s cpu_times;
};
struct uv_interface_address_s {
@@ -1048,6 +1072,16 @@ struct uv_passwd_s {
char* homedir;
};
+struct uv_utsname_s {
+ char sysname[256];
+ char release[256];
+ char version[256];
+ char machine[256];
+ /* This struct does not contain the nodename and domainname fields present in
+ the utsname type. domainname is a GNU extension. Both fields are referred
+ to as meaningless in the docs. */
+};
+
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
@@ -1070,6 +1104,7 @@ UV_EXTERN int uv_set_process_title(const char* title);
UV_EXTERN int uv_resident_set_memory(size_t* rss);
UV_EXTERN int uv_uptime(double* uptime);
UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd);
+UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd);
typedef struct {
long tv_sec;
@@ -1104,6 +1139,16 @@ UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
UV_EXTERN uv_pid_t uv_os_getpid(void);
UV_EXTERN uv_pid_t uv_os_getppid(void);
+#define UV_PRIORITY_LOW 19
+#define UV_PRIORITY_BELOW_NORMAL 10
+#define UV_PRIORITY_NORMAL 0
+#define UV_PRIORITY_ABOVE_NORMAL -7
+#define UV_PRIORITY_HIGH -14
+#define UV_PRIORITY_HIGHEST -20
+
+UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
+UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
+
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
UV_EXTERN int uv_cpumask_size(void);
@@ -1119,6 +1164,8 @@ UV_EXTERN int uv_os_unsetenv(const char* name);
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
+UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);
+
typedef enum {
UV_FS_UNKNOWN = -1,
@@ -1151,7 +1198,8 @@ typedef enum {
UV_FS_CHOWN,
UV_FS_FCHOWN,
UV_FS_REALPATH,
- UV_FS_COPYFILE
+ UV_FS_COPYFILE,
+ UV_FS_LCHOWN
} uv_fs_type;
/* uv_fs_t is a subclass of uv_req_t. */
@@ -1354,6 +1402,12 @@ UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb);
+UV_EXTERN int uv_fs_lchown(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb);
enum uv_fs_event {
diff --git a/Utilities/cmlibuv/include/uv-aix.h b/Utilities/cmlibuv/include/uv/aix.h
index 7dc992f..7dc992f 100644
--- a/Utilities/cmlibuv/include/uv-aix.h
+++ b/Utilities/cmlibuv/include/uv/aix.h
diff --git a/Utilities/cmlibuv/include/android-ifaddrs.h b/Utilities/cmlibuv/include/uv/android-ifaddrs.h
index 9cd19fe..9cd19fe 100644
--- a/Utilities/cmlibuv/include/android-ifaddrs.h
+++ b/Utilities/cmlibuv/include/uv/android-ifaddrs.h
diff --git a/Utilities/cmlibuv/include/uv-bsd.h b/Utilities/cmlibuv/include/uv/bsd.h
index 2d72b3d..2d72b3d 100644
--- a/Utilities/cmlibuv/include/uv-bsd.h
+++ b/Utilities/cmlibuv/include/uv/bsd.h
diff --git a/Utilities/cmlibuv/include/uv-darwin.h b/Utilities/cmlibuv/include/uv/darwin.h
index d226415..d226415 100644
--- a/Utilities/cmlibuv/include/uv-darwin.h
+++ b/Utilities/cmlibuv/include/uv/darwin.h
diff --git a/Utilities/cmlibuv/include/uv-errno.h b/Utilities/cmlibuv/include/uv/errno.h
index aa4d450..8eeb95d 100644
--- a/Utilities/cmlibuv/include/uv-errno.h
+++ b/Utilities/cmlibuv/include/uv/errno.h
@@ -433,5 +433,11 @@
# define UV__ENOTTY (-4029)
#endif
+#if defined(EFTYPE) && !defined(_WIN32)
+# define UV__EFTYPE UV__ERR(EFTYPE)
+#else
+# define UV__EFTYPE (-4028)
+#endif
+
#endif /* UV_ERRNO_H_ */
diff --git a/Utilities/cmlibuv/include/uv-linux.h b/Utilities/cmlibuv/include/uv/linux.h
index 9b38405..9b38405 100644
--- a/Utilities/cmlibuv/include/uv-linux.h
+++ b/Utilities/cmlibuv/include/uv/linux.h
diff --git a/Utilities/cmlibuv/include/uv-os390.h b/Utilities/cmlibuv/include/uv/os390.h
index 0267d74..0267d74 100644
--- a/Utilities/cmlibuv/include/uv-os390.h
+++ b/Utilities/cmlibuv/include/uv/os390.h
diff --git a/Utilities/cmlibuv/include/uv-posix.h b/Utilities/cmlibuv/include/uv/posix.h
index 9a96634..9a96634 100644
--- a/Utilities/cmlibuv/include/uv-posix.h
+++ b/Utilities/cmlibuv/include/uv/posix.h
diff --git a/Utilities/cmlibuv/include/stdint-msvc2008.h b/Utilities/cmlibuv/include/uv/stdint-msvc2008.h
index d02608a..d02608a 100644
--- a/Utilities/cmlibuv/include/stdint-msvc2008.h
+++ b/Utilities/cmlibuv/include/uv/stdint-msvc2008.h
diff --git a/Utilities/cmlibuv/include/uv-sunos.h b/Utilities/cmlibuv/include/uv/sunos.h
index 0421664..0421664 100644
--- a/Utilities/cmlibuv/include/uv-sunos.h
+++ b/Utilities/cmlibuv/include/uv/sunos.h
diff --git a/Utilities/cmlibuv/include/uv-threadpool.h b/Utilities/cmlibuv/include/uv/threadpool.h
index 9708ebd..9708ebd 100644
--- a/Utilities/cmlibuv/include/uv-threadpool.h
+++ b/Utilities/cmlibuv/include/uv/threadpool.h
diff --git a/Utilities/cmlibuv/include/tree.h b/Utilities/cmlibuv/include/uv/tree.h
index f936416..f936416 100644
--- a/Utilities/cmlibuv/include/tree.h
+++ b/Utilities/cmlibuv/include/uv/tree.h
diff --git a/Utilities/cmlibuv/include/uv-unix.h b/Utilities/cmlibuv/include/uv/unix.h
index 455674d..3c1b363 100644
--- a/Utilities/cmlibuv/include/uv-unix.h
+++ b/Utilities/cmlibuv/include/uv/unix.h
@@ -42,34 +42,32 @@
#include <pthread.h>
#include <signal.h>
-#include "uv-threadpool.h"
+#include "threadpool.h"
#ifdef CMAKE_BOOTSTRAP
-# include "uv-posix.h"
+# include "posix.h"
#elif defined(__linux__)
-# include "uv-linux.h"
+# include "linux.h"
#elif defined (__MVS__)
-# include "uv-os390.h"
+# include "os390.h"
#elif defined(__PASE__)
-# include "uv-posix.h"
+# include "posix.h"
#elif defined(_AIX)
-# include "uv-aix.h"
+# include "aix.h"
#elif defined(__sun)
-# include "uv-sunos.h"
+# include "sunos.h"
#elif defined(__APPLE__)
-# include "uv-darwin.h"
+# include "darwin.h"
#elif defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
-# include "uv-bsd.h"
+# include "bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__)
-# include "uv-posix.h"
-#endif
-
-#ifndef PTHREAD_BARRIER_SERIAL_THREAD
-# include "pthread-barrier.h"
+# include "posix.h"
+#elif defined(__GNU__)
+# include "posix.h"
#endif
#ifndef NI_MAXHOST
@@ -149,9 +147,30 @@ typedef pthread_rwlock_t uv_rwlock_t;
typedef UV_PLATFORM_SEM_T uv_sem_t;
typedef pthread_cond_t uv_cond_t;
typedef pthread_key_t uv_key_t;
+
+/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */
+#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */
+struct _uv_barrier {
+ uv_mutex_t mutex;
+ uv_cond_t cond;
+ unsigned threshold;
+ unsigned in;
+ unsigned out;
+};
+
+typedef struct {
+ struct _uv_barrier* b;
+# if defined(PTHREAD_BARRIER_SERIAL_THREAD)
+ /* TODO(bnoordhuis) Remove padding in v2. */
+ char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)];
+# endif
+} uv_barrier_t;
+#else
typedef pthread_barrier_t uv_barrier_t;
#endif
+#endif
/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;
diff --git a/Utilities/cmlibuv/include/uv-version.h b/Utilities/cmlibuv/include/uv/version.h
index 06c6711..abc140a 100644
--- a/Utilities/cmlibuv/include/uv-version.h
+++ b/Utilities/cmlibuv/include/uv/version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 20
-#define UV_VERSION_PATCH 3
+#define UV_VERSION_MINOR 24
+#define UV_VERSION_PATCH 2
#define UV_VERSION_IS_RELEASE 0
#define UV_VERSION_SUFFIX "dev"
diff --git a/Utilities/cmlibuv/include/uv-win.h b/Utilities/cmlibuv/include/uv/win.h
index 6486aab..f3d3809 100644
--- a/Utilities/cmlibuv/include/uv-win.h
+++ b/Utilities/cmlibuv/include/uv/win.h
@@ -25,6 +25,7 @@
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
typedef intptr_t ssize_t;
+# define SSIZE_MAX INTPTR_MAX
# define _SSIZE_T_
# define _SSIZE_T_DEFINED
#endif
@@ -59,7 +60,7 @@ typedef struct pollfd {
#endif
#include "tree.h"
-#include "uv-threadpool.h"
+#include "threadpool.h"
#define MAX_PIPENAME_LEN 256
@@ -86,8 +87,16 @@ typedef struct pollfd {
#define SIGKILL 9
#define SIGWINCH 28
-/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */
-/* unix-like platforms. However MinGW doesn't define it, so we do. */
+/* Redefine NSIG to take SIGWINCH into consideration */
+#if defined(NSIG) && NSIG <= SIGWINCH
+# undef NSIG
+#endif
+#ifndef NSIG
+# define NSIG SIGWINCH + 1
+#endif
+
+/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like
+ * platforms. However MinGW doesn't define it, so we do. */
#ifndef SIGABRT_COMPAT
# define SIGABRT_COMPAT 6
#endif
@@ -255,7 +264,7 @@ typedef union {
CRITICAL_SECTION waiters_count_lock;
HANDLE signal_event;
HANDLE broadcast_event;
- } fallback;
+ } unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
} uv_cond_t;
typedef union {
@@ -319,8 +328,6 @@ typedef struct {
char* errmsg;
} uv_lib_t;
-RB_HEAD(uv_timer_tree_s, uv_timer_s);
-
#define UV_LOOP_PRIVATE_FIELDS \
/* The loop's I/O completion port */ \
HANDLE iocp; \
@@ -332,8 +339,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
uv_req_t* pending_reqs_tail; \
/* Head of a single-linked list of closed handles */ \
uv_handle_t* endgame_handles; \
- /* The head of the timers tree */ \
- struct uv_timer_tree_s timers; \
+ /* TODO(bnoordhuis) Stop heap-allocating |timer_heap| in libuv v2.x. */ \
+ void* timer_heap; \
/* Lists of active loop (prepare / check / idle) watchers */ \
uv_prepare_t* prepare_handles; \
uv_check_t* check_handles; \
@@ -379,10 +386,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
} u; \
struct uv_req_s* next_req;
-#define UV_WRITE_PRIVATE_FIELDS \
- int ipc_header; \
- uv_buf_t write_buffer; \
- HANDLE event_handle; \
+#define UV_WRITE_PRIVATE_FIELDS \
+ int coalesced; \
+ uv_buf_t write_buffer; \
+ HANDLE event_handle; \
HANDLE wait_handle;
#define UV_CONNECT_PRIVATE_FIELDS \
@@ -470,16 +477,17 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define uv_pipe_connection_fields \
uv_timer_t* eof_timer; \
- uv_write_t ipc_header_write_req; \
- int ipc_pid; \
- uint64_t remaining_ipc_rawdata_bytes; \
- struct { \
- void* queue[2]; \
- int queue_len; \
- } pending_ipc_info; \
+ uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
+ DWORD ipc_remote_pid; \
+ union { \
+ uint32_t payload_remaining; \
+ uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
+ } ipc_data_frame; \
+ void* ipc_xfer_queue[2]; \
+ int ipc_xfer_queue_length; \
uv_write_t* non_overlapped_writes_tail; \
- uv_mutex_t readfile_mutex; \
- volatile HANDLE readfile_thread;
+ CRITICAL_SECTION readfile_thread_lock; \
+ volatile HANDLE readfile_thread_handle;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
@@ -489,8 +497,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { uv_pipe_connection_fields } conn; \
} pipe;
-/* TODO: put the parser states in an union - TTY handles are always */
-/* half-duplex so read-state can safely overlap write-state. */
+/* TODO: put the parser states in an union - TTY handles are always half-duplex
+ * so read-state can safely overlap write-state. */
#define UV_TTY_PRIVATE_FIELDS \
HANDLE handle; \
union { \
@@ -539,8 +547,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned char events;
#define UV_TIMER_PRIVATE_FIELDS \
- RB_ENTRY(uv_timer_s) tree_entry; \
- uint64_t due; \
+ void* heap_node[3]; \
+ int unused; \
+ uint64_t timeout; \
uint64_t repeat; \
uint64_t start_id; \
uv_timer_cb timer_cb;
diff --git a/Utilities/cmlibuv/src/fs-poll.c b/Utilities/cmlibuv/src/fs-poll.c
index ee73d5a..6c82dfc 100644
--- a/Utilities/cmlibuv/src/fs-poll.c
+++ b/Utilities/cmlibuv/src/fs-poll.c
@@ -83,7 +83,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
if (err < 0)
goto error;
- ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
+ ctx->timer_handle.flags |= UV_HANDLE_INTERNAL;
uv__handle_unref(&ctx->timer_handle);
err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb);
@@ -248,7 +248,7 @@ static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) {
#include "win/handle-inl.h"
void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) {
- assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(handle->flags & UV_HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
uv__handle_close(handle);
}
diff --git a/Utilities/cmlibuv/src/idna.c b/Utilities/cmlibuv/src/idna.c
new file mode 100644
index 0000000..13ffac6
--- /dev/null
+++ b/Utilities/cmlibuv/src/idna.c
@@ -0,0 +1,291 @@
+/* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Derived from https://github.com/bnoordhuis/punycode
+ * but updated to support IDNA 2008.
+ */
+
+#include "uv.h"
+#include "idna.h"
+#include <string.h>
+
+static unsigned uv__utf8_decode1_slow(const char** p,
+ const char* pe,
+ unsigned a) {
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned min;
+
+ if (a > 0xF7)
+ return -1;
+
+ switch (*p - pe) {
+ default:
+ if (a > 0xEF) {
+ min = 0x10000;
+ a = a & 7;
+ b = (unsigned char) *(*p)++;
+ c = (unsigned char) *(*p)++;
+ d = (unsigned char) *(*p)++;
+ break;
+ }
+ /* Fall through. */
+ case 2:
+ if (a > 0xDF) {
+ min = 0x800;
+ b = 0x80 | (a & 15);
+ c = (unsigned char) *(*p)++;
+ d = (unsigned char) *(*p)++;
+ a = 0;
+ break;
+ }
+ /* Fall through. */
+ case 1:
+ if (a > 0xBF) {
+ min = 0x80;
+ b = 0x80;
+ c = 0x80 | (a & 31);
+ d = (unsigned char) *(*p)++;
+ a = 0;
+ break;
+ }
+ return -1; /* Invalid continuation byte. */
+ }
+
+ if (0x80 != (0xC0 & (b ^ c ^ d)))
+ return -1; /* Invalid sequence. */
+
+ b &= 63;
+ c &= 63;
+ d &= 63;
+ a = (a << 18) | (b << 12) | (c << 6) | d;
+
+ if (a < min)
+ return -1; /* Overlong sequence. */
+
+ if (a > 0x10FFFF)
+ return -1; /* Four-byte sequence > U+10FFFF. */
+
+ if (a >= 0xD800 && a <= 0xDFFF)
+ return -1; /* Surrogate pair. */
+
+ return a;
+}
+
+unsigned uv__utf8_decode1(const char** p, const char* pe) {
+ unsigned a;
+
+ a = (unsigned char) *(*p)++;
+
+ if (a < 128)
+ return a; /* ASCII, common case. */
+
+ return uv__utf8_decode1_slow(p, pe, a);
+}
+
+#define foreach_codepoint(c, p, pe) \
+ for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;)
+
+static int uv__idna_toascii_label(const char* s, const char* se,
+ char** d, char* de) {
+ static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+ const char* ss;
+ unsigned c;
+ unsigned h;
+ unsigned k;
+ unsigned n;
+ unsigned m;
+ unsigned q;
+ unsigned t;
+ unsigned x;
+ unsigned y;
+ unsigned bias;
+ unsigned delta;
+ unsigned todo;
+ int first;
+
+ h = 0;
+ ss = s;
+ todo = 0;
+
+ foreach_codepoint(c, &s, se) {
+ if (c < 128)
+ h++;
+ else if (c == (unsigned) -1)
+ return UV_EINVAL;
+ else
+ todo++;
+ }
+
+ if (todo > 0) {
+ if (*d < de) *(*d)++ = 'x';
+ if (*d < de) *(*d)++ = 'n';
+ if (*d < de) *(*d)++ = '-';
+ if (*d < de) *(*d)++ = '-';
+ }
+
+ x = 0;
+ s = ss;
+ foreach_codepoint(c, &s, se) {
+ if (c > 127)
+ continue;
+
+ if (*d < de)
+ *(*d)++ = c;
+
+ if (++x == h)
+ break; /* Visited all ASCII characters. */
+ }
+
+ if (todo == 0)
+ return h;
+
+ /* Only write separator when we've written ASCII characters first. */
+ if (h > 0)
+ if (*d < de)
+ *(*d)++ = '-';
+
+ n = 128;
+ bias = 72;
+ delta = 0;
+ first = 1;
+
+ while (todo > 0) {
+ m = -1;
+ s = ss;
+ foreach_codepoint(c, &s, se)
+ if (c >= n)
+ if (c < m)
+ m = c;
+
+ x = m - n;
+ y = h + 1;
+
+ if (x > ~delta / y)
+ return UV_E2BIG; /* Overflow. */
+
+ delta += x * y;
+ n = m;
+
+ s = ss;
+ foreach_codepoint(c, &s, se) {
+ if (c < n)
+ if (++delta == 0)
+ return UV_E2BIG; /* Overflow. */
+
+ if (c != n)
+ continue;
+
+ for (k = 36, q = delta; /* empty */; k += 36) {
+ t = 1;
+
+ if (k > bias)
+ t = k - bias;
+
+ if (t > 26)
+ t = 26;
+
+ if (q < t)
+ break;
+
+ /* TODO(bnoordhuis) Since 1 <= t <= 26 and therefore
+ * 10 <= y <= 35, we can optimize the long division
+ * into a table-based reciprocal multiplication.
+ */
+ x = q - t;
+ y = 36 - t; /* 10 <= y <= 35 since 1 <= t <= 26. */
+ q = x / y;
+ t = t + x % y; /* 1 <= t <= 35 because of y. */
+
+ if (*d < de)
+ *(*d)++ = alphabet[t];
+ }
+
+ if (*d < de)
+ *(*d)++ = alphabet[q];
+
+ delta /= 2;
+
+ if (first) {
+ delta /= 350;
+ first = 0;
+ }
+
+ /* No overflow check is needed because |delta| was just
+ * divided by 2 and |delta+delta >= delta + delta/h|.
+ */
+ h++;
+ delta += delta / h;
+
+ for (bias = 0; delta > 35 * 26 / 2; bias += 36)
+ delta /= 35;
+
+ bias += 36 * delta / (delta + 38);
+ delta = 0;
+ todo--;
+ }
+
+ delta++;
+ n++;
+ }
+
+ return 0;
+}
+
+#undef foreach_codepoint
+
+long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
+ const char* si;
+ const char* st;
+ unsigned c;
+ char* ds;
+ int rc;
+
+ ds = d;
+
+ for (si = s; si < se; /* empty */) {
+ st = si;
+ c = uv__utf8_decode1(&si, se);
+
+ if (c != '.')
+ if (c != 0x3002) /* 。 */
+ if (c != 0xFF0E) /* . */
+ if (c != 0xFF61) /* 。 */
+ continue;
+
+ rc = uv__idna_toascii_label(s, st, &d, de);
+
+ if (rc < 0)
+ return rc;
+
+ if (d < de)
+ *d++ = '.';
+
+ s = si;
+ }
+
+ if (s < se) {
+ rc = uv__idna_toascii_label(s, se, &d, de);
+
+ if (rc < 0)
+ return rc;
+ }
+
+ if (d < de)
+ *d++ = '\0';
+
+ return d - ds; /* Number of bytes written. */
+}
diff --git a/Utilities/cmlibuv/src/idna.h b/Utilities/cmlibuv/src/idna.h
new file mode 100644
index 0000000..8e0c592
--- /dev/null
+++ b/Utilities/cmlibuv/src/idna.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef UV_SRC_IDNA_H_
+#define UV_SRC_IDNA_H_
+
+/* Decode a single codepoint. Returns the codepoint or UINT32_MAX on error.
+ * |p| is updated on success _and_ error, i.e., bad multi-byte sequences are
+ * skipped in their entirety, not just the first bad byte.
+ */
+unsigned uv__utf8_decode1(const char** p, const char* pe);
+
+/* Convert a UTF-8 domain name to IDNA 2008 / Punycode. A return value >= 0
+ * is the number of bytes written to |d|, including the trailing nul byte.
+ * A return value < 0 is a libuv error code. |s| and |d| can not overlap.
+ */
+long uv__idna_toascii(const char* s, const char* se, char* d, char* de);
+
+#endif /* UV_SRC_IDNA_H_ */
diff --git a/Utilities/cmlibuv/src/inet.c b/Utilities/cmlibuv/src/inet.c
index 7c75e43..58238dc 100644
--- a/Utilities/cmlibuv/src/inet.c
+++ b/Utilities/cmlibuv/src/inet.c
@@ -22,7 +22,7 @@
#include <string.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
-# include "stdint-msvc2008.h"
+# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
@@ -59,8 +59,7 @@ static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
if (l <= 0 || (size_t) l >= size) {
return UV_ENOSPC;
}
- strncpy(dst, tmp, size);
- dst[size - 1] = '\0';
+ uv__strscpy(dst, tmp, size);
return 0;
}
@@ -142,14 +141,8 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
*tp++ = ':';
*tp++ = '\0';
-
- /*
- * Check for overflow, copy, and we're done.
- */
- if ((size_t)(tp - tmp) > size) {
+ if (UV_E2BIG == uv__strscpy(dst, tmp, size))
return UV_ENOSPC;
- }
- strcpy(dst, tmp);
return 0;
}
diff --git a/Utilities/cmlibuv/src/strscpy.c b/Utilities/cmlibuv/src/strscpy.c
new file mode 100644
index 0000000..2a2bdce
--- /dev/null
+++ b/Utilities/cmlibuv/src/strscpy.c
@@ -0,0 +1,17 @@
+#include "strscpy.h"
+#include <limits.h> /* SSIZE_MAX */
+
+ssize_t uv__strscpy(char* d, const char* s, size_t n) {
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ if ('\0' == (d[i] = s[i]))
+ return i > SSIZE_MAX ? UV_E2BIG : (ssize_t) i;
+
+ if (i == 0)
+ return 0;
+
+ d[--i] = '\0';
+
+ return UV_E2BIG;
+}
diff --git a/Utilities/cmlibuv/src/strscpy.h b/Utilities/cmlibuv/src/strscpy.h
new file mode 100644
index 0000000..fbe0a39
--- /dev/null
+++ b/Utilities/cmlibuv/src/strscpy.h
@@ -0,0 +1,18 @@
+#ifndef UV_STRSCPY_H_
+#define UV_STRSCPY_H_
+
+/* Include uv.h for its definitions of size_t and ssize_t.
+ * size_t can be obtained directly from <stddef.h> but ssize_t requires
+ * some hoop jumping on Windows that I didn't want to duplicate here.
+ */
+#include "uv.h"
+
+/* Copies up to |n-1| bytes from |d| to |s| and always zero-terminates
+ * the result, except when |n==0|. Returns the number of bytes copied
+ * or UV_E2BIG if |d| is too small.
+ *
+ * See https://www.kernel.org/doc/htmldocs/kernel-api/API-strscpy.html
+ */
+ssize_t uv__strscpy(char* d, const char* s, size_t n);
+
+#endif /* UV_STRSCPY_H_ */
diff --git a/Utilities/cmlibuv/src/threadpool.c b/Utilities/cmlibuv/src/threadpool.c
index 413d1c2..4258933 100644
--- a/Utilities/cmlibuv/src/threadpool.c
+++ b/Utilities/cmlibuv/src/threadpool.c
@@ -33,12 +33,18 @@ static uv_once_t once = UV_ONCE_INIT;
static uv_cond_t cond;
static uv_mutex_t mutex;
static unsigned int idle_threads;
+static unsigned int slow_io_work_running;
static unsigned int nthreads;
static uv_thread_t* threads;
static uv_thread_t default_threads[4];
static QUEUE exit_message;
static QUEUE wq;
+static QUEUE run_slow_work_message;
+static QUEUE slow_io_pending_wq;
+static unsigned int slow_work_thread_threshold(void) {
+ return (nthreads + 1) / 2;
+}
static void uv__cancelled(struct uv__work* w) {
abort();
@@ -51,34 +57,67 @@ static void uv__cancelled(struct uv__work* w) {
static void worker(void* arg) {
struct uv__work* w;
QUEUE* q;
+ int is_slow_work;
uv_sem_post((uv_sem_t*) arg);
arg = NULL;
+ uv_mutex_lock(&mutex);
for (;;) {
- uv_mutex_lock(&mutex);
-
- while (QUEUE_EMPTY(&wq)) {
+ /* `mutex` should always be locked at this point. */
+
+ /* Keep waiting while either no work is present or only slow I/O
+ and we're at the threshold for that. */
+ while (QUEUE_EMPTY(&wq) ||
+ (QUEUE_HEAD(&wq) == &run_slow_work_message &&
+ QUEUE_NEXT(&run_slow_work_message) == &wq &&
+ slow_io_work_running >= slow_work_thread_threshold())) {
idle_threads += 1;
uv_cond_wait(&cond, &mutex);
idle_threads -= 1;
}
q = QUEUE_HEAD(&wq);
-
- if (q == &exit_message)
+ if (q == &exit_message) {
uv_cond_signal(&cond);
- else {
+ uv_mutex_unlock(&mutex);
+ break;
+ }
+
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q); /* Signal uv_cancel() that the work req is executing. */
+
+ is_slow_work = 0;
+ if (q == &run_slow_work_message) {
+ /* If we're at the slow I/O threshold, re-schedule until after all
+ other work in the queue is done. */
+ if (slow_io_work_running >= slow_work_thread_threshold()) {
+ QUEUE_INSERT_TAIL(&wq, q);
+ continue;
+ }
+
+ /* If we encountered a request to run slow I/O work but there is none
+ to run, that means it's cancelled => Start over. */
+ if (QUEUE_EMPTY(&slow_io_pending_wq))
+ continue;
+
+ is_slow_work = 1;
+ slow_io_work_running++;
+
+ q = QUEUE_HEAD(&slow_io_pending_wq);
QUEUE_REMOVE(q);
- QUEUE_INIT(q); /* Signal uv_cancel() that the work req is
- executing. */
+ QUEUE_INIT(q);
+
+ /* If there is more slow I/O work, schedule it to be run as well. */
+ if (!QUEUE_EMPTY(&slow_io_pending_wq)) {
+ QUEUE_INSERT_TAIL(&wq, &run_slow_work_message);
+ if (idle_threads > 0)
+ uv_cond_signal(&cond);
+ }
}
uv_mutex_unlock(&mutex);
- if (q == &exit_message)
- break;
-
w = QUEUE_DATA(q, struct uv__work, wq);
w->work(w);
@@ -88,12 +127,32 @@ static void worker(void* arg) {
QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq);
uv_async_send(&w->loop->wq_async);
uv_mutex_unlock(&w->loop->wq_mutex);
+
+ /* Lock `mutex` since that is expected at the start of the next
+ * iteration. */
+ uv_mutex_lock(&mutex);
+ if (is_slow_work) {
+ /* `slow_io_work_running` is protected by `mutex`. */
+ slow_io_work_running--;
+ }
}
}
-static void post(QUEUE* q) {
+static void post(QUEUE* q, enum uv__work_kind kind) {
uv_mutex_lock(&mutex);
+ if (kind == UV__WORK_SLOW_IO) {
+ /* Insert into a separate queue. */
+ QUEUE_INSERT_TAIL(&slow_io_pending_wq, q);
+ if (!QUEUE_EMPTY(&run_slow_work_message)) {
+ /* Running slow I/O tasks is already scheduled => Nothing to do here.
+ The worker that runs said other task will schedule this one as well. */
+ uv_mutex_unlock(&mutex);
+ return;
+ }
+ q = &run_slow_work_message;
+ }
+
QUEUE_INSERT_TAIL(&wq, q);
if (idle_threads > 0)
uv_cond_signal(&cond);
@@ -108,7 +167,7 @@ UV_DESTRUCTOR(static void cleanup(void)) {
if (nthreads == 0)
return;
- post(&exit_message);
+ post(&exit_message, UV__WORK_CPU);
for (i = 0; i < nthreads; i++)
if (uv_thread_join(threads + i))
@@ -156,6 +215,8 @@ static void init_threads(void) {
abort();
QUEUE_INIT(&wq);
+ QUEUE_INIT(&slow_io_pending_wq);
+ QUEUE_INIT(&run_slow_work_message);
if (uv_sem_init(&sem, 0))
abort();
@@ -194,13 +255,14 @@ static void init_once(void) {
void uv__work_submit(uv_loop_t* loop,
struct uv__work* w,
+ enum uv__work_kind kind,
void (*work)(struct uv__work* w),
void (*done)(struct uv__work* w, int status)) {
uv_once(&once, init_once);
w->loop = loop;
w->work = work;
w->done = done;
- post(&w->wq);
+ post(&w->wq, kind);
}
@@ -284,7 +346,11 @@ int uv_queue_work(uv_loop_t* loop,
req->loop = loop;
req->work_cb = work_cb;
req->after_work_cb = after_work_cb;
- uv__work_submit(loop, &req->work_req, uv__queue_work, uv__queue_done);
+ uv__work_submit(loop,
+ &req->work_req,
+ UV__WORK_CPU,
+ uv__queue_work,
+ uv__queue_done);
return 0;
}
diff --git a/Utilities/cmlibuv/src/unix/timer.c b/Utilities/cmlibuv/src/timer.c
index 54dabfe..dd78bcb 100644
--- a/Utilities/cmlibuv/src/unix/timer.c
+++ b/Utilities/cmlibuv/src/timer.c
@@ -19,13 +19,22 @@
*/
#include "uv.h"
-#include "internal.h"
+#include "uv-common.h"
#include "heap-inl.h"
#include <assert.h>
#include <limits.h>
+static struct heap *timer_heap(const uv_loop_t* loop) {
+#ifdef _WIN32
+ return (struct heap*) loop->timer_heap;
+#else
+ return (struct heap*) &loop->timer_heap;
+#endif
+}
+
+
static int timer_less_than(const struct heap_node* ha,
const struct heap_node* hb) {
const uv_timer_t* a;
@@ -81,7 +90,7 @@ int uv_timer_start(uv_timer_t* handle,
/* start_id is the second index to be compared in uv__timer_cmp() */
handle->start_id = handle->loop->timer_counter++;
- heap_insert((struct heap*) &handle->loop->timer_heap,
+ heap_insert(timer_heap(handle->loop),
(struct heap_node*) &handle->heap_node,
timer_less_than);
uv__handle_start(handle);
@@ -94,7 +103,7 @@ int uv_timer_stop(uv_timer_t* handle) {
if (!uv__is_active(handle))
return 0;
- heap_remove((struct heap*) &handle->loop->timer_heap,
+ heap_remove(timer_heap(handle->loop),
(struct heap_node*) &handle->heap_node,
timer_less_than);
uv__handle_stop(handle);
@@ -131,7 +140,7 @@ int uv__next_timeout(const uv_loop_t* loop) {
const uv_timer_t* handle;
uint64_t diff;
- heap_node = heap_min((const struct heap*) &loop->timer_heap);
+ heap_node = heap_min(timer_heap(loop));
if (heap_node == NULL)
return -1; /* block indefinitely */
@@ -143,7 +152,7 @@ int uv__next_timeout(const uv_loop_t* loop) {
if (diff > INT_MAX)
diff = INT_MAX;
- return diff;
+ return (int) diff;
}
@@ -152,7 +161,7 @@ void uv__run_timers(uv_loop_t* loop) {
uv_timer_t* handle;
for (;;) {
- heap_node = heap_min((struct heap*) &loop->timer_heap);
+ heap_node = heap_min(timer_heap(loop));
if (heap_node == NULL)
break;
diff --git a/Utilities/cmlibuv/src/unix/aix-common.c b/Utilities/cmlibuv/src/unix/aix-common.c
index 9c11c5d..e9697e9 100644
--- a/Utilities/cmlibuv/src/unix/aix-common.c
+++ b/Utilities/cmlibuv/src/unix/aix-common.c
@@ -166,8 +166,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
}
-int uv_interface_addresses(uv_interface_address_t** addresses,
- int* count) {
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int sockfd, inet6, size = 1;
struct ifconf ifc;
@@ -175,6 +174,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
struct sockaddr_dl* sa_addr;
*count = 0;
+ *addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
return UV__ERR(errno);
@@ -217,6 +217,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
+ if (*count == 0) {
+ uv__close(sockfd);
+ return 0;
+ }
+
/* Alloc the return interface structs */
*addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
if (!(*addresses)) {
@@ -290,3 +295,4 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
uv__free(addresses);
}
+
diff --git a/Utilities/cmlibuv/src/unix/aix.c b/Utilities/cmlibuv/src/unix/aix.c
index 92de814..337e58e 100644
--- a/Utilities/cmlibuv/src/unix/aix.c
+++ b/Utilities/cmlibuv/src/unix/aix.c
@@ -358,19 +358,15 @@ void uv_loadavg(double avg[3]) {
#ifdef HAVE_SYS_AHAFS_EVPRODS_H
-static char *uv__rawname(char *cp) {
- static char rawbuf[FILENAME_MAX+1];
- char *dp = rindex(cp, '/');
+static char* uv__rawname(const char* cp, char (*dst)[FILENAME_MAX+1]) {
+ char* dp;
+ dp = rindex(cp, '/');
if (dp == 0)
return 0;
- *dp = 0;
- strcpy(rawbuf, cp);
- *dp = '/';
- strcat(rawbuf, "/r");
- strcat(rawbuf, dp+1);
- return rawbuf;
+ snprintf(*dst, sizeof(*dst), "%.*s/r%s", (int) (dp - cp), cp, dp + 1);
+ return *dst;
}
@@ -399,6 +395,7 @@ static int uv__path_is_a_directory(char* filename) {
* Returns 0 if AHAFS is mounted, or an error code < 0 on failure
*/
static int uv__is_ahafs_mounted(void){
+ char rawbuf[FILENAME_MAX+1];
int rv, i = 2;
struct vmount *p;
int size_multiplier = 10;
@@ -432,7 +429,7 @@ static int uv__is_ahafs_mounted(void){
obj = vmt2dataptr(vmt, VMT_OBJECT); /* device */
stub = vmt2dataptr(vmt, VMT_STUB); /* mount point */
- if (EQ(obj, dev) || EQ(uv__rawname(obj), dev) || EQ(stub, dev)) {
+ if (EQ(obj, dev) || EQ(uv__rawname(obj, &rawbuf), dev) || EQ(stub, dev)) {
uv__free(p); /* Found a match */
return 0;
}
@@ -453,7 +450,8 @@ static int uv__makedir_p(const char *dir) {
size_t len;
int err;
- snprintf(tmp, sizeof(tmp),"%s",dir);
+ /* TODO(bnoordhuis) Check uv__strscpy() return value. */
+ uv__strscpy(tmp, dir, sizeof(tmp));
len = strlen(tmp);
if (tmp[len - 1] == '/')
tmp[len - 1] = 0;
@@ -557,7 +555,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1");
rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
- if (rc < 0)
+ if (rc < 0 && errno != EBUSY)
return UV__ERR(errno);
return 0;
@@ -702,9 +700,9 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int
else
p++;
}
- strncpy(fname, p, sizeof(fname) - 1);
- /* Just in case */
- fname[sizeof(fname) - 1] = '\0';
+
+ /* TODO(bnoordhuis) Check uv__strscpy() return value. */
+ uv__strscpy(fname, p, sizeof(fname));
handle->cb(handle, fname, events, 0);
}
@@ -730,12 +728,19 @@ int uv_fs_event_start(uv_fs_event_t* handle,
char cwd[PATH_MAX];
char absolute_path[PATH_MAX];
char readlink_cwd[PATH_MAX];
+ struct timeval zt;
+ fd_set pollfd;
/* Figure out whether filename is absolute or not */
- if (filename[0] == '/') {
+ if (filename[0] == '\0') {
+ /* Missing a pathname */
+ return UV_ENOENT;
+ }
+ else if (filename[0] == '/') {
/* We have absolute pathname */
- snprintf(absolute_path, sizeof(absolute_path), "%s", filename);
+ /* TODO(bnoordhuis) Check uv__strscpy() return value. */
+ uv__strscpy(absolute_path, filename, sizeof(absolute_path));
} else {
/* We have a relative pathname, compose the absolute pathname */
snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid());
@@ -769,6 +774,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
+ /* AHAFS wants someone to poll for it to start mointoring.
+ * so kick-start it so that we don't miss an event in the
+ * eventuality of an event that occurs in the current loop. */
+ do {
+ memset(&zt, 0, sizeof(zt));
+ FD_ZERO(&pollfd);
+ FD_SET(fd, &pollfd);
+ rc = select(fd + 1, &pollfd, NULL, NULL, &zt);
+ } while (rc == -1 && errno == EINTR);
return 0;
#else
return UV_ENOSYS;
@@ -886,16 +900,20 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
size_t len;
- len = strlen(process_argv[0]);
if (buffer == NULL || size == 0)
return UV_EINVAL;
- else if (size <= len)
- return UV_ENOBUFS;
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
uv_mutex_lock(&process_title_mutex);
- memcpy(buffer, process_argv[0], len + 1);
+ len = strlen(process_argv[0]);
+ if (size <= len) {
+ uv_mutex_unlock(&process_title_mutex);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_argv[0], len);
+ buffer[len] = '\0';
uv_mutex_unlock(&process_title_mutex);
@@ -982,7 +1000,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
return UV_ENOMEM;
}
- strcpy(cpu_id.name, FIRST_CPU);
+ /* TODO(bnoordhuis) Check uv__strscpy() return value. */
+ uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name));
result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
if (result == -1) {
uv__free(ps_cpus);
diff --git a/Utilities/cmlibuv/src/unix/android-ifaddrs.c b/Utilities/cmlibuv/src/unix/android-ifaddrs.c
index bf30b14..99fb25a 100644
--- a/Utilities/cmlibuv/src/unix/android-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/android-ifaddrs.c
@@ -23,7 +23,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "android-ifaddrs.h"
+#include "uv/android-ifaddrs.h"
#include "uv-common.h"
#include <string.h>
diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
index 0d02154..3c2253f 100644
--- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
@@ -52,13 +52,10 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
*/
if (ent->ifa_addr->sa_family == AF_LINK)
return 1;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
if (ent->ifa_addr->sa_family != PF_INET &&
ent->ifa_addr->sa_family != PF_INET6)
return 1;
-#elif defined(__OpenBSD__)
- if (ent->ifa_addr->sa_family != PF_INET)
- return 1;
#endif
return 0;
}
@@ -69,11 +66,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int i;
+ *count = 0;
+ *addresses = NULL;
+
if (getifaddrs(&addrs) != 0)
return UV__ERR(errno);
- *count = 0;
-
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@@ -81,6 +79,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ freeifaddrs(addrs);
+ return 0;
+ }
+
*addresses = uv__malloc(*count * sizeof(**addresses));
if (*addresses == NULL) {
@@ -121,15 +124,17 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;
for (i = 0; i < *count; i++) {
- if (strcmp(address->name, ent->ifa_name) == 0) {
#if defined(__CYGWIN__) || defined(__MSYS__)
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
#else
+ 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));
-#endif
+ } else {
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
+#endif
address++;
}
}
diff --git a/Utilities/cmlibuv/src/unix/bsd-proctitle.c b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
new file mode 100644
index 0000000..0ce47c8
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
@@ -0,0 +1,93 @@
+/* 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 <sys/types.h>
+#include <unistd.h>
+
+
+static uv_mutex_t process_title_mutex;
+static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
+static char* process_title;
+
+
+static void init_process_title_mutex_once(void) {
+ if (uv_mutex_init(&process_title_mutex))
+ abort();
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ char* new_title;
+
+ new_title = uv__strdup(title);
+ if (new_title == NULL)
+ return UV_ENOMEM;
+
+ uv_once(&process_title_mutex_once, init_process_title_mutex_once);
+ uv_mutex_lock(&process_title_mutex);
+
+ uv__free(process_title);
+ process_title = new_title;
+ setproctitle("%s", title);
+
+ uv_mutex_unlock(&process_title_mutex);
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return UV_EINVAL;
+
+ uv_once(&process_title_mutex_once, init_process_title_mutex_once);
+ uv_mutex_lock(&process_title_mutex);
+
+ if (process_title != NULL) {
+ len = strlen(process_title) + 1;
+
+ if (size < len) {
+ uv_mutex_unlock(&process_title_mutex);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_title, len);
+ } else {
+ len = 0;
+ }
+
+ uv_mutex_unlock(&process_title_mutex);
+
+ buffer[len] = '\0';
+
+ return 0;
+}
diff --git a/Utilities/cmlibuv/src/unix/cmake-bootstrap.c b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
index 4f32d03..309ec79 100644
--- a/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
+++ b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
@@ -46,6 +46,7 @@ void uv__async_stop(uv_loop_t* loop) {
}
void uv__work_submit(uv_loop_t* loop, struct uv__work* w,
+ enum uv__work_kind kind,
void (*work)(struct uv__work* w),
void (*done)(struct uv__work* w, int status)) {
abort();
diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c
index a357ef3..a8d6adb 100644
--- a/Utilities/cmlibuv/src/unix/core.c
+++ b/Utilities/cmlibuv/src/unix/core.c
@@ -41,6 +41,7 @@
#include <sys/resource.h> /* getrusage */
#include <pwd.h>
#include <sched.h>
+#include <sys/utsname.h>
#ifdef __sun
# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
@@ -119,7 +120,7 @@ uint64_t uv_hrtime(void) {
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
assert(!uv__is_closing(handle));
- handle->flags |= UV_CLOSING;
+ handle->flags |= UV_HANDLE_CLOSING;
handle->close_cb = close_cb;
switch (handle->type) {
@@ -177,8 +178,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
case UV_SIGNAL:
uv__signal_close((uv_signal_t*) handle);
- /* Signal handles may not be closed immediately. The signal code will */
- /* itself close uv__make_close_pending whenever appropriate. */
+ /* Signal handles may not be closed immediately. The signal code will
+ * itself close uv__make_close_pending whenever appropriate. */
return;
default:
@@ -217,8 +218,8 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
}
void uv__make_close_pending(uv_handle_t* handle) {
- assert(handle->flags & UV_CLOSING);
- assert(!(handle->flags & UV_CLOSED));
+ assert(handle->flags & UV_HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->next_closing = handle->loop->closing_handles;
handle->loop->closing_handles = handle;
}
@@ -244,15 +245,17 @@ int uv__getiovmax(void) {
static void uv__finish_close(uv_handle_t* handle) {
- /* Note: while the handle is in the UV_CLOSING state now, it's still possible
- * for it to be active in the sense that uv__is_active() returns true.
+ /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
+ * possible for it to be active in the sense that uv__is_active() returns
+ * true.
+ *
* A good example is when the user calls uv_shutdown(), immediately followed
* by uv_close(). The handle is considered active at this point because the
* completion of the shutdown req is still pending.
*/
- assert(handle->flags & UV_CLOSING);
- assert(!(handle->flags & UV_CLOSED));
- handle->flags |= UV_CLOSED;
+ assert(handle->flags & UV_HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ handle->flags |= UV_HANDLE_CLOSED;
switch (handle->type) {
case UV_PREPARE:
@@ -637,27 +640,6 @@ int uv__cloexec_fcntl(int fd, int set) {
}
-/* This function is not execve-safe, there is a race window
- * between the call to dup() and fcntl(FD_CLOEXEC).
- */
-int uv__dup(int fd) {
- int err;
-
- fd = dup(fd);
-
- if (fd == -1)
- return UV__ERR(errno);
-
- err = uv__cloexec(fd, 1);
- if (err) {
- uv__close(fd);
- return err;
- }
-
- return fd;
-}
-
-
ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
struct cmsghdr* cmsg;
ssize_t rc;
@@ -930,6 +912,11 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
}
+int uv__fd_exists(uv_loop_t* loop, int fd) {
+ return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
+}
+
+
int uv_getrusage(uv_rusage_t* rusage) {
struct rusage usage;
@@ -1343,6 +1330,9 @@ uv_os_fd_t uv_get_osfhandle(int fd) {
return fd;
}
+int uv_open_osfhandle(uv_os_fd_t os_fd) {
+ return os_fd;
+}
uv_pid_t uv_os_getpid(void) {
return getpid();
@@ -1352,3 +1342,87 @@ uv_pid_t uv_os_getpid(void) {
uv_pid_t uv_os_getppid(void) {
return getppid();
}
+
+
+int uv_os_getpriority(uv_pid_t pid, int* priority) {
+ int r;
+
+ if (priority == NULL)
+ return UV_EINVAL;
+
+ errno = 0;
+ r = getpriority(PRIO_PROCESS, (int) pid);
+
+ if (r == -1 && errno != 0)
+ return UV__ERR(errno);
+
+ *priority = r;
+ return 0;
+}
+
+
+int uv_os_setpriority(uv_pid_t pid, int priority) {
+ if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
+ return UV_EINVAL;
+
+ if (setpriority(PRIO_PROCESS, (int) pid, priority) != 0)
+ return UV__ERR(errno);
+
+ return 0;
+}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ struct utsname buf;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ if (uname(&buf) == -1) {
+ r = UV__ERR(errno);
+ goto error;
+ }
+
+ r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
+ if (r == UV_E2BIG)
+ goto error;
+
+#ifdef _AIX
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%s.%s",
+ buf.version,
+ buf.release);
+ if (r >= sizeof(buffer->release)) {
+ r = UV_E2BIG;
+ goto error;
+ }
+#else
+ r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release));
+ if (r == UV_E2BIG)
+ goto error;
+#endif
+
+ r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version));
+ if (r == UV_E2BIG)
+ goto error;
+
+#if defined(_AIX) || defined(__PASE__)
+ r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine));
+#else
+ r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
+#endif
+
+ if (r == UV_E2BIG)
+ goto error;
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/Utilities/cmlibuv/src/unix/cygwin.c b/Utilities/cmlibuv/src/unix/cygwin.c
index 9fe4093..9da20e2 100644
--- a/Utilities/cmlibuv/src/unix/cygwin.c
+++ b/Utilities/cmlibuv/src/unix/cygwin.c
@@ -38,7 +38,7 @@ int uv_uptime(double* uptime) {
int uv_resident_set_memory(size_t* rss) {
/* FIXME: read /proc/meminfo? */
*rss = 0;
- return UV_ENOSYS;
+ return 0;
}
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
diff --git a/Utilities/cmlibuv/src/unix/darwin-proctitle.c b/Utilities/cmlibuv/src/unix/darwin-proctitle.c
index dabde22..e505bdd 100644
--- a/Utilities/cmlibuv/src/unix/darwin-proctitle.c
+++ b/Utilities/cmlibuv/src/unix/darwin-proctitle.c
@@ -33,61 +33,56 @@
# include <ApplicationServices/ApplicationServices.h>
#endif
+#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
-static int uv__pthread_setname_np(const char* name) {
- int (*dynamic_pthread_setname_np)(const char* name);
- char namebuf[64]; /* MAXTHREADNAMESIZE */
- int err;
-
- /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
- *(void **)(&dynamic_pthread_setname_np) =
- dlsym(RTLD_DEFAULT, "pthread_setname_np");
-
- if (dynamic_pthread_setname_np == NULL)
- return UV_ENOSYS;
-
- strncpy(namebuf, name, sizeof(namebuf) - 1);
- namebuf[sizeof(namebuf) - 1] = '\0';
- err = dynamic_pthread_setname_np(namebuf);
- if (err)
- return UV__ERR(err);
+static int (*dynamic_pthread_setname_np)(const char* name);
+#if !TARGET_OS_IPHONE
+static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
+ const char*,
+ CFStringEncoding);
+static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
+static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
+static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
+static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
+static OSStatus (*pLSSetApplicationInformationItem)(int,
+ CFTypeRef,
+ CFStringRef,
+ CFStringRef,
+ CFDictionaryRef*);
+static void* application_services_handle;
+static void* core_foundation_handle;
+static CFBundleRef launch_services_bundle;
+static CFStringRef* display_name_key;
+static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
+static CFBundleRef (*pCFBundleGetMainBundle)(void);
+static CFBundleRef hi_services_bundle;
+static OSStatus (*pSetApplicationIsDaemon)(int);
+static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
+static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
+ void*);
+
+
+UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) {
+ if (core_foundation_handle != NULL) {
+ dlclose(core_foundation_handle);
+ core_foundation_handle = NULL;
+ }
- return 0;
+ if (application_services_handle != NULL) {
+ dlclose(application_services_handle);
+ application_services_handle = NULL;
+ }
}
+#endif /* !TARGET_OS_IPHONE */
-int uv__set_process_title(const char* title) {
-#if TARGET_OS_IPHONE
- return uv__pthread_setname_np(title);
-#else
- CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
- const char*,
- CFStringEncoding);
- CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
- void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
- void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
- CFTypeRef (*pLSGetCurrentApplicationASN)(void);
- OSStatus (*pLSSetApplicationInformationItem)(int,
- CFTypeRef,
- CFStringRef,
- CFStringRef,
- CFDictionaryRef*);
- void* application_services_handle;
- void* core_foundation_handle;
- CFBundleRef launch_services_bundle;
- CFStringRef* display_name_key;
- CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
- CFBundleRef (*pCFBundleGetMainBundle)(void);
- CFBundleRef hi_services_bundle;
- OSStatus (*pSetApplicationIsDaemon)(int);
- CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
- void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
- void*);
- CFTypeRef asn;
- int err;
-
- err = UV_ENOENT;
+void uv__set_process_title_platform_init(void) {
+ /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
+ *(void **)(&dynamic_pthread_setname_np) =
+ dlsym(RTLD_DEFAULT, "pthread_setname_np");
+
+#if !TARGET_OS_IPHONE
application_services_handle = dlopen("/System/Library/Frameworks/"
"ApplicationServices.framework/"
"Versions/A/ApplicationServices",
@@ -116,8 +111,6 @@ int uv__set_process_title(const char* title) {
goto out;
}
-#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
-
launch_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
@@ -148,13 +141,14 @@ int uv__set_process_title(const char* title) {
"CFBundleGetInfoDictionary");
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
"CFBundleGetMainBundle");
+
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
goto out;
/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
hi_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
- err = UV_ENOENT;
+
if (hi_services_bundle == NULL)
goto out;
@@ -168,42 +162,37 @@ int uv__set_process_title(const char* title) {
pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
+
if (pSetApplicationIsDaemon == NULL ||
pLSApplicationCheckIn == NULL ||
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
goto out;
}
- if (pSetApplicationIsDaemon(1) != noErr)
- goto out;
-
- pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
-
- /* Check into process manager?! */
- pLSApplicationCheckIn(-2,
- pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
-
- asn = pLSGetCurrentApplicationASN();
-
- err = UV_EINVAL;
- if (pLSSetApplicationInformationItem(-2, /* Magic value. */
- asn,
- *display_name_key,
- S(title),
- NULL) != noErr) {
- goto out;
- }
-
- uv__pthread_setname_np(title); /* Don't care if it fails. */
- err = 0;
+ return;
out:
- if (core_foundation_handle != NULL)
- dlclose(core_foundation_handle);
+ uv__set_process_title_platform_fini();
+#endif /* !TARGET_OS_IPHONE */
+}
- if (application_services_handle != NULL)
- dlclose(application_services_handle);
- return err;
+void uv__set_process_title(const char* title) {
+#if !TARGET_OS_IPHONE
+ if (core_foundation_handle != NULL && pSetApplicationIsDaemon(1) != noErr) {
+ CFTypeRef asn;
+ pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
+ pLSApplicationCheckIn(/* Magic value */ -2,
+ pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
+ asn = pLSGetCurrentApplicationASN();
+ pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
+ *display_name_key, S(title), NULL);
+ }
#endif /* !TARGET_OS_IPHONE */
+
+ if (dynamic_pthread_setname_np != NULL) {
+ char namebuf[64]; /* MAXTHREADNAMESIZE */
+ uv__strscpy(namebuf, title, sizeof(namebuf));
+ dynamic_pthread_setname_np(namebuf);
+ }
}
diff --git a/Utilities/cmlibuv/src/unix/freebsd.c b/Utilities/cmlibuv/src/unix/freebsd.c
index 70ccb13..0f729cf 100644
--- a/Utilities/cmlibuv/src/unix/freebsd.c
+++ b/Utilities/cmlibuv/src/unix/freebsd.c
@@ -47,15 +47,6 @@
# define CP_INTR 4
#endif
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
@@ -159,76 +150,6 @@ void uv_loadavg(double avg[3]) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- int oid[4];
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
-
- oid[0] = CTL_KERN;
- oid[1] = KERN_PROC;
- oid[2] = KERN_PROC_ARGS;
- oid[3] = getpid();
-
- sysctl(oid,
- ARRAY_SIZE(oid),
- NULL,
- NULL,
- process_title,
- strlen(process_title) + 1);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size;
diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c
index a6cc6db..bffc956 100644
--- a/Utilities/cmlibuv/src/unix/fs.c
+++ b/Utilities/cmlibuv/src/unix/fs.c
@@ -43,7 +43,6 @@
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
-#include <utime.h>
#include <poll.h>
#if defined(__DragonFly__) || \
@@ -62,11 +61,20 @@
#if defined(__APPLE__)
# include <copyfile.h>
+# include <sys/sysctl.h>
#elif defined(__linux__) && !defined(FICLONE)
# include <sys/ioctl.h>
# define FICLONE _IOW(0x94, 9, int)
#endif
+#if defined(_AIX) && !defined(_AIX71)
+# include <utime.h>
+#endif
+
+#if defined(_AIX) && _XOPEN_SOURCE <= 600
+extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
+#endif
+
#define INIT(subtype) \
do { \
if (req == NULL) \
@@ -120,7 +128,11 @@
do { \
if (cb != NULL) { \
uv__req_register(loop, req); \
- uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
+ uv__work_submit(loop, \
+ &req->work_req, \
+ UV__WORK_FAST_IO, \
+ uv__fs_work, \
+ uv__fs_done); \
return 0; \
} \
else { \
@@ -143,7 +155,7 @@ static ssize_t uv__fs_fsync(uv_fs_t* req) {
int r;
r = fcntl(req->file, F_FULLFSYNC);
- if (r != 0 && errno == ENOTTY)
+ if (r != 0)
r = fsync(req->file);
return r;
#else
@@ -165,59 +177,17 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
static ssize_t uv__fs_futime(uv_fs_t* req) {
-#if defined(__linux__)
+#if defined(__linux__) \
+ || defined(_AIX71)
/* utimesat() has nanosecond resolution but we stick to microseconds
* for the sake of consistency with other platforms.
*/
- static int no_utimesat;
struct timespec ts[2];
- struct timeval tv[2];
- char path[sizeof("/proc/self/fd/") + 3 * sizeof(int)];
- int r;
-
- if (no_utimesat)
- goto skip;
-
ts[0].tv_sec = req->atime;
ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
-
- r = uv__utimesat(req->file, NULL, ts, 0);
- if (r == 0)
- return r;
-
- if (errno != ENOSYS)
- return r;
-
- no_utimesat = 1;
-
-skip:
-
- tv[0].tv_sec = req->atime;
- tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
- tv[1].tv_sec = req->mtime;
- tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
- snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file);
-
- r = utimes(path, tv);
- if (r == 0)
- return r;
-
- switch (errno) {
- case ENOENT:
- if (fcntl(req->file, F_GETFL) == -1 && errno == EBADF)
- break;
- /* Fall through. */
-
- case EACCES:
- case ENOTDIR:
- errno = ENOSYS;
- break;
- }
-
- return r;
-
+ return futimens(req->file, ts);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
@@ -235,13 +205,6 @@ skip:
# else
return futimes(req->file, tv);
# endif
-#elif defined(_AIX71)
- struct timespec ts[2];
- ts[0].tv_sec = req->atime;
- ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
- ts[1].tv_sec = req->mtime;
- ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
- return futimens(req->file, ts);
#elif defined(__MVS__)
attrib_t atr;
memset(&atr, 0, sizeof(atr));
@@ -314,17 +277,13 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
#if defined(__linux__)
static int no_preadv;
#endif
+ unsigned int iovmax;
ssize_t result;
-#if defined(_AIX)
- struct stat buf;
- if(fstat(req->file, &buf))
- return -1;
- if(S_ISDIR(buf.st_mode)) {
- errno = EISDIR;
- return -1;
- }
-#endif /* defined(_AIX) */
+ iovmax = uv__getiovmax();
+ if (req->nbufs > iovmax)
+ req->nbufs = iovmax;
+
if (req->off < 0) {
if (req->nbufs == 1)
result = read(req->file, req->bufs[0].base, req->bufs[0].len);
@@ -343,25 +302,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
if (no_preadv) retry:
# endif
{
- off_t nread;
- size_t index;
-
- nread = 0;
- index = 0;
- result = 1;
- do {
- if (req->bufs[index].len > 0) {
- result = pread(req->file,
- req->bufs[index].base,
- req->bufs[index].len,
- req->off + nread);
- if (result > 0)
- nread += result;
- }
- index++;
- } while (index < req->nbufs && result > 0);
- if (nread > 0)
- result = nread;
+ result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
}
# if defined(__linux__)
else {
@@ -379,6 +320,13 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
}
done:
+ /* Early cleanup of bufs allocation, since we're done with it. */
+ if (req->bufs != req->bufsml)
+ uv__free(req->bufs);
+
+ req->bufs = NULL;
+ req->nbufs = 0;
+
return result;
}
@@ -446,8 +394,10 @@ static ssize_t uv__fs_pathmax_size(const char* path) {
}
static ssize_t uv__fs_readlink(uv_fs_t* req) {
+ ssize_t maxlen;
ssize_t len;
char* buf;
+ char* newbuf;
#if defined(UV__FS_PATH_MAX_FALLBACK)
/* We may not have a real PATH_MAX. Read size of link. */
@@ -461,17 +411,17 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
return -1;
}
- len = st.st_size;
+ maxlen = st.st_size;
/* According to readlink(2) lstat can report st_size == 0
for some symlinks, such as those in /proc or /sys. */
- if (len == 0)
- len = uv__fs_pathmax_size(req->path);
+ if (maxlen == 0)
+ maxlen = uv__fs_pathmax_size(req->path);
#else
- len = uv__fs_pathmax_size(req->path);
+ maxlen = uv__fs_pathmax_size(req->path);
#endif
- buf = uv__malloc(len + 1);
+ buf = uv__malloc(maxlen);
if (buf == NULL) {
errno = ENOMEM;
@@ -479,17 +429,28 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
}
#if defined(__MVS__)
- len = os390_readlink(req->path, buf, len);
+ len = os390_readlink(req->path, buf, maxlen);
#else
- len = readlink(req->path, buf, len);
+ len = readlink(req->path, buf, maxlen);
#endif
-
if (len == -1) {
uv__free(buf);
return -1;
}
+ /* Uncommon case: resize to make room for the trailing nul byte. */
+ if (len == maxlen) {
+ newbuf = uv__realloc(buf, len + 1);
+
+ if (newbuf == NULL) {
+ uv__free(buf);
+ return -1;
+ }
+
+ buf = newbuf;
+ }
+
buf[len] = '\0';
req->ptr = buf;
@@ -739,10 +700,48 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
static ssize_t uv__fs_utime(uv_fs_t* req) {
+#if defined(__linux__) \
+ || defined(_AIX71) \
+ || defined(__sun)
+ /* utimesat() has nanosecond resolution but we stick to microseconds
+ * for the sake of consistency with other platforms.
+ */
+ struct timespec ts[2];
+ ts[0].tv_sec = req->atime;
+ ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
+ ts[1].tv_sec = req->mtime;
+ ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
+ return utimensat(AT_FDCWD, req->path, ts, 0);
+#elif defined(__APPLE__) \
+ || defined(__DragonFly__) \
+ || defined(__FreeBSD__) \
+ || defined(__FreeBSD_kernel__) \
+ || defined(__NetBSD__) \
+ || defined(__OpenBSD__)
+ struct timeval tv[2];
+ tv[0].tv_sec = req->atime;
+ tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
+ tv[1].tv_sec = req->mtime;
+ tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
+ return utimes(req->path, tv);
+#elif defined(_AIX) \
+ && !defined(_AIX71)
struct utimbuf buf;
buf.actime = req->atime;
buf.modtime = req->mtime;
- return utime(req->path, &buf); /* TODO use utimes() where available */
+ return utime(req->path, &buf);
+#elif defined(__MVS__)
+ attrib_t atr;
+ memset(&atr, 0, sizeof(atr));
+ atr.att_mtimechg = 1;
+ atr.att_atimechg = 1;
+ atr.att_mtime = req->mtime;
+ atr.att_atime = req->atime;
+ return __lchattr((char*) req->path, &atr, sizeof(atr));
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
}
@@ -780,25 +779,7 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
if (no_pwritev) retry:
# endif
{
- off_t written;
- size_t index;
-
- written = 0;
- index = 0;
- r = 0;
- do {
- if (req->bufs[index].len > 0) {
- r = pwrite(req->file,
- req->bufs[index].base,
- req->bufs[index].len,
- req->off + written);
- if (r > 0)
- written += r;
- }
- index++;
- } while (index < req->nbufs && r >= 0);
- if (written > 0)
- r = written;
+ r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
}
# if defined(__linux__)
else {
@@ -827,26 +808,41 @@ done:
static ssize_t uv__fs_copyfile(uv_fs_t* req) {
#if defined(__APPLE__) && !TARGET_OS_IPHONE
/* On macOS, use the native copyfile(3). */
+ static int can_clone;
copyfile_flags_t flags;
+ char buf[64];
+ size_t len;
+ int major;
flags = COPYFILE_ALL;
if (req->flags & UV_FS_COPYFILE_EXCL)
flags |= COPYFILE_EXCL;
-#ifdef COPYFILE_CLONE
- if (req->flags & UV_FS_COPYFILE_FICLONE)
- flags |= COPYFILE_CLONE;
-#endif
-
+ /* Check OS version. Cloning is only supported on macOS >= 10.12. */
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
-#ifdef COPYFILE_CLONE_FORCE
- flags |= COPYFILE_CLONE_FORCE;
-#else
- return UV_ENOSYS;
-#endif
+ if (can_clone == 0) {
+ len = sizeof(buf);
+ if (sysctlbyname("kern.osrelease", buf, &len, NULL, 0))
+ return UV__ERR(errno);
+
+ if (1 != sscanf(buf, "%d", &major))
+ abort();
+
+ can_clone = -1 + 2 * (major >= 16); /* macOS >= 10.12 */
+ }
+
+ if (can_clone < 0)
+ return UV_ENOSYS;
}
+ /* copyfile() simply ignores COPYFILE_CLONE if it's not supported. */
+ if (req->flags & UV_FS_COPYFILE_FICLONE)
+ flags |= 1 << 24; /* COPYFILE_CLONE */
+
+ if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE)
+ flags |= 1 << 25; /* COPYFILE_CLONE_FORCE */
+
return copyfile(req->path, req->new_path, NULL, flags);
#else
uv_fs_t fs_req;
@@ -906,9 +902,11 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
/* If an error occurred that the sendfile fallback also won't handle, or
this is a force clone then exit. Otherwise, fall through to try using
sendfile(). */
- if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) ||
- req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
- err = -errno;
+ if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) {
+ err = UV__ERR(errno);
+ goto out;
+ } else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+ err = UV_ENOTSUP;
goto out;
}
} else {
@@ -968,7 +966,11 @@ out:
}
}
- return result;
+ if (result == 0)
+ return 0;
+
+ errno = UV__ERR(result);
+ return -1;
#endif
}
@@ -1084,9 +1086,21 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
return ret;
}
+static size_t uv__fs_buf_offset(uv_buf_t* bufs, size_t size) {
+ size_t offset;
+ /* Figure out which bufs are done */
+ for (offset = 0; size > 0 && bufs[offset].len <= size; ++offset)
+ size -= bufs[offset].len;
+
+ /* Fix a partial read/write */
+ if (size > 0) {
+ bufs[offset].base += size;
+ bufs[offset].len -= size;
+ }
+ return offset;
+}
-typedef ssize_t (*uv__fs_buf_iter_processor)(uv_fs_t* req);
-static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process) {
+static ssize_t uv__fs_write_all(uv_fs_t* req) {
unsigned int iovmax;
unsigned int nbufs;
uv_buf_t* bufs;
@@ -1103,7 +1117,10 @@ static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process)
if (req->nbufs > iovmax)
req->nbufs = iovmax;
- result = process(req);
+ do
+ result = uv__fs_write(req);
+ while (result < 0 && errno == EINTR);
+
if (result <= 0) {
if (total == 0)
total = result;
@@ -1113,14 +1130,12 @@ static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process)
if (req->off >= 0)
req->off += result;
+ req->nbufs = uv__fs_buf_offset(req->bufs, result);
req->bufs += req->nbufs;
nbufs -= req->nbufs;
total += result;
}
- if (errno == EINTR && total == -1)
- return total;
-
if (bufs != req->bufsml)
uv__free(bufs);
@@ -1137,7 +1152,8 @@ static void uv__fs_work(struct uv__work* w) {
ssize_t r;
req = container_of(w, uv_fs_t, work_req);
- retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
+ retry_on_eintr = !(req->fs_type == UV_FS_CLOSE ||
+ req->fs_type == UV_FS_READ);
do {
errno = 0;
@@ -1155,6 +1171,7 @@ static void uv__fs_work(struct uv__work* w) {
X(COPYFILE, uv__fs_copyfile(req));
X(FCHMOD, fchmod(req->file, req->mode));
X(FCHOWN, fchown(req->file, req->uid, req->gid));
+ X(LCHOWN, lchown(req->path, req->uid, req->gid));
X(FDATASYNC, uv__fs_fdatasync(req));
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
X(FSYNC, uv__fs_fsync(req));
@@ -1165,7 +1182,7 @@ static void uv__fs_work(struct uv__work* w) {
X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
X(OPEN, uv__fs_open(req));
- X(READ, uv__fs_buf_iter(req, uv__fs_read));
+ X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req));
X(READLINK, uv__fs_readlink(req));
X(REALPATH, uv__fs_realpath(req));
@@ -1176,7 +1193,7 @@ static void uv__fs_work(struct uv__work* w) {
X(SYMLINK, symlink(req->path, req->new_path));
X(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req));
- X(WRITE, uv__fs_buf_iter(req, uv__fs_write));
+ X(WRITE, uv__fs_write_all(req));
default: abort();
}
#undef X
@@ -1281,6 +1298,20 @@ int uv_fs_fchown(uv_loop_t* loop,
}
+int uv_fs_lchown(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb) {
+ INIT(LCHOWN);
+ PATH;
+ req->uid = uid;
+ req->gid = gid;
+ POST;
+}
+
+
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
INIT(FDATASYNC);
req->file = file;
diff --git a/Utilities/cmlibuv/src/unix/fsevents.c b/Utilities/cmlibuv/src/unix/fsevents.c
index 47d8024..c430562 100644
--- a/Utilities/cmlibuv/src/unix/fsevents.c
+++ b/Utilities/cmlibuv/src/unix/fsevents.c
@@ -255,42 +255,55 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
path = paths[i];
len = strlen(path);
+ if (handle->realpath_len == 0)
+ continue; /* This should be unreachable */
+
/* Filter out paths that are outside handle's request */
- if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
+ if (len < handle->realpath_len)
+ continue;
+
+ if (handle->realpath_len != len &&
+ path[handle->realpath_len] != '/')
+ /* Make sure that realpath actually named a directory,
+ * or that we matched the whole string */
continue;
- if (handle->realpath_len > 1 || *handle->realpath != '/') {
+ if (memcmp(path, handle->realpath, handle->realpath_len) != 0)
+ continue;
+
+ if (!(handle->realpath_len == 1 && handle->realpath[0] == '/')) {
+ /* Remove common prefix, unless the watched folder is "/" */
path += handle->realpath_len;
len -= handle->realpath_len;
- /* Skip forward slash */
- if (*path != '\0') {
+ /* Ignore events with path equal to directory itself */
+ if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir))
+ continue;
+
+ if (len == 0) {
+ /* Since we're using fsevents to watch the file itself,
+ * realpath == path, and we now need to get the basename of the file back
+ * (for commonality with other codepaths and platforms). */
+ while (len < handle->realpath_len && path[-1] != '/') {
+ path--;
+ len++;
+ }
+ /* Created and Removed seem to be always set, but don't make sense */
+ flags &= ~kFSEventsRenamed;
+ } else {
+ /* Skip forward slash */
path++;
len--;
}
}
-#ifdef MAC_OS_X_VERSION_10_7
- /* Ignore events with path equal to directory itself */
- if (len == 0)
- continue;
-#else
- if (len == 0 && (flags & kFSEventStreamEventFlagItemIsDir))
- continue;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
/* Do not emit events from subdirectories (without option set) */
- if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != '\0') {
pos = strchr(path + 1, '/');
if (pos != NULL)
continue;
}
-#ifndef MAC_OS_X_VERSION_10_7
- path = "";
- len = 0;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
event = uv__malloc(sizeof(*event) + len);
if (event == NULL)
break;
@@ -299,22 +312,11 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
memcpy(event->path, path, len + 1);
event->events = UV_RENAME;
-#ifdef MAC_OS_X_VERSION_10_7
- if (0 != (flags & kFSEventsModified) &&
- 0 == (flags & kFSEventsRenamed)) {
- event->events = UV_CHANGE;
- }
-#else
- if (0 != (flags & kFSEventsModified) &&
- 0 != (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
- }
- if (0 == (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
+ if (0 == (flags & kFSEventsRenamed)) {
+ if (0 != (flags & kFSEventsModified) ||
+ 0 == (flags & kFSEventStreamEventFlagItemIsDir))
+ event->events = UV_CHANGE;
}
-#endif /* MAC_OS_X_VERSION_10_7 */
QUEUE_INSERT_TAIL(&head, &event->member);
}
@@ -836,7 +838,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
handle->cf_cb->data = handle;
uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
- handle->cf_cb->flags |= UV__HANDLE_INTERNAL;
+ handle->cf_cb->flags |= UV_HANDLE_INTERNAL;
uv_unref((uv_handle_t*) handle->cf_cb);
err = uv_mutex_init(&handle->cf_mutex);
diff --git a/Utilities/cmlibuv/src/unix/getaddrinfo.c b/Utilities/cmlibuv/src/unix/getaddrinfo.c
index 10e8afd..6d23fbe 100644
--- a/Utilities/cmlibuv/src/unix/getaddrinfo.c
+++ b/Utilities/cmlibuv/src/unix/getaddrinfo.c
@@ -27,6 +27,7 @@
#include "uv.h"
#include "internal.h"
+#include "idna.h"
#include <errno.h>
#include <stddef.h> /* NULL */
@@ -141,15 +142,34 @@ int uv_getaddrinfo(uv_loop_t* loop,
const char* hostname,
const char* service,
const struct addrinfo* hints) {
+ char hostname_ascii[256];
size_t hostname_len;
size_t service_len;
size_t hints_len;
size_t len;
char* buf;
+ long rc;
if (req == NULL || (hostname == NULL && service == NULL))
return UV_EINVAL;
+ /* FIXME(bnoordhuis) IDNA does not seem to work z/OS,
+ * probably because it uses EBCDIC rather than ASCII.
+ */
+#ifdef __MVS__
+ (void) &hostname_ascii;
+#else
+ if (hostname != NULL) {
+ rc = uv__idna_toascii(hostname,
+ hostname + strlen(hostname),
+ hostname_ascii,
+ hostname_ascii + sizeof(hostname_ascii));
+ if (rc < 0)
+ return rc;
+ hostname = hostname_ascii;
+ }
+#endif
+
hostname_len = hostname ? strlen(hostname) + 1 : 0;
service_len = service ? strlen(service) + 1 : 0;
hints_len = hints ? sizeof(*hints) : 0;
@@ -186,6 +206,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (cb) {
uv__work_submit(loop,
&req->work_req,
+ UV__WORK_SLOW_IO,
uv__getaddrinfo_work,
uv__getaddrinfo_done);
return 0;
diff --git a/Utilities/cmlibuv/src/unix/getnameinfo.c b/Utilities/cmlibuv/src/unix/getnameinfo.c
index d9e6f79..b695081 100644
--- a/Utilities/cmlibuv/src/unix/getnameinfo.c
+++ b/Utilities/cmlibuv/src/unix/getnameinfo.c
@@ -109,6 +109,7 @@ int uv_getnameinfo(uv_loop_t* loop,
if (getnameinfo_cb) {
uv__work_submit(loop,
&req->work_req,
+ UV__WORK_SLOW_IO,
uv__getnameinfo_work,
uv__getnameinfo_done);
return 0;
diff --git a/Utilities/cmlibuv/src/unix/ibmi.c b/Utilities/cmlibuv/src/unix/ibmi.c
index 02e90fb..13fed6c 100644
--- a/Utilities/cmlibuv/src/unix/ibmi.c
+++ b/Utilities/cmlibuv/src/unix/ibmi.c
@@ -72,7 +72,8 @@ void uv_loadavg(double avg[3]) {
int uv_resident_set_memory(size_t* rss) {
- return UV_ENOSYS;
+ *rss = 0;
+ return 0;
}
diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h
index 89c6eb1..48fe6e8 100644
--- a/Utilities/cmlibuv/src/unix/internal.h
+++ b/Utilities/cmlibuv/src/unix/internal.h
@@ -137,26 +137,6 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t;
-/* handle flags */
-enum {
- UV_CLOSING = 0x01, /* uv_close() called but not finished. */
- UV_CLOSED = 0x02, /* close(2) finished. */
- UV_STREAM_READING = 0x04, /* uv_read_start() called. */
- UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
- UV_STREAM_SHUT = 0x10, /* Write side closed. */
- UV_STREAM_READABLE = 0x20, /* The stream is readable */
- UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
- UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */
- UV_STREAM_READ_PARTIAL = 0x100, /* read(2) read less than requested. */
- UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */
- UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
- UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
- UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
- UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */
- UV_UDP_PROCESSING = 0x20000, /* Handle is running the send callback queue. */
- UV_HANDLE_BOUND = 0x40000 /* Handle is bound to an address and port */
-};
-
/* loop flags */
enum {
UV_LOOP_BLOCK_SIGPROF = 1
@@ -215,7 +195,6 @@ int uv__nonblock_fcntl(int fd, int set);
int uv__close(int fd); /* preserves errno */
int uv__close_nocheckstdio(int fd);
int uv__socket(int domain, int type, int protocol);
-int uv__dup(int fd);
ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
void uv__make_close_pending(uv_handle_t* handle);
int uv__getiovmax(void);
@@ -229,6 +208,7 @@ 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);
+int uv__fd_exists(uv_loop_t* loop, int fd);
/* async */
void uv__async_stop(uv_loop_t* loop);
@@ -261,10 +241,6 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay);
/* pipe */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
-/* timer */
-void uv__run_timers(uv_loop_t* loop);
-int uv__next_timeout(const uv_loop_t* loop);
-
/* signal */
void uv__signal_close(uv_signal_t* handle);
void uv__signal_global_once_init(void);
@@ -289,7 +265,6 @@ void uv__prepare_close(uv_prepare_t* handle);
void uv__process_close(uv_process_t* handle);
void uv__stream_close(uv_stream_t* handle);
void uv__tcp_close(uv_tcp_t* handle);
-void uv__timer_close(uv_timer_t* handle);
void uv__udp_close(uv_udp_t* handle);
void uv__udp_finish_close(uv_udp_t* handle);
uv_handle_type uv__handle_type(int fd);
@@ -319,24 +294,6 @@ int uv__fsevents_init(uv_fs_event_t* handle);
int uv__fsevents_close(uv_fs_event_t* handle);
void uv__fsevents_loop_delete(uv_loop_t* loop);
-/* OSX < 10.7 has no file events, polyfill them */
-#ifndef MAC_OS_X_VERSION_10_7
-
-static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
-static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
-static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
-static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
-static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
-static const int kFSEventStreamEventFlagItemModified = 0x00001000;
-static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
-static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
-static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
-static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
-static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
-static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
-
-#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
-
#endif /* defined(__APPLE__) */
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
diff --git a/Utilities/cmlibuv/src/unix/kqueue.c b/Utilities/cmlibuv/src/unix/kqueue.c
index a30fd73..c24f96e 100644
--- a/Utilities/cmlibuv/src/unix/kqueue.c
+++ b/Utilities/cmlibuv/src/unix/kqueue.c
@@ -261,8 +261,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = loop->watchers[fd];
if (w == NULL) {
- /* File descriptor that we've stopped watching, disarm it. */
- /* TODO batch up */
+ /* File descriptor that we've stopped watching, disarm it.
+ * TODO: batch up. */
struct kevent events[1];
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
@@ -452,49 +452,48 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* path,
unsigned int flags) {
-#if defined(__APPLE__)
- struct stat statbuf;
-#endif /* defined(__APPLE__) */
int fd;
if (uv__is_active(handle))
return UV_EINVAL;
- /* TODO open asynchronously - but how do we report back errors? */
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return UV__ERR(errno);
-
- uv__handle_start(handle);
- uv__io_init(&handle->event_watcher, uv__fs_event, fd);
- handle->path = uv__strdup(path);
- 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;
handle->realpath_len = 0;
handle->cf_flags = flags;
- if (fstat(fd, &statbuf))
- goto fallback;
- /* FSEvents works only with directories */
- if (!(statbuf.st_mode & S_IFDIR))
- goto fallback;
-
- /* The fallback fd is no longer needed */
- uv__close(fd);
- handle->event_watcher.fd = -1;
-
- return uv__fsevents_init(handle);
-
-fallback:
+ if (!uv__has_forked_with_cfrunloop) {
+ int r;
+ /* The fallback fd is not used */
+ handle->event_watcher.fd = -1;
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ r = uv__fsevents_init(handle);
+ if (r == 0) {
+ uv__handle_start(handle);
+ } else {
+ uv__free(handle->path);
+ handle->path = NULL;
+ }
+ return r;
+ }
#endif /* defined(__APPLE__) */
+ /* TODO open asynchronously - but how do we report back errors? */
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return UV__ERR(errno);
+
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ uv__handle_start(handle);
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
return 0;
@@ -502,29 +501,29 @@ fallback:
int uv_fs_event_stop(uv_fs_event_t* handle) {
+ int r;
+ r = 0;
+
if (!uv__is_active(handle))
return 0;
uv__handle_stop(handle);
#if defined(__APPLE__)
- if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle))
-#endif /* defined(__APPLE__) */
- {
- uv__io_close(handle->loop, &handle->event_watcher);
- }
-
- uv__free(handle->path);
- handle->path = NULL;
+ if (!uv__has_forked_with_cfrunloop)
+ r = uv__fsevents_close(handle);
+#endif
if (handle->event_watcher.fd != -1) {
- /* When FSEvents is used, we don't use the event_watcher's fd under certain
- * confitions. (see uv_fs_event_start) */
+ uv__io_close(handle->loop, &handle->event_watcher);
uv__close(handle->event_watcher.fd);
handle->event_watcher.fd = -1;
}
- return 0;
+ uv__free(handle->path);
+ handle->path = NULL;
+
+ return r;
}
diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c
index b63c25f..3341b94 100644
--- a/Utilities/cmlibuv/src/unix/linux-core.c
+++ b/Utilities/cmlibuv/src/unix/linux-core.c
@@ -20,7 +20,7 @@
/* We lean on the fact that POLL{IN,OUT,ERR,HUP} correspond with their
* EPOLL* counterparts. We use the POLL* variants in this file because that
- * is what libuv uses elsewhere and it avoids a dependency on <sys/epoll.h>.
+ * is what libuv uses elsewhere.
*/
#include "uv.h"
@@ -34,6 +34,7 @@
#include <errno.h>
#include <net/if.h>
+#include <sys/epoll.h>
#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/sysinfo.h>
@@ -51,7 +52,7 @@
#ifdef HAVE_IFADDRS_H
# if defined(__ANDROID__)
-# include "android-ifaddrs.h"
+# include "uv/android-ifaddrs.h"
# else
# include <ifaddrs.h>
# endif
@@ -84,13 +85,13 @@ static unsigned long read_cpufreq(unsigned int cpunum);
int uv__platform_loop_init(uv_loop_t* loop) {
int fd;
- fd = uv__epoll_create1(UV__EPOLL_CLOEXEC);
+ fd = epoll_create1(EPOLL_CLOEXEC);
/* epoll_create1() can fail either because it's not implemented (old kernel)
* or because it doesn't understand the EPOLL_CLOEXEC flag.
*/
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
- fd = uv__epoll_create(256);
+ fd = epoll_create(256);
if (fd != -1)
uv__cloexec(fd, 1);
@@ -134,20 +135,20 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
- struct uv__epoll_event* events;
- struct uv__epoll_event dummy;
+ struct epoll_event* events;
+ struct epoll_event dummy;
uintptr_t i;
uintptr_t nfds;
assert(loop->watchers != NULL);
- events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
+ events = (struct epoll_event*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events != NULL)
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
- if ((int) events[i].data == fd)
- events[i].data = -1;
+ if (events[i].data.fd == fd)
+ events[i].data.fd = -1;
/* Remove the file descriptor from the epoll.
* This avoids a problem where the same file description remains open
@@ -160,25 +161,26 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
*/
memset(&dummy, 0, sizeof(dummy));
- uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy);
+ epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
}
}
int uv__io_check_fd(uv_loop_t* loop, int fd) {
- struct uv__epoll_event e;
+ struct epoll_event e;
int rc;
+ memset(&e, 0, sizeof(e));
e.events = POLLIN;
- e.data = -1;
+ e.data.fd = -1;
rc = 0;
- if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_ADD, fd, &e))
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
if (errno != EEXIST)
rc = UV__ERR(errno);
if (rc == 0)
- if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &e))
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
abort();
return rc;
@@ -195,16 +197,14 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* that being the largest value I have seen in the wild (and only once.)
*/
static const int max_safe_timeout = 1789569;
- static int no_epoll_pwait;
- static int no_epoll_wait;
- struct uv__epoll_event events[1024];
- struct uv__epoll_event* pe;
- struct uv__epoll_event e;
+ struct epoll_event events[1024];
+ struct epoll_event* pe;
+ struct epoll_event e;
int real_timeout;
QUEUE* q;
uv__io_t* w;
sigset_t sigset;
- uint64_t sigmask;
+ sigset_t* psigset;
uint64_t base;
int have_signals;
int nevents;
@@ -219,6 +219,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
return;
}
+ memset(&e, 0, sizeof(e));
+
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
q = QUEUE_HEAD(&loop->watcher_queue);
QUEUE_REMOVE(q);
@@ -230,35 +232,35 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
assert(w->fd < (int) loop->nwatchers);
e.events = w->pevents;
- e.data = w->fd;
+ e.data.fd = w->fd;
if (w->events == 0)
- op = UV__EPOLL_CTL_ADD;
+ op = EPOLL_CTL_ADD;
else
- op = UV__EPOLL_CTL_MOD;
+ op = EPOLL_CTL_MOD;
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
* events, skip the syscall and squelch the events after epoll_wait().
*/
- if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
+ if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
if (errno != EEXIST)
abort();
- assert(op == UV__EPOLL_CTL_ADD);
+ assert(op == EPOLL_CTL_ADD);
/* We've reactivated a file descriptor that's been watched before. */
- if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e))
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
abort();
}
w->events = w->pevents;
}
- sigmask = 0;
+ psigset = NULL;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
sigemptyset(&sigset);
sigaddset(&sigset, SIGPROF);
- sigmask |= 1 << (SIGPROF - 1);
+ psigset = &sigset;
}
assert(timeout >= -1);
@@ -273,30 +275,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
timeout = max_safe_timeout;
- if (sigmask != 0 && no_epoll_pwait != 0)
- if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
- abort();
-
- if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
- nfds = uv__epoll_pwait(loop->backend_fd,
- events,
- ARRAY_SIZE(events),
- timeout,
- sigmask);
- if (nfds == -1 && errno == ENOSYS)
- no_epoll_pwait = 1;
- } else {
- nfds = uv__epoll_wait(loop->backend_fd,
- events,
- ARRAY_SIZE(events),
- timeout);
- if (nfds == -1 && errno == ENOSYS)
- no_epoll_wait = 1;
- }
-
- if (sigmask != 0 && no_epoll_pwait != 0)
- if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
- abort();
+ nfds = epoll_pwait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout,
+ psigset);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
@@ -317,12 +300,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
if (nfds == -1) {
- if (errno == ENOSYS) {
- /* epoll_wait() or epoll_pwait() failed, try the other system call. */
- assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
- continue;
- }
-
if (errno != EINTR)
abort();
@@ -344,7 +321,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
for (i = 0; i < nfds; i++) {
pe = events + i;
- fd = pe->data;
+ fd = pe->data.fd;
/* Skip invalidated events, see uv__platform_invalidate_fd */
if (fd == -1)
@@ -361,7 +338,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* Ignore all errors because we may be racing with another thread
* when the file descriptor is closed.
*/
- uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe);
+ epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
continue;
}
@@ -388,7 +365,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* free when we switch over to edge-triggered I/O.
*/
if (pe->events == POLLERR || pe->events == POLLHUP)
- pe->events |= w->pevents & (POLLIN | POLLOUT | UV__POLLPRI);
+ pe->events |=
+ w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
if (pe->events != 0) {
/* Run signal watchers last. This also affects child process watchers
@@ -851,9 +829,10 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return !exclude_type;
}
-int uv_interface_addresses(uv_interface_address_t** addresses,
- int* count) {
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#ifndef HAVE_IFADDRS_H
+ *count = 0;
+ *addresses = NULL;
return UV_ENOSYS;
#else
struct ifaddrs *addrs, *ent;
@@ -861,12 +840,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
int i;
struct sockaddr_ll *sll;
- if (getifaddrs(&addrs))
- return UV__ERR(errno);
-
*count = 0;
*addresses = NULL;
+ if (getifaddrs(&addrs))
+ return UV__ERR(errno);
+
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@@ -875,8 +854,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
- if (*count == 0)
+ if (*count == 0) {
+ freeifaddrs(addrs);
return 0;
+ }
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
@@ -920,6 +901,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
if (strcmp(address->name, ent->ifa_name) == 0) {
sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
+ } else {
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
address++;
}
diff --git a/Utilities/cmlibuv/src/unix/linux-inotify.c b/Utilities/cmlibuv/src/unix/linux-inotify.c
index bcad630..9b26202 100644
--- a/Utilities/cmlibuv/src/unix/linux-inotify.c
+++ b/Utilities/cmlibuv/src/unix/linux-inotify.c
@@ -19,7 +19,7 @@
*/
#include "uv.h"
-#include "tree.h"
+#include "uv/tree.h"
#include "internal.h"
#include <stdint.h>
@@ -278,6 +278,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
const char* path,
unsigned int flags) {
struct watcher_list* w;
+ size_t len;
int events;
int err;
int wd;
@@ -306,12 +307,13 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (w)
goto no_insert;
- w = uv__malloc(sizeof(*w) + strlen(path) + 1);
+ len = strlen(path) + 1;
+ w = uv__malloc(sizeof(*w) + len);
if (w == NULL)
return UV_ENOMEM;
w->wd = wd;
- w->path = strcpy((char*)(w + 1), path);
+ w->path = memcpy(w + 1, path, len);
QUEUE_INIT(&w->watchers);
w->iterating = 0;
RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w);
diff --git a/Utilities/cmlibuv/src/unix/linux-syscalls.c b/Utilities/cmlibuv/src/unix/linux-syscalls.c
index 89998de..bfd7544 100644
--- a/Utilities/cmlibuv/src/unix/linux-syscalls.c
+++ b/Utilities/cmlibuv/src/unix/linux-syscalls.c
@@ -77,56 +77,6 @@
# endif
#endif /* __NR_eventfd2 */
-#ifndef __NR_epoll_create
-# if defined(__x86_64__)
-# define __NR_epoll_create 213
-# elif defined(__i386__)
-# define __NR_epoll_create 254
-# elif defined(__arm__)
-# define __NR_epoll_create (UV_SYSCALL_BASE + 250)
-# endif
-#endif /* __NR_epoll_create */
-
-#ifndef __NR_epoll_create1
-# if defined(__x86_64__)
-# define __NR_epoll_create1 291
-# elif defined(__i386__)
-# define __NR_epoll_create1 329
-# elif defined(__arm__)
-# define __NR_epoll_create1 (UV_SYSCALL_BASE + 357)
-# endif
-#endif /* __NR_epoll_create1 */
-
-#ifndef __NR_epoll_ctl
-# if defined(__x86_64__)
-# define __NR_epoll_ctl 233 /* used to be 214 */
-# elif defined(__i386__)
-# define __NR_epoll_ctl 255
-# elif defined(__arm__)
-# define __NR_epoll_ctl (UV_SYSCALL_BASE + 251)
-# endif
-#endif /* __NR_epoll_ctl */
-
-#ifndef __NR_epoll_wait
-# if defined(__x86_64__)
-# define __NR_epoll_wait 232 /* used to be 215 */
-# elif defined(__i386__)
-# define __NR_epoll_wait 256
-# elif defined(__arm__)
-# define __NR_epoll_wait (UV_SYSCALL_BASE + 252)
-# endif
-#endif /* __NR_epoll_wait */
-
-#ifndef __NR_epoll_pwait
-# if defined(__x86_64__)
-# define __NR_epoll_pwait 281
-# elif defined(__i386__)
-# define __NR_epoll_pwait 319
-# elif defined(__arm__)
-# define __NR_epoll_pwait (UV_SYSCALL_BASE + 346)
-# endif
-#endif /* __NR_epoll_pwait */
-
#ifndef __NR_inotify_init
# if defined(__x86_64__)
# define __NR_inotify_init 253
@@ -285,76 +235,6 @@ int uv__eventfd2(unsigned int count, int flags) {
}
-int uv__epoll_create(int size) {
-#if defined(__NR_epoll_create)
- return syscall(__NR_epoll_create, size);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__epoll_create1(int flags) {
-#if defined(__NR_epoll_create1)
- return syscall(__NR_epoll_create1, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) {
-#if defined(__NR_epoll_ctl)
- return syscall(__NR_epoll_ctl, epfd, op, fd, events);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__epoll_wait(int epfd,
- struct uv__epoll_event* events,
- int nevents,
- int timeout) {
-#if defined(__NR_epoll_wait)
- int result;
- result = syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
-#if MSAN_ACTIVE
- if (result > 0)
- __msan_unpoison(events, sizeof(events[0]) * result);
-#endif
- return result;
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__epoll_pwait(int epfd,
- struct uv__epoll_event* events,
- int nevents,
- int timeout,
- uint64_t sigmask) {
-#if defined(__NR_epoll_pwait)
- int result;
- result = syscall(__NR_epoll_pwait,
- epfd,
- events,
- nevents,
- timeout,
- &sigmask,
- sizeof(sigmask));
-#if MSAN_ACTIVE
- if (result > 0)
- __msan_unpoison(events, sizeof(events[0]) * result);
-#endif
- return result;
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
int uv__inotify_init(void) {
#if defined(__NR_inotify_init)
return syscall(__NR_inotify_init);
@@ -431,19 +311,6 @@ int uv__recvmmsg(int fd,
}
-int uv__utimesat(int dirfd,
- const char* path,
- const struct timespec times[2],
- int flags)
-{
-#if defined(__NR_utimensat)
- return syscall(__NR_utimensat, dirfd, path, times, flags);
-#else
- return errno = ENOSYS, -1;
-#endif
-}
-
-
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
#if defined(__NR_preadv)
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
diff --git a/Utilities/cmlibuv/src/unix/linux-syscalls.h b/Utilities/cmlibuv/src/unix/linux-syscalls.h
index 4c095e9..3dfd329 100644
--- a/Utilities/cmlibuv/src/unix/linux-syscalls.h
+++ b/Utilities/cmlibuv/src/unix/linux-syscalls.h
@@ -66,12 +66,6 @@
# define UV__SOCK_NONBLOCK UV__O_NONBLOCK
#endif
-/* epoll flags */
-#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC
-#define UV__EPOLL_CTL_ADD 1
-#define UV__EPOLL_CTL_DEL 2
-#define UV__EPOLL_CTL_MOD 3
-
/* inotify flags */
#define UV__IN_ACCESS 0x001
#define UV__IN_MODIFY 0x002
@@ -86,18 +80,6 @@
#define UV__IN_DELETE_SELF 0x400
#define UV__IN_MOVE_SELF 0x800
-#if defined(__x86_64__)
-struct uv__epoll_event {
- uint32_t events;
- uint64_t data;
-} __attribute__((packed));
-#else
-struct uv__epoll_event {
- uint32_t events;
- uint64_t data;
-};
-#endif
-
struct uv__inotify_event {
int32_t wd;
uint32_t mask;
@@ -113,18 +95,6 @@ struct uv__mmsghdr {
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
int uv__eventfd(unsigned int count);
-int uv__epoll_create(int size);
-int uv__epoll_create1(int flags);
-int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event *ev);
-int uv__epoll_wait(int epfd,
- struct uv__epoll_event* events,
- int nevents,
- int timeout);
-int uv__epoll_pwait(int epfd,
- struct uv__epoll_event* events,
- int nevents,
- int timeout,
- uint64_t sigmask);
int uv__eventfd2(unsigned int count, int flags);
int uv__inotify_init(void);
int uv__inotify_init1(int flags);
@@ -140,10 +110,6 @@ int uv__sendmmsg(int fd,
struct uv__mmsghdr* mmsg,
unsigned int vlen,
unsigned int flags);
-int uv__utimesat(int dirfd,
- const char* path,
- const struct timespec times[2],
- int flags);
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
int uv__dup3(int oldfd, int newfd, int flags);
diff --git a/Utilities/cmlibuv/src/unix/loop.c b/Utilities/cmlibuv/src/unix/loop.c
index 99ead6c..c2a03d7 100644
--- a/Utilities/cmlibuv/src/unix/loop.c
+++ b/Utilities/cmlibuv/src/unix/loop.c
@@ -20,7 +20,7 @@
*/
#include "uv.h"
-#include "tree.h"
+#include "uv/tree.h"
#include "internal.h"
#include "heap-inl.h"
#include <stdlib.h>
@@ -74,7 +74,7 @@ int uv_loop_init(uv_loop_t* loop) {
goto fail_signal_init;
uv__handle_unref(&loop->child_watcher);
- loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
+ loop->child_watcher.flags |= UV_HANDLE_INTERNAL;
QUEUE_INIT(&loop->process_handles);
err = uv_rwlock_init(&loop->cloexec_lock);
@@ -90,7 +90,7 @@ int uv_loop_init(uv_loop_t* loop) {
goto fail_async_init;
uv__handle_unref(&loop->wq_async);
- loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+ loop->wq_async.flags |= UV_HANDLE_INTERNAL;
return 0;
diff --git a/Utilities/cmlibuv/src/unix/netbsd.c b/Utilities/cmlibuv/src/unix/netbsd.c
index 2605c11..a2a4e52 100644
--- a/Utilities/cmlibuv/src/unix/netbsd.c
+++ b/Utilities/cmlibuv/src/unix/netbsd.c
@@ -40,15 +40,6 @@
#include <unistd.h>
#include <time.h>
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
@@ -96,7 +87,8 @@ int uv_exepath(char* buffer, size_t* size) {
/* Copy string from the intermediate buffer to outer one with appropriate
* length.
*/
- strlcpy(buffer, int_buf, *size);
+ /* TODO(bnoordhuis) Check uv__strscpy() return value. */
+ uv__strscpy(buffer, int_buf, *size);
/* Set new size. */
*size = strlen(buffer);
@@ -134,65 +126,6 @@ uint64_t uv_get_total_memory(void) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
- setproctitle("%s", title);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
-
int uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;
diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c
index ce937cd..bffb58b 100644
--- a/Utilities/cmlibuv/src/unix/openbsd.c
+++ b/Utilities/cmlibuv/src/unix/openbsd.c
@@ -36,16 +36,6 @@
#include <unistd.h>
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
}
@@ -146,65 +136,6 @@ uint64_t uv_get_total_memory(void) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
- setproctitle("%s", title);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
-
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size = getpagesize();
diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.c b/Utilities/cmlibuv/src/unix/os390-syscalls.c
index a5dd344..1040d66 100644
--- a/Utilities/cmlibuv/src/unix/os390-syscalls.c
+++ b/Utilities/cmlibuv/src/unix/os390-syscalls.c
@@ -141,7 +141,7 @@ static void init_message_queue(uv__os390_epoll* lst) {
} msg;
/* initialize message queue */
- lst->msg_queue = msgget(IPC_PRIVATE, 0622 | IPC_CREAT);
+ lst->msg_queue = msgget(IPC_PRIVATE, 0600 | IPC_CREAT);
if (lst->msg_queue == -1)
abort();
@@ -255,12 +255,13 @@ int epoll_ctl(uv__os390_epoll* lst,
lst->items[fd].events = event->events;
lst->items[fd].revents = 0;
} else if (op == EPOLL_CTL_MOD) {
- if (fd >= lst->size || lst->items[fd].fd == -1) {
+ if (fd >= lst->size - 1 || lst->items[fd].fd == -1) {
uv_mutex_unlock(&global_epoll_lock);
errno = ENOENT;
return -1;
}
lst->items[fd].events = event->events;
+ lst->items[fd].revents = 0;
} else
abort();
@@ -275,8 +276,9 @@ int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events,
struct pollfd* pfds;
int pollret;
int reventcount;
+ int nevents;
- size = _SET_FDS_MSGS(size, 1, lst->size - 1);
+ _SET_FDS_MSGS(size, 1, lst->size - 1);
pfds = lst->items;
pollret = poll(pfds, size, timeout);
if (pollret <= 0)
@@ -285,19 +287,28 @@ int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events,
pollret = _NFDS(pollret) + _NMSGS(pollret);
reventcount = 0;
+ nevents = 0;
for (int i = 0;
i < lst->size && i < maxevents && reventcount < pollret; ++i) {
struct epoll_event ev;
+ struct pollfd* pfd;
- if (pfds[i].fd == -1 || pfds[i].revents == 0)
+ pfd = &pfds[i];
+ if (pfd->fd == -1 || pfd->revents == 0)
continue;
- ev.fd = pfds[i].fd;
- ev.events = pfds[i].revents;
- events[reventcount++] = ev;
+ ev.fd = pfd->fd;
+ ev.events = pfd->revents;
+ if (pfd->revents & POLLIN && pfd->revents & POLLOUT)
+ reventcount += 2;
+ else if (pfd->revents & (POLLIN | POLLOUT))
+ ++reventcount;
+
+ pfd->revents = 0;
+ events[nevents++] = ev;
}
- return reventcount;
+ return nevents;
}
@@ -493,7 +504,7 @@ ssize_t os390_readlink(const char* path, char* buf, size_t len) {
size_t strnlen(const char* str, size_t maxlen) {
- void* p = memchr(str, 0, maxlen);
+ char* p = memchr(str, 0, maxlen);
if (p == NULL)
return maxlen;
else
diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.h b/Utilities/cmlibuv/src/unix/os390-syscalls.h
index 6e34a88..ea59910 100644
--- a/Utilities/cmlibuv/src/unix/os390-syscalls.h
+++ b/Utilities/cmlibuv/src/unix/os390-syscalls.h
@@ -36,10 +36,6 @@
#define MAX_ITEMS_PER_EPOLL 1024
#define UV__O_CLOEXEC 0x80000
-#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC
-#define UV__EPOLL_CTL_ADD EPOLL_CTL_ADD
-#define UV__EPOLL_CTL_DEL EPOLL_CTL_DEL
-#define UV__EPOLL_CTL_MOD EPOLL_CTL_MOD
struct epoll_event {
int events;
diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c
index f766b39..dc146e3 100644
--- a/Utilities/cmlibuv/src/unix/os390.c
+++ b/Utilities/cmlibuv/src/unix/os390.c
@@ -229,15 +229,15 @@ static int getexe(const int pid, char* buf, size_t len) {
assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A');
/* Get the offset from the lowest 3 bytes */
- Output_path = (char*)(&Output_buf) +
- (Output_buf.Output_data.offsetPath & 0x00FFFFFF);
+ Output_path = (struct Output_path_type*) ((char*) (&Output_buf) +
+ (Output_buf.Output_data.offsetPath & 0x00FFFFFF));
if (Output_path->len >= len) {
errno = ENOBUFS;
return -1;
}
- strncpy(buf, Output_path->path, len);
+ uv__strscpy(buf, Output_path->path, len);
return 0;
}
@@ -357,13 +357,11 @@ uint64_t uv_get_total_memory(void) {
int uv_resident_set_memory(size_t* rss) {
- char* psa;
char* ascb;
char* rax;
size_t nframes;
- psa = PSA_PTR;
- ascb = *(char* __ptr32 *)(psa + PSAAOLD);
+ ascb = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);
rax = *(char* __ptr32 *)(ascb + ASCBRSME);
nframes = *(unsigned int*)(rax + RAXFMCT);
@@ -512,7 +510,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
/* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
address->is_internal = flg.__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
-
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
address++;
}
@@ -531,12 +529,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifreq* p;
int count_v6;
+ *count = 0;
+ *addresses = NULL;
+
/* get the ipv6 addresses first */
uv_interface_address_t* addresses_v6;
uv__interface_addresses_v6(&addresses_v6, &count_v6);
/* now get the ipv4 addresses */
- *count = 0;
/* Assume maximum buffer size allowable */
maxsize = 16384;
@@ -578,6 +578,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ uv__close(sockfd);
+ return 0;
+ }
+
/* Alloc the return interface structs */
*addresses = uv__malloc((*count + count_v6) *
sizeof(uv_interface_address_t));
@@ -624,6 +629,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
address++;
}
@@ -662,7 +668,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
/* Remove the file descriptor from the epoll. */
if (loop->ep != NULL)
- epoll_ctl(loop->ep, UV__EPOLL_CTL_DEL, fd, &dummy);
+ epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy);
}
@@ -751,7 +757,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
sizeof(handle->rfis_rftok));
- /*
+ /*
* This call will take "/" as the path argument in case we
* don't care to supply the correct path. The system will simply
* ignore it.
@@ -838,9 +844,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
e.fd = w->fd;
if (w->events == 0)
- op = UV__EPOLL_CTL_ADD;
+ op = EPOLL_CTL_ADD;
else
- op = UV__EPOLL_CTL_MOD;
+ op = EPOLL_CTL_MOD;
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
* events, skip the syscall and squelch the events after epoll_wait().
@@ -849,10 +855,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (errno != EEXIST)
abort();
- assert(op == UV__EPOLL_CTL_ADD);
+ assert(op == EPOLL_CTL_ADD);
/* We've reactivated a file descriptor that's been watched before. */
- if (epoll_ctl(loop->ep, UV__EPOLL_CTL_MOD, w->fd, &e))
+ if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e))
abort();
}
@@ -934,7 +940,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* Ignore all errors because we may be racing with another thread
* when the file descriptor is closed.
*/
- epoll_ctl(loop->ep, UV__EPOLL_CTL_DEL, fd, pe);
+ epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe);
continue;
}
@@ -987,7 +993,7 @@ void uv__set_process_title(const char* title) {
}
int uv__io_fork(uv_loop_t* loop) {
- /*
+ /*
Nullify the msg queue but don't close it because
it is still being used by the parent.
*/
diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c
index 42846b9..9657bc9 100644
--- a/Utilities/cmlibuv/src/unix/pipe.c
+++ b/Utilities/cmlibuv/src/unix/pipe.c
@@ -64,8 +64,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
sockfd = err;
memset(&saddr, 0, sizeof saddr);
- strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1);
- saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
+ uv__strscpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path));
saddr.sun_family = AF_UNIX;
if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
@@ -130,7 +129,20 @@ void uv__pipe_close(uv_pipe_t* handle) {
int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
+ int flags;
+ int mode;
int err;
+ flags = 0;
+
+ if (uv__fd_exists(handle->loop, fd))
+ return UV_EEXIST;
+
+ do
+ mode = fcntl(fd, F_GETFL);
+ while (mode == -1 && errno == EINTR);
+
+ if (mode == -1)
+ return UV__ERR(errno); /* according to docs, must be EBADF */
err = uv__nonblock(fd, 1);
if (err)
@@ -142,9 +154,13 @@ int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
return err;
#endif /* defined(__APPLE__) */
- return uv__stream_open((uv_stream_t*)handle,
- fd,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ mode &= O_ACCMODE;
+ if (mode != O_WRONLY)
+ flags |= UV_HANDLE_READABLE;
+ if (mode != O_RDONLY)
+ flags |= UV_HANDLE_WRITABLE;
+
+ return uv__stream_open((uv_stream_t*)handle, fd, flags);
}
@@ -167,8 +183,7 @@ void uv_pipe_connect(uv_connect_t* req,
}
memset(&saddr, 0, sizeof saddr);
- strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1);
- saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
+ uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path));
saddr.sun_family = AF_UNIX;
do {
@@ -194,7 +209,7 @@ void uv_pipe_connect(uv_connect_t* req,
if (new_sock) {
err = uv__stream_open((uv_stream_t*)handle,
uv__stream_fd(handle),
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
}
if (err == 0)
diff --git a/Utilities/cmlibuv/src/unix/poll.c b/Utilities/cmlibuv/src/unix/poll.c
index f3b0bf4..3d5022b 100644
--- a/Utilities/cmlibuv/src/unix/poll.c
+++ b/Utilities/cmlibuv/src/unix/poll.c
@@ -68,6 +68,9 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
int err;
+ if (uv__fd_exists(loop, fd))
+ return UV_EEXIST;
+
err = uv__io_check_fd(loop, fd);
if (err)
return err;
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index f2a5065..e9579f5 100644
--- a/Utilities/cmlibuv/src/unix/process.c
+++ b/Utilities/cmlibuv/src/unix/process.c
@@ -250,9 +250,9 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
flags = 0;
if (container->flags & UV_WRITABLE_PIPE)
- flags |= UV_STREAM_READABLE;
+ flags |= UV_HANDLE_READABLE;
if (container->flags & UV_READABLE_PIPE)
- flags |= UV_STREAM_WRITABLE;
+ flags |= UV_HANDLE_WRITABLE;
return uv__stream_open(container->data.stream, pipefds[0], flags);
}
diff --git a/Utilities/cmlibuv/src/unix/proctitle.c b/Utilities/cmlibuv/src/unix/proctitle.c
index 1a8c7a7..a5ce203 100644
--- a/Utilities/cmlibuv/src/unix/proctitle.c
+++ b/Utilities/cmlibuv/src/unix/proctitle.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
+extern void uv__set_process_title_platform_init(void);
extern void uv__set_process_title(const char* title);
static uv_mutex_t process_title_mutex;
@@ -38,6 +39,9 @@ static struct {
static void init_process_title_mutex_once(void) {
uv_mutex_init(&process_title_mutex);
+#ifdef __APPLE__
+ uv__set_process_title_platform_init();
+#endif
}
diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c
index b9d0a56..01aa55f 100644
--- a/Utilities/cmlibuv/src/unix/signal.c
+++ b/Utilities/cmlibuv/src/unix/signal.c
@@ -54,8 +54,7 @@ static void uv__signal_unregister_handler(int signum);
static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
static struct uv__signal_tree_s uv__signal_tree =
RB_INITIALIZER(uv__signal_tree);
-static int uv__signal_lock_pipefd[2];
-
+static int uv__signal_lock_pipefd[2] = { -1, -1 };
RB_GENERATE_STATIC(uv__signal_tree_s,
uv_signal_s, tree_entry,
@@ -64,7 +63,7 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
static void uv__signal_global_reinit(void);
static void uv__signal_global_init(void) {
- if (!uv__signal_lock_pipefd[0])
+ if (uv__signal_lock_pipefd[0] == -1)
/* 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
@@ -74,15 +73,11 @@ static void uv__signal_global_init(void) {
if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
abort();
- if (uv__make_pipe(uv__signal_lock_pipefd, 0))
- abort();
-
- if (uv__signal_unlock())
- abort();
+ uv__signal_global_reinit();
}
-static void uv__signal_global_reinit(void) {
+UV_DESTRUCTOR(static void uv__signal_global_fini(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
@@ -90,11 +85,26 @@ static void uv__signal_global_reinit(void) {
* 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();
+ if (uv__signal_lock_pipefd[0] != -1) {
+ uv__close(uv__signal_lock_pipefd[0]);
+ uv__signal_lock_pipefd[0] = -1;
+ }
+
+ if (uv__signal_lock_pipefd[1] != -1) {
+ uv__close(uv__signal_lock_pipefd[1]);
+ uv__signal_lock_pipefd[1] = -1;
+ }
+}
+
+
+static void uv__signal_global_reinit(void) {
+ uv__signal_global_fini();
+
+ if (uv__make_pipe(uv__signal_lock_pipefd, 0))
+ abort();
+
+ if (uv__signal_unlock())
+ abort();
}
@@ -103,7 +113,6 @@ void uv__signal_global_once_init(void) {
}
-
static int uv__signal_lock(void) {
int r;
char data;
@@ -387,7 +396,7 @@ static int uv__signal_start(uv_signal_t* handle,
*/
first_handle = uv__signal_first_handle(signum);
if (first_handle == NULL ||
- (!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) {
+ (!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. */
@@ -398,7 +407,7 @@ static int uv__signal_start(uv_signal_t* handle,
handle->signum = signum;
if (oneshot)
- handle->flags |= UV__SIGNAL_ONE_SHOT;
+ handle->flags |= UV_SIGNAL_ONE_SHOT;
RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
@@ -455,20 +464,20 @@ static void uv__signal_event(uv_loop_t* loop,
handle = msg->handle;
if (msg->signum == handle->signum) {
- assert(!(handle->flags & UV_CLOSING));
+ assert(!(handle->flags & UV_HANDLE_CLOSING));
handle->signal_cb(handle, handle->signum);
}
handle->dispatched_signals++;
- if (handle->flags & UV__SIGNAL_ONE_SHOT)
+ 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.
*/
- if ((handle->flags & UV_CLOSING) &&
+ if ((handle->flags & UV_HANDLE_CLOSING) &&
(handle->caught_signals == handle->dispatched_signals)) {
uv__make_close_pending((uv_handle_t*) handle);
}
@@ -496,11 +505,11 @@ static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
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
+ /* 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;
+ f1 = w1->flags & UV_SIGNAL_ONE_SHOT;
+ f2 = w2->flags & UV_SIGNAL_ONE_SHOT;
if (f1 < f2) return -1;
if (f1 > f2) return 1;
@@ -549,8 +558,8 @@ static void uv__signal_stop(uv_signal_t* handle) {
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;
+ 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);
diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c
index 9bdd1c5..4b9123f 100644
--- a/Utilities/cmlibuv/src/unix/stream.c
+++ b/Utilities/cmlibuv/src/unix/stream.c
@@ -58,11 +58,19 @@ struct uv__stream_select_s {
fd_set* swrite;
size_t swrite_sz;
};
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+
+/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
+ * EPROTOTYPE can be returned while trying to write to a socket that is
+ * shutting down. If we retry the write, we should get the expected EPIPE
+ * instead.
+ */
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
- (errno == EMSGSIZE && send_handle))
+ (errno == EMSGSIZE && send_handle != NULL))
#else
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
#endif /* defined(__APPLE__) */
@@ -220,7 +228,7 @@ static void uv__stream_osx_select(void* arg) {
uv_sem_wait(&s->async_sem);
/* Should be processed at this stage */
- assert((s->events == 0) || (stream->flags & UV_CLOSING));
+ assert((s->events == 0) || (stream->flags & UV_HANDLE_CLOSING));
}
}
}
@@ -248,7 +256,7 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) {
if ((events & POLLOUT) && uv__io_active(&stream->io_watcher, POLLOUT))
uv__stream_io(stream->loop, &stream->io_watcher, POLLOUT);
- if (stream->flags & UV_CLOSING)
+ if (stream->flags & UV_HANDLE_CLOSING)
return;
/* NOTE: It is important to do it here, otherwise `select()` might be called
@@ -342,7 +350,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
if (err)
goto failed_async_init;
- s->async.flags |= UV__HANDLE_INTERNAL;
+ s->async.flags |= UV_HANDLE_INTERNAL;
uv__handle_unref(&s->async);
err = uv_sem_init(&s->close_sem, 0);
@@ -407,12 +415,14 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
stream->flags |= flags;
if (stream->type == UV_TCP) {
- if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
+ if ((stream->flags & UV_HANDLE_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
return UV__ERR(errno);
/* TODO Use delay the user passed in. */
- if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60))
+ if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
+ uv__tcp_keepalive(fd, 1, 60)) {
return UV__ERR(errno);
+ }
}
#if defined(__APPLE__)
@@ -447,7 +457,7 @@ void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
void uv__stream_destroy(uv_stream_t* stream) {
assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT));
- assert(stream->flags & UV_CLOSED);
+ assert(stream->flags & UV_HANDLE_CLOSED);
if (stream->connect_req) {
uv__req_unregister(stream->loop, stream->connect_req);
@@ -522,7 +532,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
stream = container_of(w, uv_stream_t, io_watcher);
assert(events & POLLIN);
assert(stream->accepted_fd == -1);
- assert(!(stream->flags & UV_CLOSING));
+ assert(!(stream->flags & UV_HANDLE_CLOSING));
uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
@@ -565,7 +575,8 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
return;
}
- if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) {
+ if (stream->type == UV_TCP &&
+ (stream->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
/* Give other processes a chance to accept connections. */
struct timespec timeout = { 0, 1 };
nanosleep(&timeout, NULL);
@@ -590,7 +601,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
case UV_TCP:
err = uv__stream_open(client,
server->accepted_fd,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
if (err) {
/* TODO handle error */
uv__close(server->accepted_fd);
@@ -674,14 +685,14 @@ static void uv__drain(uv_stream_t* stream) {
uv__stream_osx_interrupt_select(stream);
/* Shutdown? */
- if ((stream->flags & UV_STREAM_SHUTTING) &&
- !(stream->flags & UV_CLOSING) &&
- !(stream->flags & UV_STREAM_SHUT)) {
+ if ((stream->flags & UV_HANDLE_SHUTTING) &&
+ !(stream->flags & UV_HANDLE_CLOSING) &&
+ !(stream->flags & UV_HANDLE_SHUT)) {
assert(stream->shutdown_req);
req = stream->shutdown_req;
stream->shutdown_req = NULL;
- stream->flags &= ~UV_STREAM_SHUTTING;
+ stream->flags &= ~UV_HANDLE_SHUTTING;
uv__req_unregister(stream->loop, req);
err = 0;
@@ -689,7 +700,7 @@ static void uv__drain(uv_stream_t* stream) {
err = UV__ERR(errno);
if (err == 0)
- stream->flags |= UV_STREAM_SHUT;
+ stream->flags |= UV_HANDLE_SHUT;
if (req->cb != NULL)
req->cb(req, err);
@@ -697,6 +708,14 @@ static void uv__drain(uv_stream_t* stream) {
}
+static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) {
+ if (n == 1)
+ return write(fd, vec->iov_base, vec->iov_len);
+ else
+ return writev(fd, vec, n);
+}
+
+
static size_t uv__write_req_size(uv_write_t* req) {
size_t size;
@@ -709,6 +728,37 @@ static size_t uv__write_req_size(uv_write_t* req) {
}
+/* Returns 1 if all write request data has been written, or 0 if there is still
+ * more data to write.
+ *
+ * Note: the return value only says something about the *current* request.
+ * There may still be other write requests sitting in the queue.
+ */
+static int uv__write_req_update(uv_stream_t* stream,
+ uv_write_t* req,
+ size_t n) {
+ uv_buf_t* buf;
+ size_t len;
+
+ assert(n <= stream->write_queue_size);
+ stream->write_queue_size -= n;
+
+ buf = req->bufs + req->write_index;
+
+ while (n > 0) {
+ len = n < buf->len ? n : buf->len;
+ buf->base += len;
+ buf->len -= len;
+ buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */
+ n -= len;
+ }
+
+ req->write_index = buf - req->bufs;
+
+ return req->write_index == req->nbufs;
+}
+
+
static void uv__write_req_finish(uv_write_t* req) {
uv_stream_t* stream = req->handle;
@@ -829,102 +879,32 @@ start:
*pi = fd_to_send;
}
- do {
+ do
n = sendmsg(uv__stream_fd(stream), &msg, 0);
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- } else {
- do {
- if (iovcnt == 1) {
- n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len);
- } else {
- n = writev(uv__stream_fd(stream), iov, iovcnt);
- }
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- }
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
- if (n < 0) {
- if (!WRITE_RETRY_ON_ERROR(req->send_handle)) {
- err = UV__ERR(errno);
- goto error;
- } else if (stream->flags & UV_STREAM_BLOCKING) {
- /* If this is a blocking stream, try again. */
- goto start;
- }
+ /* Ensure the handle isn't sent again in case this is a partial write. */
+ if (n >= 0)
+ req->send_handle = NULL;
} else {
- /* Successful write */
-
- while (n >= 0) {
- uv_buf_t* buf = &(req->bufs[req->write_index]);
- size_t len = buf->len;
-
- assert(req->write_index < req->nbufs);
-
- if ((size_t)n < len) {
- buf->base += n;
- buf->len -= n;
- stream->write_queue_size -= n;
- n = 0;
-
- /* There is more to write. */
- if (stream->flags & UV_STREAM_BLOCKING) {
- /*
- * If we're blocking then we should not be enabling the write
- * watcher - instead we need to try again.
- */
- goto start;
- } else {
- /* Break loop and ensure the watcher is pending. */
- break;
- }
-
- } else {
- /* Finished writing the buf at index req->write_index. */
- req->write_index++;
-
- assert((size_t)n >= len);
- n -= len;
-
- assert(stream->write_queue_size >= len);
- stream->write_queue_size -= len;
+ do
+ n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
+ }
- if (req->write_index == req->nbufs) {
- /* Then we're done! */
- assert(n == 0);
- uv__write_req_finish(req);
- /* TODO: start trying to write the next request. */
- return;
- }
- }
- }
+ if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) {
+ err = UV__ERR(errno);
+ goto error;
}
- /* Either we've counted n down to zero or we've got EAGAIN. */
- assert(n == 0 || n == -1);
+ if (n > 0 && uv__write_req_update(stream, req, n)) {
+ uv__write_req_finish(req);
+ return; /* TODO(bnoordhuis) Start trying to write the next request. */
+ }
- /* Only non-blocking streams should use the write_watcher. */
- assert(!(stream->flags & UV_STREAM_BLOCKING));
+ /* If this is a blocking stream, try again. */
+ if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
+ goto start;
/* We're not done. */
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
@@ -947,10 +927,16 @@ error:
static void uv__write_callbacks(uv_stream_t* stream) {
uv_write_t* req;
QUEUE* q;
+ QUEUE pq;
+
+ if (QUEUE_EMPTY(&stream->write_completed_queue))
+ return;
+
+ QUEUE_MOVE(&stream->write_completed_queue, &pq);
- while (!QUEUE_EMPTY(&stream->write_completed_queue)) {
+ while (!QUEUE_EMPTY(&pq)) {
/* Pop a req off write_completed_queue. */
- q = QUEUE_HEAD(&stream->write_completed_queue);
+ q = QUEUE_HEAD(&pq);
req = QUEUE_DATA(q, uv_write_t, queue);
QUEUE_REMOVE(q);
uv__req_unregister(stream->loop, req);
@@ -966,8 +952,6 @@ static void uv__write_callbacks(uv_stream_t* stream) {
if (req->cb)
req->cb(req, req->error);
}
-
- assert(QUEUE_EMPTY(&stream->write_completed_queue));
}
@@ -1015,13 +999,13 @@ uv_handle_type uv__handle_type(int fd) {
static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
- stream->flags |= UV_STREAM_READ_EOF;
+ stream->flags |= UV_HANDLE_READ_EOF;
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
uv__stream_osx_interrupt_select(stream);
stream->read_cb(stream, UV_EOF, buf);
- stream->flags &= ~UV_STREAM_READING;
+ stream->flags &= ~UV_HANDLE_READING;
}
@@ -1121,6 +1105,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wgnu-folding-constant"
+# pragma clang diagnostic ignored "-Wvla-extension"
#endif
static void uv__read(uv_stream_t* stream) {
@@ -1132,7 +1117,7 @@ static void uv__read(uv_stream_t* stream) {
int err;
int is_ipc;
- stream->flags &= ~UV_STREAM_READ_PARTIAL;
+ stream->flags &= ~UV_HANDLE_READ_PARTIAL;
/* Prevent loop starvation when the data comes in as fast as (or faster than)
* we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
@@ -1141,11 +1126,11 @@ static void uv__read(uv_stream_t* stream) {
is_ipc = stream->type == UV_NAMED_PIPE && ((uv_pipe_t*) stream)->ipc;
- /* XXX: Maybe instead of having UV_STREAM_READING we just test if
+ /* XXX: Maybe instead of having UV_HANDLE_READING we just test if
* tcp->read_cb is NULL or not?
*/
while (stream->read_cb
- && (stream->flags & UV_STREAM_READING)
+ && (stream->flags & UV_HANDLE_READING)
&& (count-- > 0)) {
assert(stream->alloc_cb != NULL);
@@ -1186,7 +1171,7 @@ static void uv__read(uv_stream_t* stream) {
/* Error */
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Wait for the next one. */
- if (stream->flags & UV_STREAM_READING) {
+ if (stream->flags & UV_HANDLE_READING) {
uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
uv__stream_osx_interrupt_select(stream);
}
@@ -1199,8 +1184,8 @@ static void uv__read(uv_stream_t* stream) {
} else {
/* Error. User should call uv_close(). */
stream->read_cb(stream, UV__ERR(errno), &buf);
- if (stream->flags & UV_STREAM_READING) {
- stream->flags &= ~UV_STREAM_READING;
+ if (stream->flags & UV_HANDLE_READING) {
+ stream->flags &= ~UV_HANDLE_READING;
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
@@ -1250,7 +1235,7 @@ static void uv__read(uv_stream_t* stream) {
/* Return if we didn't fill the buffer, there is no more data to read. */
if (nread < buflen) {
- stream->flags |= UV_STREAM_READ_PARTIAL;
+ stream->flags |= UV_HANDLE_READ_PARTIAL;
return;
}
}
@@ -1271,9 +1256,9 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
stream->type == UV_TTY ||
stream->type == UV_NAMED_PIPE);
- if (!(stream->flags & UV_STREAM_WRITABLE) ||
- stream->flags & UV_STREAM_SHUT ||
- stream->flags & UV_STREAM_SHUTTING ||
+ if (!(stream->flags & UV_HANDLE_WRITABLE) ||
+ stream->flags & UV_HANDLE_SHUT ||
+ stream->flags & UV_HANDLE_SHUTTING ||
uv__is_closing(stream)) {
return UV_ENOTCONN;
}
@@ -1285,7 +1270,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
req->handle = stream;
req->cb = cb;
stream->shutdown_req = req;
- stream->flags |= UV_STREAM_SHUTTING;
+ stream->flags |= UV_HANDLE_SHUTTING;
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
@@ -1302,7 +1287,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(stream->type == UV_TCP ||
stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
- assert(!(stream->flags & UV_CLOSING));
+ assert(!(stream->flags & UV_HANDLE_CLOSING));
if (stream->connect_req) {
uv__stream_connect(stream);
@@ -1311,7 +1296,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(uv__stream_fd(stream) >= 0);
- /* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
+ /* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
if (events & (POLLIN | POLLERR | POLLHUP))
uv__read(stream);
@@ -1325,9 +1310,9 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
* report the EOF yet because there is still data to read.
*/
if ((events & POLLHUP) &&
- (stream->flags & UV_STREAM_READING) &&
- (stream->flags & UV_STREAM_READ_PARTIAL) &&
- !(stream->flags & UV_STREAM_READ_EOF)) {
+ (stream->flags & UV_HANDLE_READING) &&
+ (stream->flags & UV_HANDLE_READ_PARTIAL) &&
+ !(stream->flags & UV_HANDLE_READ_EOF)) {
uv_buf_t buf = { NULL, 0 };
uv__stream_eof(stream, &buf);
}
@@ -1417,7 +1402,7 @@ int uv_write2(uv_write_t* req,
if (uv__stream_fd(stream) < 0)
return UV_EBADF;
- if (!(stream->flags & UV_STREAM_WRITABLE))
+ if (!(stream->flags & UV_HANDLE_WRITABLE))
return -EPIPE;
if (send_handle) {
@@ -1487,7 +1472,7 @@ int uv_write2(uv_write_t* req,
* if this assert fires then somehow the blocking stream isn't being
* sufficiently flushed in uv__write.
*/
- assert(!(stream->flags & UV_STREAM_BLOCKING));
+ assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES));
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
}
@@ -1568,16 +1553,16 @@ int uv_read_start(uv_stream_t* stream,
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
- if (stream->flags & UV_CLOSING)
+ if (stream->flags & UV_HANDLE_CLOSING)
return UV_EINVAL;
- if (!(stream->flags & UV_STREAM_READABLE))
+ if (!(stream->flags & UV_HANDLE_READABLE))
return -ENOTCONN;
- /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
+ /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just
* expresses the desired state of the user.
*/
- stream->flags |= UV_STREAM_READING;
+ stream->flags |= UV_HANDLE_READING;
/* TODO: try to do the read inline? */
/* TODO: keep track of tcp state. If we've gotten a EOF then we should
@@ -1598,10 +1583,10 @@ int uv_read_start(uv_stream_t* stream,
int uv_read_stop(uv_stream_t* stream) {
- if (!(stream->flags & UV_STREAM_READING))
+ if (!(stream->flags & UV_HANDLE_READING))
return 0;
- stream->flags &= ~UV_STREAM_READING;
+ stream->flags &= ~UV_HANDLE_READING;
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
@@ -1614,12 +1599,12 @@ int uv_read_stop(uv_stream_t* stream) {
int uv_is_readable(const uv_stream_t* stream) {
- return !!(stream->flags & UV_STREAM_READABLE);
+ return !!(stream->flags & UV_HANDLE_READABLE);
}
int uv_is_writable(const uv_stream_t* stream) {
- return !!(stream->flags & UV_STREAM_WRITABLE);
+ return !!(stream->flags & UV_HANDLE_WRITABLE);
}
@@ -1668,6 +1653,7 @@ void uv__stream_close(uv_stream_t* handle) {
uv__io_close(handle->loop, &handle->io_watcher);
uv_read_stop(handle);
uv__handle_stop(handle);
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
if (handle->io_watcher.fd != -1) {
/* Don't close stdio file descriptors. Nothing good comes from it. */
diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c
index b92888e..aac6504 100644
--- a/Utilities/cmlibuv/src/unix/sunos.c
+++ b/Utilities/cmlibuv/src/unix/sunos.c
@@ -696,6 +696,8 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
#ifdef SUNOS_NO_IFADDRS
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ *count = 0;
+ *addresses = NULL;
return UV_ENOSYS;
}
#else /* SUNOS_NO_IFADDRS */
@@ -709,13 +711,14 @@ static int uv__set_phys_addr(uv_interface_address_t* address,
struct sockaddr_dl* sa_addr;
int sockfd;
- int i;
+ size_t i;
struct arpreq arpreq;
/* This appears to only work as root */
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
for (i = 0; i < sizeof(address->phys_addr); i++) {
+ /* Check that all bytes of phys_addr are zero. */
if (address->phys_addr[i] != 0)
return 0;
}
@@ -762,11 +765,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs* addrs;
struct ifaddrs* ent;
+ *count = 0;
+ *addresses = NULL;
+
if (getifaddrs(&addrs))
return UV__ERR(errno);
- *count = 0;
-
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent))
@@ -774,6 +778,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ freeifaddrs(addrs);
+ return 0;
+ }
+
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
freeifaddrs(addrs);
diff --git a/Utilities/cmlibuv/src/unix/tcp.c b/Utilities/cmlibuv/src/unix/tcp.c
index 9a46793..2982851 100644
--- a/Utilities/cmlibuv/src/unix/tcp.c
+++ b/Utilities/cmlibuv/src/unix/tcp.c
@@ -216,7 +216,7 @@ int uv__tcp_connect(uv_connect_t* req,
err = maybe_new_socket(handle,
addr->sa_family,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
if (err)
return err;
@@ -263,13 +263,16 @@ int uv__tcp_connect(uv_connect_t* req,
int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
int err;
+ if (uv__fd_exists(handle->loop, sock))
+ return UV_EEXIST;
+
err = uv__nonblock(sock, 1);
if (err)
return err;
return uv__stream_open((uv_stream_t*)handle,
sock,
- UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
}
@@ -331,7 +334,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
}
if (single_accept)
- tcp->flags |= UV_TCP_SINGLE_ACCEPT;
+ tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
flags = 0;
#if defined(__MVS__)
@@ -398,9 +401,9 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
}
if (on)
- handle->flags |= UV_TCP_NODELAY;
+ handle->flags |= UV_HANDLE_TCP_NODELAY;
else
- handle->flags &= ~UV_TCP_NODELAY;
+ handle->flags &= ~UV_HANDLE_TCP_NODELAY;
return 0;
}
@@ -416,9 +419,9 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
}
if (on)
- handle->flags |= UV_TCP_KEEPALIVE;
+ handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
else
- handle->flags &= ~UV_TCP_KEEPALIVE;
+ handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
/* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
* uv_tcp_t with an int that's almost never used...
@@ -430,9 +433,9 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
if (enable)
- handle->flags &= ~UV_TCP_SINGLE_ACCEPT;
+ handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT;
else
- handle->flags |= UV_TCP_SINGLE_ACCEPT;
+ handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
return 0;
}
diff --git a/Utilities/cmlibuv/src/unix/thread.c b/Utilities/cmlibuv/src/unix/thread.c
index 303bc6e..2900470 100644
--- a/Utilities/cmlibuv/src/unix/thread.c
+++ b/Utilities/cmlibuv/src/unix/thread.c
@@ -44,108 +44,119 @@
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
+#if defined(PTHREAD_BARRIER_SERIAL_THREAD)
+STATIC_ASSERT(sizeof(uv_barrier_t) == sizeof(pthread_barrier_t));
+#endif
-#if defined(UV__PTHREAD_BARRIER_FALLBACK)
-/* TODO: support barrier_attr */
-int pthread_barrier_init(pthread_barrier_t* barrier,
- const void* barrier_attr,
- unsigned count) {
+/* Note: guard clauses should match uv_barrier_t's in include/uv/uv-unix.h. */
+#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ struct _uv_barrier* b;
int rc;
- _uv_barrier* b;
if (barrier == NULL || count == 0)
- return EINVAL;
-
- if (barrier_attr != NULL)
- return ENOTSUP;
+ return UV_EINVAL;
b = uv__malloc(sizeof(*b));
if (b == NULL)
- return ENOMEM;
+ return UV_ENOMEM;
b->in = 0;
b->out = 0;
b->threshold = count;
- if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0)
+ rc = uv_mutex_init(&b->mutex);
+ if (rc != 0)
goto error2;
- if ((rc = pthread_cond_init(&b->cond, NULL)) != 0)
+
+ rc = uv_cond_init(&b->cond);
+ if (rc != 0)
goto error;
barrier->b = b;
return 0;
error:
- pthread_mutex_destroy(&b->mutex);
+ uv_mutex_destroy(&b->mutex);
error2:
uv__free(b);
return rc;
}
-int pthread_barrier_wait(pthread_barrier_t* barrier) {
- int rc;
- _uv_barrier* b;
+
+int uv_barrier_wait(uv_barrier_t* barrier) {
+ struct _uv_barrier* b;
+ int last;
if (barrier == NULL || barrier->b == NULL)
- return EINVAL;
+ return UV_EINVAL;
b = barrier->b;
- /* Lock the mutex*/
- if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
- return rc;
+ uv_mutex_lock(&b->mutex);
- /* Increment the count. If this is the first thread to reach the threshold,
- wake up waiters, unlock the mutex, then return
- PTHREAD_BARRIER_SERIAL_THREAD. */
if (++b->in == b->threshold) {
b->in = 0;
- b->out = b->threshold - 1;
- rc = pthread_cond_signal(&b->cond);
- assert(rc == 0);
-
- pthread_mutex_unlock(&b->mutex);
- return PTHREAD_BARRIER_SERIAL_THREAD;
+ b->out = b->threshold;
+ uv_cond_signal(&b->cond);
+ } else {
+ do
+ uv_cond_wait(&b->cond, &b->mutex);
+ while (b->in != 0);
}
- /* Otherwise, wait for other threads until in is set to 0,
- then return 0 to indicate this is not the first thread. */
- do {
- if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0)
- break;
- } while (b->in != 0);
-
- /* mark thread exit */
- b->out--;
- pthread_cond_signal(&b->cond);
- pthread_mutex_unlock(&b->mutex);
- return rc;
+
+ last = (--b->out == 0);
+ if (!last)
+ uv_cond_signal(&b->cond); /* Not needed for last thread. */
+
+ uv_mutex_unlock(&b->mutex);
+ return last;
}
-int pthread_barrier_destroy(pthread_barrier_t* barrier) {
- int rc;
- _uv_barrier* b;
- if (barrier == NULL || barrier->b == NULL)
- return EINVAL;
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ struct _uv_barrier* b;
b = barrier->b;
+ uv_mutex_lock(&b->mutex);
- if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
- return rc;
+ assert(b->in == 0);
+ assert(b->out == 0);
- if (b->in > 0 || b->out > 0)
- rc = EBUSY;
-
- pthread_mutex_unlock(&b->mutex);
+ if (b->in != 0 || b->out != 0)
+ abort();
- if (rc)
- return rc;
+ uv_mutex_unlock(&b->mutex);
+ uv_mutex_destroy(&b->mutex);
+ uv_cond_destroy(&b->cond);
- pthread_cond_destroy(&b->cond);
- pthread_mutex_destroy(&b->mutex);
uv__free(barrier->b);
barrier->b = NULL;
- return 0;
}
+
+#else
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ return UV__ERR(pthread_barrier_init(barrier, NULL, count));
+}
+
+
+int uv_barrier_wait(uv_barrier_t* barrier) {
+ int rc;
+
+ rc = pthread_barrier_wait(barrier);
+ if (rc != 0)
+ if (rc != PTHREAD_BARRIER_SERIAL_THREAD)
+ abort();
+
+ return rc == PTHREAD_BARRIER_SERIAL_THREAD;
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ if (pthread_barrier_destroy(barrier))
+ abort();
+}
+
#endif
@@ -771,25 +782,6 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
}
-int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
- return UV__ERR(pthread_barrier_init(barrier, NULL, count));
-}
-
-
-void uv_barrier_destroy(uv_barrier_t* barrier) {
- if (pthread_barrier_destroy(barrier))
- abort();
-}
-
-
-int uv_barrier_wait(uv_barrier_t* barrier) {
- int r = pthread_barrier_wait(barrier);
- if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
- abort();
- return r == PTHREAD_BARRIER_SERIAL_THREAD;
-}
-
-
int uv_key_create(uv_key_t* key) {
return UV__ERR(pthread_key_create(key, NULL));
}
diff --git a/Utilities/cmlibuv/src/unix/tty.c b/Utilities/cmlibuv/src/unix/tty.c
index e8ea302..b8bc283 100644
--- a/Utilities/cmlibuv/src/unix/tty.c
+++ b/Utilities/cmlibuv/src/unix/tty.c
@@ -92,13 +92,15 @@ static int uv__tty_is_slave(const int fd) {
return result;
}
-int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
+int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
uv_handle_type type;
int flags = 0;
int newfd = -1;
int r;
int saved_flags;
+ int mode;
char path[256];
+ (void)unused; /* deprecated parameter is no longer needed */
/* File descriptors that refer to files cannot be monitored with epoll.
* That restriction also applies to character devices like /dev/random
@@ -108,6 +110,15 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
return UV_EINVAL;
+ /* Save the fd flags in case we need to restore them due to an error. */
+ do
+ saved_flags = fcntl(fd, F_GETFL);
+ while (saved_flags == -1 && errno == EINTR);
+
+ if (saved_flags == -1)
+ return UV__ERR(errno);
+ mode = saved_flags & O_ACCMODE;
+
/* Reopen the file descriptor when it refers to a tty. This lets us put the
* tty in non-blocking mode without affecting other processes that share it
* with us.
@@ -125,14 +136,14 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
* slave device.
*/
if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
- r = uv__open_cloexec(path, O_RDWR);
+ r = uv__open_cloexec(path, mode);
else
r = -1;
if (r < 0) {
/* fallback to using blocking writes */
- if (!readable)
- flags |= UV_STREAM_BLOCKING;
+ if (mode != O_RDONLY)
+ flags |= UV_HANDLE_BLOCKING_WRITES;
goto skip;
}
@@ -151,22 +162,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
fd = newfd;
}
-#if defined(__APPLE__)
- /* Save the fd flags in case we need to restore them due to an error. */
- do
- saved_flags = fcntl(fd, F_GETFL);
- while (saved_flags == -1 && errno == EINTR);
-
- if (saved_flags == -1) {
- if (newfd != -1)
- uv__close(newfd);
- return UV__ERR(errno);
- }
-#endif
-
- /* Pacify the compiler. */
- (void) &saved_flags;
-
skip:
uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
@@ -174,7 +169,7 @@ skip:
* the handle queue, since it was added by uv__handle_init in uv_stream_init.
*/
- if (!(flags & UV_STREAM_BLOCKING))
+ if (!(flags & UV_HANDLE_BLOCKING_WRITES))
uv__nonblock(fd, 1);
#if defined(__APPLE__)
@@ -191,10 +186,10 @@ skip:
}
#endif
- if (readable)
- flags |= UV_STREAM_READABLE;
- else
- flags |= UV_STREAM_WRITABLE;
+ if (mode != O_WRONLY)
+ flags |= UV_HANDLE_READABLE;
+ if (mode != O_RDONLY)
+ flags |= UV_HANDLE_WRITABLE;
uv__stream_open((uv_stream_t*) tty, fd, flags);
tty->mode = UV_TTY_MODE_NORMAL;
diff --git a/Utilities/cmlibuv/src/unix/udp.c b/Utilities/cmlibuv/src/unix/udp.c
index 74d613b..ec337ec 100644
--- a/Utilities/cmlibuv/src/unix/udp.c
+++ b/Utilities/cmlibuv/src/unix/udp.c
@@ -92,8 +92,8 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
uv_udp_send_t* req;
QUEUE* q;
- assert(!(handle->flags & UV_UDP_PROCESSING));
- handle->flags |= UV_UDP_PROCESSING;
+ assert(!(handle->flags & UV_HANDLE_UDP_PROCESSING));
+ handle->flags |= UV_HANDLE_UDP_PROCESSING;
while (!QUEUE_EMPTY(&handle->write_completed_queue)) {
q = QUEUE_HEAD(&handle->write_completed_queue);
@@ -128,7 +128,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
uv__handle_stop(handle);
}
- handle->flags &= ~UV_UDP_PROCESSING;
+ handle->flags &= ~UV_HANDLE_UDP_PROCESSING;
}
@@ -427,7 +427,7 @@ int uv__udp_send(uv_udp_send_t* req,
QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue);
uv__handle_start(handle);
- if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
+ if (empty_queue && !(handle->flags & UV_HANDLE_UDP_PROCESSING)) {
uv__udp_sendmsg(handle);
/* `uv__udp_sendmsg` may not be able to do non-blocking write straight
@@ -624,6 +624,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (handle->io_watcher.fd != -1)
return UV_EBUSY;
+ if (uv__fd_exists(handle->loop, sock))
+ return UV_EEXIST;
+
err = uv__nonblock(sock, 1);
if (err)
return err;
@@ -757,14 +760,16 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
* IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
@@ -780,14 +785,16 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
* IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
&on,
sizeof(on));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) ||
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
diff --git a/Utilities/cmlibuv/src/uv-common.c b/Utilities/cmlibuv/src/uv-common.c
index 15dec08..907ebf2 100644
--- a/Utilities/cmlibuv/src/uv-common.c
+++ b/Utilities/cmlibuv/src/uv-common.c
@@ -72,7 +72,9 @@ char* uv__strndup(const char* s, size_t n) {
}
void* uv__malloc(size_t size) {
- return uv__allocator.local_malloc(size);
+ if (size > 0)
+ return uv__allocator.local_malloc(size);
+ return NULL;
}
void uv__free(void* ptr) {
@@ -91,7 +93,10 @@ void* uv__calloc(size_t count, size_t size) {
}
void* uv__realloc(void* ptr, size_t size) {
- return uv__allocator.local_realloc(ptr, size);
+ if (size > 0)
+ return uv__allocator.local_realloc(ptr, size);
+ uv__free(ptr);
+ return NULL;
}
int uv_replace_allocator(uv_malloc_func malloc_func,
@@ -155,6 +160,18 @@ static const char* uv__unknown_err_code(int err) {
return copy != NULL ? copy : "Unknown system error";
}
+#define UV_ERR_NAME_GEN_R(name, _) \
+case UV_## name: \
+ uv__strscpy(buf, #name, buflen); break;
+char* uv_err_name_r(int err, char* buf, size_t buflen) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_ERR_NAME_GEN_R)
+ default: snprintf(buf, buflen, "Unknown system error %d", err);
+ }
+ return buf;
+}
+#undef UV_ERR_NAME_GEN_R
+
#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
const char* uv_err_name(int err) {
@@ -166,6 +183,19 @@ const char* uv_err_name(int err) {
#undef UV_ERR_NAME_GEN
+#define UV_STRERROR_GEN_R(name, msg) \
+case UV_ ## name: \
+ snprintf(buf, buflen, "%s", msg); break;
+char* uv_strerror_r(int err, char* buf, size_t buflen) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_STRERROR_GEN_R)
+ default: snprintf(buf, buflen, "Unknown system error %d", err);
+ }
+ return buf;
+}
+#undef UV_STRERROR_GEN_R
+
+
#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
const char* uv_strerror(int err) {
switch (err) {
@@ -359,7 +389,7 @@ void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
QUEUE_REMOVE(q);
QUEUE_INSERT_TAIL(&loop->handle_queue, q);
- if (h->flags & UV__HANDLE_INTERNAL) continue;
+ if (h->flags & UV_HANDLE_INTERNAL) continue;
walk_cb(h, arg);
}
}
@@ -388,9 +418,9 @@ static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
fprintf(stream,
"[%c%c%c] %-8s %p\n",
- "R-"[!(h->flags & UV__HANDLE_REF)],
- "A-"[!(h->flags & UV__HANDLE_ACTIVE)],
- "I-"[!(h->flags & UV__HANDLE_INTERNAL)],
+ "R-"[!(h->flags & UV_HANDLE_REF)],
+ "A-"[!(h->flags & UV_HANDLE_ACTIVE)],
+ "I-"[!(h->flags & UV_HANDLE_INTERNAL)],
type,
(void*)h);
}
@@ -634,7 +664,7 @@ int uv_loop_close(uv_loop_t* loop) {
QUEUE_FOREACH(q, &loop->handle_queue) {
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
- if (!(h->flags & UV__HANDLE_INTERNAL))
+ if (!(h->flags & UV_HANDLE_INTERNAL))
return UV_EBUSY;
}
diff --git a/Utilities/cmlibuv/src/uv-common.h b/Utilities/cmlibuv/src/uv-common.h
index c497d01..15ac4d0 100644
--- a/Utilities/cmlibuv/src/uv-common.h
+++ b/Utilities/cmlibuv/src/uv-common.h
@@ -32,14 +32,15 @@
#include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
-# include "stdint-msvc2008.h"
+# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#include "uv.h"
-#include "tree.h"
+#include "uv/tree.h"
#include "queue.h"
+#include "strscpy.h"
#if EDOM > 0
# define UV__ERR(x) (-(x))
@@ -59,22 +60,67 @@ extern int snprintf(char*, size_t, const char*, ...);
#define STATIC_ASSERT(expr) \
void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
-#ifndef _WIN32
+/* Handle flags. Some flags are specific to Windows or UNIX. */
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 */
+ /* Used by all handles. */
+ UV_HANDLE_CLOSING = 0x00000001,
+ UV_HANDLE_CLOSED = 0x00000002,
+ UV_HANDLE_ACTIVE = 0x00000004,
+ UV_HANDLE_REF = 0x00000008,
+ UV_HANDLE_INTERNAL = 0x00000010,
+ UV_HANDLE_ENDGAME_QUEUED = 0x00000020,
+
+ /* Used by streams. */
+ UV_HANDLE_LISTENING = 0x00000040,
+ UV_HANDLE_CONNECTION = 0x00000080,
+ UV_HANDLE_SHUTTING = 0x00000100,
+ UV_HANDLE_SHUT = 0x00000200,
+ UV_HANDLE_READ_PARTIAL = 0x00000400,
+ UV_HANDLE_READ_EOF = 0x00000800,
+
+ /* Used by streams and UDP handles. */
+ UV_HANDLE_READING = 0x00001000,
+ UV_HANDLE_BOUND = 0x00002000,
+ UV_HANDLE_READABLE = 0x00004000,
+ UV_HANDLE_WRITABLE = 0x00008000,
+ UV_HANDLE_READ_PENDING = 0x00010000,
+ UV_HANDLE_SYNC_BYPASS_IOCP = 0x00020000,
+ UV_HANDLE_ZERO_READ = 0x00040000,
+ UV_HANDLE_EMULATE_IOCP = 0x00080000,
+ UV_HANDLE_BLOCKING_WRITES = 0x00100000,
+ UV_HANDLE_CANCELLATION_PENDING = 0x00200000,
+
+ /* Used by uv_tcp_t and uv_udp_t handles */
+ UV_HANDLE_IPV6 = 0x00400000,
+
+ /* Only used by uv_tcp_t handles. */
+ UV_HANDLE_TCP_NODELAY = 0x01000000,
+ UV_HANDLE_TCP_KEEPALIVE = 0x02000000,
+ UV_HANDLE_TCP_SINGLE_ACCEPT = 0x04000000,
+ UV_HANDLE_TCP_ACCEPT_STATE_CHANGING = 0x08000000,
+ UV_HANDLE_TCP_SOCKET_CLOSED = 0x10000000,
+ UV_HANDLE_SHARED_TCP_SOCKET = 0x20000000,
+
+ /* Only used by uv_udp_t handles. */
+ UV_HANDLE_UDP_PROCESSING = 0x01000000,
+
+ /* Only used by uv_pipe_t handles. */
+ UV_HANDLE_NON_OVERLAPPED_PIPE = 0x01000000,
+ UV_HANDLE_PIPESERVER = 0x02000000,
+
+ /* Only used by uv_tty_t handles. */
+ UV_HANDLE_TTY_READABLE = 0x01000000,
+ UV_HANDLE_TTY_RAW = 0x02000000,
+ UV_HANDLE_TTY_SAVED_POSITION = 0x04000000,
+ UV_HANDLE_TTY_SAVED_ATTRIBUTES = 0x08000000,
+
+ /* Only used by uv_signal_t handles. */
+ UV_SIGNAL_ONE_SHOT_DISPATCHED = 0x01000000,
+ UV_SIGNAL_ONE_SHOT = 0x02000000,
+
+ /* Only used by uv_poll_t handles. */
+ UV_HANDLE_POLL_SLOW = 0x01000000
};
-#else
-# 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);
@@ -119,8 +165,15 @@ void uv__fs_poll_close(uv_fs_poll_t* handle);
int uv__getaddrinfo_translate_error(int sys_err); /* EAI_* error. */
+enum uv__work_kind {
+ UV__WORK_CPU,
+ UV__WORK_FAST_IO,
+ UV__WORK_SLOW_IO
+};
+
void uv__work_submit(uv_loop_t* loop,
struct uv__work *w,
+ enum uv__work_kind kind,
void (*work)(struct uv__work *w),
void (*done)(struct uv__work *w, int status));
@@ -132,6 +185,10 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
void uv__fs_scandir_cleanup(uv_fs_t* req);
+int uv__next_timeout(const uv_loop_t* loop);
+void uv__run_timers(uv_loop_t* loop);
+void uv__timer_close(uv_timer_t* handle);
+
#define uv__has_active_reqs(loop) \
((loop)->active_reqs.count > 0)
@@ -164,49 +221,47 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
while (0)
#define uv__is_active(h) \
- (((h)->flags & UV__HANDLE_ACTIVE) != 0)
+ (((h)->flags & UV_HANDLE_ACTIVE) != 0)
#define uv__is_closing(h) \
- (((h)->flags & (UV_CLOSING | UV_CLOSED)) != 0)
+ (((h)->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED)) != 0)
#define uv__handle_start(h) \
do { \
- assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \
- if (((h)->flags & UV__HANDLE_ACTIVE) != 0) break; \
- (h)->flags |= UV__HANDLE_ACTIVE; \
- if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_add(h); \
+ if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break; \
+ (h)->flags |= UV_HANDLE_ACTIVE; \
+ if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_add(h); \
} \
while (0)
#define uv__handle_stop(h) \
do { \
- assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \
- if (((h)->flags & UV__HANDLE_ACTIVE) == 0) break; \
- (h)->flags &= ~UV__HANDLE_ACTIVE; \
- if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_rm(h); \
+ if (((h)->flags & UV_HANDLE_ACTIVE) == 0) break; \
+ (h)->flags &= ~UV_HANDLE_ACTIVE; \
+ if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_rm(h); \
} \
while (0)
#define uv__handle_ref(h) \
do { \
- if (((h)->flags & UV__HANDLE_REF) != 0) break; \
- (h)->flags |= UV__HANDLE_REF; \
- if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \
- if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \
+ if (((h)->flags & UV_HANDLE_REF) != 0) break; \
+ (h)->flags |= UV_HANDLE_REF; \
+ if (((h)->flags & UV_HANDLE_CLOSING) != 0) break; \
+ if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \
} \
while (0)
#define uv__handle_unref(h) \
do { \
- if (((h)->flags & UV__HANDLE_REF) == 0) break; \
- (h)->flags &= ~UV__HANDLE_REF; \
- if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \
- if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \
+ if (((h)->flags & UV_HANDLE_REF) == 0) break; \
+ (h)->flags &= ~UV_HANDLE_REF; \
+ if (((h)->flags & UV_HANDLE_CLOSING) != 0) break; \
+ if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \
} \
while (0)
#define uv__has_ref(h) \
- (((h)->flags & UV__HANDLE_REF) != 0)
+ (((h)->flags & UV_HANDLE_REF) != 0)
#if defined(_WIN32)
# define uv__handle_platform_init(h) ((h)->u.fd = -1)
@@ -218,7 +273,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
do { \
(h)->loop = (loop_); \
(h)->type = (type_); \
- (h)->flags = UV__HANDLE_REF; /* Ref the loop when active. */ \
+ (h)->flags = UV_HANDLE_REF; /* Ref the loop when active. */ \
QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); \
uv__handle_platform_init(h); \
} \
diff --git a/Utilities/cmlibuv/src/uv-data-getter-setters.c b/Utilities/cmlibuv/src/uv-data-getter-setters.c
index 533e4a2..b7fcd4a 100644
--- a/Utilities/cmlibuv/src/uv-data-getter-setters.c
+++ b/Utilities/cmlibuv/src/uv-data-getter-setters.c
@@ -3,11 +3,11 @@
const char* uv_handle_type_name(uv_handle_type type) {
switch (type) {
#define XX(uc,lc) case UV_##uc: return #lc;
- UV_HANDLE_TYPE_MAP(XX)
+ UV_HANDLE_TYPE_MAP(XX)
#undef XX
- case UV_FILE: return "file";
- case UV_HANDLE_TYPE_MAX:
- case UV_UNKNOWN_HANDLE: return NULL;
+ case UV_FILE: return "file";
+ case UV_HANDLE_TYPE_MAX:
+ case UV_UNKNOWN_HANDLE: return NULL;
}
return NULL;
}
@@ -31,10 +31,12 @@ void uv_handle_set_data(uv_handle_t* handle, void* data) {
const char* uv_req_type_name(uv_req_type type) {
switch (type) {
#define XX(uc,lc) case UV_##uc: return #lc;
- UV_REQ_TYPE_MAP(XX)
+ UV_REQ_TYPE_MAP(XX)
#undef XX
- case UV_REQ_TYPE_MAX:
- case UV_UNKNOWN_REQ: return NULL;
+ case UV_REQ_TYPE_MAX:
+ case UV_UNKNOWN_REQ:
+ default: /* UV_REQ_TYPE_PRIVATE */
+ return NULL;
}
return NULL;
}
diff --git a/Utilities/cmlibuv/src/win/async.c b/Utilities/cmlibuv/src/win/async.c
index 0b636ed..d787f66 100644
--- a/Utilities/cmlibuv/src/win/async.c
+++ b/Utilities/cmlibuv/src/win/async.c
@@ -29,7 +29,7 @@
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
- if (handle->flags & UV__HANDLE_CLOSING &&
+ if (handle->flags & UV_HANDLE_CLOSING &&
!handle->async_sent) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
uv__handle_close(handle);
@@ -71,9 +71,9 @@ int uv_async_send(uv_async_t* handle) {
return -1;
}
- /* The user should make sure never to call uv_async_send to a closing */
- /* or closed handle. */
- assert(!(handle->flags & UV__HANDLE_CLOSING));
+ /* The user should make sure never to call uv_async_send to a closing or
+ * closed handle. */
+ assert(!(handle->flags & UV_HANDLE_CLOSING));
if (!uv__atomic_exchange_set(&handle->async_sent)) {
POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
@@ -90,7 +90,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
handle->async_sent = 0;
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*)handle);
} else if (handle->async_cb != NULL) {
handle->async_cb(handle);
diff --git a/Utilities/cmlibuv/src/win/atomicops-inl.h b/Utilities/cmlibuv/src/win/atomicops-inl.h
index 6d8126f..52713cf 100644
--- a/Utilities/cmlibuv/src/win/atomicops-inl.h
+++ b/Utilities/cmlibuv/src/win/atomicops-inl.h
@@ -29,10 +29,10 @@
/* Atomic set operation on char */
#ifdef _MSC_VER /* MSVC */
-/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
-/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
-/* exist, and interlocked operations on larger targets might require the */
-/* target to be aligned. */
+/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
+ * efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
+ * and interlocked operations on larger targets might require the target to be
+ * aligned. */
#pragma intrinsic(_InterlockedOr8)
static char INLINE uv__atomic_exchange_set(char volatile* target) {
diff --git a/Utilities/cmlibuv/src/win/core.c b/Utilities/cmlibuv/src/win/core.c
index b8aad11..58309c6 100644
--- a/Utilities/cmlibuv/src/win/core.c
+++ b/Utilities/cmlibuv/src/win/core.c
@@ -33,6 +33,7 @@
#include "internal.h"
#include "queue.h"
#include "handle-inl.h"
+#include "heap-inl.h"
#include "req-inl.h"
/* uv_once initialization guards */
@@ -221,6 +222,7 @@ static void uv_init(void) {
int uv_loop_init(uv_loop_t* loop) {
+ struct heap* timer_heap;
int err;
/* Initialize libuv itself first */
@@ -246,7 +248,13 @@ int uv_loop_init(uv_loop_t* loop) {
loop->endgame_handles = NULL;
- RB_INIT(&loop->timers);
+ loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
+ if (timer_heap == NULL) {
+ err = UV_ENOMEM;
+ goto fail_timers_alloc;
+ }
+
+ heap_init(timer_heap);
loop->check_handles = NULL;
loop->prepare_handles = NULL;
@@ -273,7 +281,7 @@ int uv_loop_init(uv_loop_t* loop) {
goto fail_async_init;
uv__handle_unref(&loop->wq_async);
- loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+ loop->wq_async.flags |= UV_HANDLE_INTERNAL;
err = uv__loops_add(loop);
if (err)
@@ -285,6 +293,10 @@ fail_async_init:
uv_mutex_destroy(&loop->wq_mutex);
fail_mutex_init:
+ uv__free(timer_heap);
+ loop->timer_heap = NULL;
+
+fail_timers_alloc:
CloseHandle(loop->iocp);
loop->iocp = INVALID_HANDLE_VALUE;
@@ -292,6 +304,13 @@ fail_mutex_init:
}
+void uv_update_time(uv_loop_t* loop) {
+ uint64_t new_time = uv__hrtime(1000);
+ assert(new_time >= loop->time);
+ loop->time = new_time;
+}
+
+
void uv__once_init(void) {
uv_once(&uv_init_guard_, uv_init);
}
@@ -320,6 +339,9 @@ void uv__loop_close(uv_loop_t* loop) {
uv_mutex_unlock(&loop->wq_mutex);
uv_mutex_destroy(&loop->wq_mutex);
+ uv__free(loop->timer_heap);
+ loop->timer_heap = NULL;
+
CloseHandle(loop->iocp);
}
@@ -359,7 +381,7 @@ int uv_backend_timeout(const uv_loop_t* loop) {
}
-static void uv_poll(uv_loop_t* loop, DWORD timeout) {
+static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) {
DWORD bytes;
ULONG_PTR key;
OVERLAPPED* overlapped;
@@ -410,7 +432,7 @@ static void uv_poll(uv_loop_t* loop, DWORD timeout) {
}
-static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
+static void uv__poll(uv_loop_t* loop, DWORD timeout) {
BOOL success;
uv_req_t* req;
OVERLAPPED_ENTRY overlappeds[128];
@@ -422,12 +444,12 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) {
- success = pGetQueuedCompletionStatusEx(loop->iocp,
- overlappeds,
- ARRAY_SIZE(overlappeds),
- &count,
- timeout,
- FALSE);
+ success = GetQueuedCompletionStatusEx(loop->iocp,
+ overlappeds,
+ ARRAY_SIZE(overlappeds),
+ &count,
+ timeout,
+ FALSE);
if (success) {
for (i = 0; i < count; i++) {
@@ -485,12 +507,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
DWORD timeout;
int r;
int ran_pending;
- void (*poll)(uv_loop_t* loop, DWORD timeout);
-
- if (pGetQueuedCompletionStatusEx)
- poll = &uv_poll_ex;
- else
- poll = &uv_poll;
r = uv__loop_alive(loop);
if (!r)
@@ -498,7 +514,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
while (r != 0 && loop->stop_flag == 0) {
uv_update_time(loop);
- uv_process_timers(loop);
+ uv__run_timers(loop);
ran_pending = uv_process_reqs(loop);
uv_idle_invoke(loop);
@@ -508,7 +524,11 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop);
- (*poll)(loop, timeout);
+ if (pGetQueuedCompletionStatusEx)
+ uv__poll(loop, timeout);
+ else
+ uv__poll_wine(loop, timeout);
+
uv_check_invoke(loop);
uv_process_endgames(loop);
@@ -522,7 +542,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
* the check.
*/
- uv_process_timers(loop);
+ uv__run_timers(loop);
}
r = uv__loop_alive(loop);
diff --git a/Utilities/cmlibuv/src/win/dl.c b/Utilities/cmlibuv/src/win/dl.c
index 97ac1c1..676be4d 100644
--- a/Utilities/cmlibuv/src/win/dl.c
+++ b/Utilities/cmlibuv/src/win/dl.c
@@ -64,7 +64,8 @@ void uv_dlclose(uv_lib_t* lib) {
int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
- *ptr = (void*) GetProcAddress(lib->handle, name);
+ /* Cast though integer to suppress pedantic warning about forbidden cast. */
+ *ptr = (void*)(uintptr_t) GetProcAddress(lib->handle, name);
return uv__dlerror(lib, "", *ptr ? 0 : GetLastError());
}
@@ -75,8 +76,9 @@ const char* uv_dlerror(const uv_lib_t* lib) {
static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
- DWORD_PTR args[1] = { (DWORD_PTR) errorno };
- LPSTR fallback_error = "error: %1!d!";
+ static const CHAR fallback_error[] = "error: %1!d!";
+ DWORD_PTR args[1];
+ args[0] = (DWORD_PTR) errorno;
FormatMessageA(FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ARGUMENT_ARRAY |
@@ -107,7 +109,8 @@ static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) {
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR) &lib->errmsg, 0, NULL);
- if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
+ if (!res && (GetLastError() == ERROR_MUI_FILE_NOT_FOUND ||
+ GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND)) {
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
diff --git a/Utilities/cmlibuv/src/win/error.c b/Utilities/cmlibuv/src/win/error.c
index 9b03bfe..24924ba 100644
--- a/Utilities/cmlibuv/src/win/error.c
+++ b/Utilities/cmlibuv/src/win/error.c
@@ -46,8 +46,8 @@ void uv_fatal_error(const int errorno, const char* syscall) {
errmsg = "Unknown error";
}
- /* FormatMessage messages include a newline character already, */
- /* so don't add another. */
+ /* FormatMessage messages include a newline character already, so don't add
+ * another. */
if (syscall) {
fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
} else {
diff --git a/Utilities/cmlibuv/src/win/fs-event.c b/Utilities/cmlibuv/src/win/fs-event.c
index 14c9af9..acf8e11 100644
--- a/Utilities/cmlibuv/src/win/fs-event.c
+++ b/Utilities/cmlibuv/src/win/fs-event.c
@@ -83,7 +83,7 @@ static void uv_relative_path(const WCHAR* filename,
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
WCHAR** file) {
size_t len, i;
-
+
if (filename == NULL) {
if (dir != NULL)
*dir = NULL;
@@ -215,11 +215,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__free(long_path);
long_path = NULL;
}
- }
- if (long_path) {
- uv__free(pathw);
- pathw = long_path;
+ if (long_path) {
+ uv__free(pathw);
+ pathw = long_path;
+ }
}
dir_to_watch = pathw;
@@ -230,8 +230,11 @@ 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))) {
+ if (GetShortPathNameW(pathw,
+ short_path_buffer,
+ ARRAY_SIZE(short_path_buffer))) {
+ short_path = short_path_buffer;
+ } else {
short_path = NULL;
}
@@ -419,7 +422,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
* - We are not active, just ignore the callback
*/
if (!uv__is_active(handle)) {
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle);
}
return;
@@ -543,7 +546,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
}
offset = file_info->NextEntryOffset;
- } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
+ } while (offset && !(handle->flags & UV_HANDLE_CLOSING));
} else {
handle->cb(handle, NULL, UV_CHANGE, 0);
}
@@ -552,7 +555,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
}
- if (!(handle->flags & UV__HANDLE_CLOSING)) {
+ if (!(handle->flags & UV_HANDLE_CLOSING)) {
uv_fs_event_queue_readdirchanges(loop, handle);
} else {
uv_want_endgame(loop, (uv_handle_t*)handle);
@@ -573,7 +576,7 @@ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
- if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) {
+ if ((handle->flags & UV_HANDLE_CLOSING) && !handle->req_pending) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
if (handle->buffer) {
diff --git a/Utilities/cmlibuv/src/win/fs.c b/Utilities/cmlibuv/src/win/fs.c
index 30b87ac..65d936b 100644
--- a/Utilities/cmlibuv/src/win/fs.c
+++ b/Utilities/cmlibuv/src/win/fs.c
@@ -55,7 +55,11 @@
do { \
if (cb != NULL) { \
uv__req_register(loop, req); \
- uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
+ uv__work_submit(loop, \
+ &req->work_req, \
+ UV__WORK_FAST_IO, \
+ uv__fs_work, \
+ uv__fs_done); \
return 0; \
} else { \
uv__fs_work(&req->work_req); \
@@ -92,14 +96,17 @@
return; \
}
+#define MILLIONu (1000U * 1000U)
+#define BILLIONu (1000U * 1000U * 1000U)
+
#define FILETIME_TO_UINT(filetime) \
- (*((uint64_t*) &(filetime)) - 116444736000000000ULL)
+ (*((uint64_t*) &(filetime)) - (uint64_t) 116444736 * BILLIONu)
#define FILETIME_TO_TIME_T(filetime) \
- (FILETIME_TO_UINT(filetime) / 10000000ULL)
+ (FILETIME_TO_UINT(filetime) / (10u * MILLIONu))
#define FILETIME_TO_TIME_NS(filetime, secs) \
- ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100)
+ ((FILETIME_TO_UINT(filetime) - (secs * (uint64_t) 10 * MILLIONu)) * 100U)
#define FILETIME_TO_TIMESPEC(ts, filetime) \
do { \
@@ -109,8 +116,8 @@
#define TIME_T_TO_FILETIME(time, filetime_ptr) \
do { \
- uint64_t bigtime = ((uint64_t) ((time) * 10000000ULL)) + \
- 116444736000000000ULL; \
+ uint64_t bigtime = ((uint64_t) ((time) * (uint64_t) 10 * MILLIONu)) + \
+ (uint64_t) 116444736 * BILLIONu; \
(filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \
(filetime_ptr)->dwHighDateTime = bigtime >> 32; \
} while(0)
@@ -326,12 +333,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
sizeof(WCHAR);
- /* Real symlinks can contain pretty much everything, but the only thing */
- /* we really care about is undoing the implicit conversion to an NT */
- /* namespaced path that CreateSymbolicLink will perform on absolute */
- /* paths. If the path is win32-namespaced then the user must have */
- /* explicitly made it so, and we better just return the unmodified */
- /* reparse data. */
+ /* Real symlinks can contain pretty much everything, but the only thing we
+ * really care about is undoing the implicit conversion to an NT namespaced
+ * path that CreateSymbolicLink will perform on absolute paths. If the path
+ * is win32-namespaced then the user must have explicitly made it so, and
+ * we better just return the unmodified reparse data. */
if (w_target_len >= 4 &&
w_target[0] == L'\\' &&
w_target[1] == L'?' &&
@@ -352,8 +358,8 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
(w_target[5] == L'N' || w_target[5] == L'n') &&
(w_target[6] == L'C' || w_target[6] == L'c') &&
w_target[7] == L'\\') {
- /* \??\UNC\<server>\<share>\ - make sure the final path looks like */
- /* \\<server>\<share>\ */
+ /* \??\UNC\<server>\<share>\ - make sure the final path looks like
+ * \\<server>\<share>\ */
w_target += 6;
w_target[0] = L'\\';
w_target_len -= 6;
@@ -368,11 +374,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
sizeof(WCHAR);
- /* Only treat junctions that look like \??\<drive>:\ as symlink. */
- /* Junctions can also be used as mount points, like \??\Volume{<guid>}, */
- /* but that's confusing for programs since they wouldn't be able to */
- /* actually understand such a path when returned by uv_readlink(). */
- /* UNC paths are never valid for junctions so we don't care about them. */
+ /* Only treat junctions that look like \??\<drive>:\ as symlink. Junctions
+ * can also be used as mount points, like \??\Volume{<guid>}, but that's
+ * confusing for programs since they wouldn't be able to actually
+ * understand such a path when returned by uv_readlink(). UNC paths are
+ * never valid for junctions so we don't care about them. */
if (!(w_target_len >= 6 &&
w_target[0] == L'\\' &&
w_target[1] == L'?' &&
@@ -409,8 +415,8 @@ void fs__open(uv_fs_t* req) {
int fd, current_umask;
int flags = req->fs.info.file_flags;
- /* Obtain the active umask. umask() never fails and returns the previous */
- /* umask. */
+ /* Obtain the active umask. umask() never fails and returns the previous
+ * umask. */
current_umask = umask(0);
umask(current_umask);
@@ -502,6 +508,33 @@ void fs__open(uv_fs_t* req) {
}
if (flags & UV_FS_O_DIRECT) {
+ /*
+ * FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive.
+ * Windows returns 87, ERROR_INVALID_PARAMETER if these are combined.
+ *
+ * FILE_APPEND_DATA is included in FILE_GENERIC_WRITE:
+ *
+ * FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE |
+ * FILE_WRITE_DATA |
+ * FILE_WRITE_ATTRIBUTES |
+ * FILE_WRITE_EA |
+ * FILE_APPEND_DATA |
+ * SYNCHRONIZE
+ *
+ * Note: Appends are also permitted by FILE_WRITE_DATA.
+ *
+ * In order for direct writes and direct appends to succeed, we therefore
+ * exclude FILE_APPEND_DATA if FILE_WRITE_DATA is specified, and otherwise
+ * fail if the user's sole permission is a direct append, since this
+ * particular combination is invalid.
+ */
+ if (access & FILE_APPEND_DATA) {
+ if (access & FILE_WRITE_DATA) {
+ access &= ~FILE_APPEND_DATA;
+ } else {
+ goto einval;
+ }
+ }
attributes |= FILE_FLAG_NO_BUFFERING;
}
@@ -530,8 +563,8 @@ void fs__open(uv_fs_t* req) {
DWORD error = GetLastError();
if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) &&
!(flags & UV_FS_O_EXCL)) {
- /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was */
- /* specified, it means the path referred to a directory. */
+ /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was
+ * specified, it means the path referred to a directory. */
SET_REQ_UV_ERROR(req, UV_EISDIR, error);
} else {
SET_REQ_WIN32_ERROR(req, GetLastError());
@@ -756,9 +789,9 @@ void fs__unlink(uv_fs_t* req) {
}
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- /* Do not allow deletion of directories, unless it is a symlink. When */
- /* the path refers to a non-symlink directory, report EPERM as mandated */
- /* by POSIX.1. */
+ /* Do not allow deletion of directories, unless it is a symlink. When the
+ * path refers to a non-symlink directory, report EPERM as mandated by
+ * POSIX.1. */
/* Check if it is a reparse point. If it's not, it's a normal directory. */
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
@@ -767,8 +800,8 @@ void fs__unlink(uv_fs_t* req) {
return;
}
- /* Read the reparse point and check if it is a valid symlink. */
- /* If not, don't unlink. */
+ /* Read the reparse point and check if it is a valid symlink. If not, don't
+ * unlink. */
if (fs__readlink_handle(handle, NULL, NULL) < 0) {
DWORD error = GetLastError();
if (error == ERROR_SYMLINK_NOT_SUPPORTED)
@@ -783,9 +816,8 @@ void fs__unlink(uv_fs_t* req) {
/* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 };
- basic.FileAttributes = info.dwFileAttributes
- & ~(FILE_ATTRIBUTE_READONLY)
- | FILE_ATTRIBUTE_ARCHIVE;
+ basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
+ FILE_ATTRIBUTE_ARCHIVE;
status = pNtSetInformationFile(handle,
&iosb,
@@ -1196,7 +1228,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
/* st_blocks contains the on-disk allocation size in 512-byte units. */
statbuf->st_blocks =
- file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL;
+ (uint64_t) file_info.StandardInformation.AllocationSize.QuadPart >> 9;
statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks;
@@ -1490,6 +1522,7 @@ static void fs__chmod(uv_fs_t* req) {
static void fs__fchmod(uv_fs_t* req) {
int fd = req->file.fd;
+ int clear_archive_flag;
HANDLE handle;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
@@ -1497,7 +1530,11 @@ static void fs__fchmod(uv_fs_t* req) {
VERIFY_FD(fd, req);
- handle = uv__get_osfhandle(fd);
+ handle = ReOpenFile(uv__get_osfhandle(fd), FILE_WRITE_ATTRIBUTES, 0, 0);
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
nt_status = pNtQueryInformationFile(handle,
&io_status,
@@ -1507,7 +1544,27 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
- return;
+ goto fchmod_cleanup;
+ }
+
+ /* Test if the Archive attribute is cleared */
+ if ((file_info.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == 0) {
+ /* Set Archive flag, otherwise setting or clearing the read-only
+ flag will not work */
+ file_info.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
+ nt_status = pNtSetInformationFile(handle,
+ &io_status,
+ &file_info,
+ sizeof file_info,
+ FileBasicInformation);
+ if (!NT_SUCCESS(nt_status)) {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+ goto fchmod_cleanup;
+ }
+ /* Remeber to clear the flag later on */
+ clear_archive_flag = 1;
+ } else {
+ clear_archive_flag = 0;
}
if (req->fs.info.mode & _S_IWRITE) {
@@ -1524,10 +1581,28 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
- return;
+ goto fchmod_cleanup;
+ }
+
+ if (clear_archive_flag) {
+ file_info.FileAttributes &= ~FILE_ATTRIBUTE_ARCHIVE;
+ if (file_info.FileAttributes == 0) {
+ file_info.FileAttributes = FILE_ATTRIBUTE_NORMAL;
+ }
+ nt_status = pNtSetInformationFile(handle,
+ &io_status,
+ &file_info,
+ sizeof file_info,
+ FileBasicInformation);
+ if (!NT_SUCCESS(nt_status)) {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+ goto fchmod_cleanup;
+ }
}
SET_REQ_SUCCESS(req);
+fchmod_cleanup:
+ CloseHandle(handle);
}
@@ -1787,17 +1862,13 @@ static void fs__symlink(uv_fs_t* req) {
fs__create_junction(req, pathw, new_pathw);
return;
}
- if (!pCreateSymbolicLinkW) {
- SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
- return;
- }
if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag;
else
flags = uv__file_symlink_usermode_flag;
- if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) {
+ if (CreateSymbolicLinkW(new_pathw, pathw, flags)) {
SET_REQ_RESULT(req, 0);
return;
}
@@ -1848,13 +1919,13 @@ static void fs__readlink(uv_fs_t* req) {
}
-static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
+static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
int r;
DWORD w_realpath_len;
WCHAR* w_realpath_ptr = NULL;
WCHAR* w_realpath_buf;
- w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
+ w_realpath_len = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
if (w_realpath_len == 0) {
return -1;
}
@@ -1866,10 +1937,8 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
}
w_realpath_ptr = w_realpath_buf;
- if (pGetFinalPathNameByHandleW(handle,
- w_realpath_ptr,
- w_realpath_len,
- VOLUME_NAME_DOS) == 0) {
+ if (GetFinalPathNameByHandleW(
+ handle, w_realpath_ptr, w_realpath_len, VOLUME_NAME_DOS) == 0) {
uv__free(w_realpath_buf);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
@@ -1901,11 +1970,6 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
static void fs__realpath(uv_fs_t* req) {
HANDLE handle;
- if (!pGetFinalPathNameByHandleW) {
- SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
- return;
- }
-
handle = CreateFileW(req->file.pathw,
0,
0,
@@ -1940,6 +2004,10 @@ static void fs__fchown(uv_fs_t* req) {
}
+static void fs__lchown(uv_fs_t* req) {
+ req->result = 0;
+}
+
static void uv__fs_work(struct uv__work* w) {
uv_fs_t* req;
@@ -1977,6 +2045,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(REALPATH, realpath)
XX(CHOWN, chown)
XX(FCHOWN, fchown);
+ XX(LCHOWN, lchown);
default:
assert(!"bad uv_fs_type");
}
@@ -2262,6 +2331,19 @@ int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
}
+int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
+ uv_gid_t gid, uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_LCHOWN);
+ err = fs__capture_path(req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+ POST;
+}
+
+
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
diff --git a/Utilities/cmlibuv/src/win/getaddrinfo.c b/Utilities/cmlibuv/src/win/getaddrinfo.c
index 5adc766..dfab860 100644
--- a/Utilities/cmlibuv/src/win/getaddrinfo.c
+++ b/Utilities/cmlibuv/src/win/getaddrinfo.c
@@ -24,6 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
+#include "idna.h"
/* EAI_* constants. */
#include <winsock2.h>
@@ -71,8 +72,8 @@ int uv__getaddrinfo_translate_error(int sys_err) {
#endif
-/* adjust size value to be multiple of 4. Use to keep pointer aligned */
-/* Do we need different versions of this for different architectures? */
+/* Adjust size value to be multiple of 4. Use to keep pointer aligned.
+ * Do we need different versions of this for different architectures? */
#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2)
#ifndef NDIS_IF_MAX_STRING_SIZE
@@ -124,8 +125,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
}
if (req->retcode == 0) {
- /* convert addrinfoW to addrinfo */
- /* first calculate required length */
+ /* Convert addrinfoW to addrinfo. First calculate required length. */
addrinfow_ptr = req->addrinfow;
while (addrinfow_ptr != NULL) {
addrinfo_len += addrinfo_struct_len +
@@ -260,11 +260,13 @@ int uv_getaddrinfo(uv_loop_t* loop,
const char* node,
const char* service,
const struct addrinfo* hints) {
+ char hostname_ascii[256];
int nodesize = 0;
int servicesize = 0;
int hintssize = 0;
char* alloc_ptr = NULL;
int err;
+ long rc;
if (req == NULL || (node == NULL && service == NULL)) {
return UV_EINVAL;
@@ -278,12 +280,19 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* calculate required memory size for all input values */
if (node != NULL) {
- nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) *
- sizeof(WCHAR));
+ rc = uv__idna_toascii(node,
+ node + strlen(node),
+ hostname_ascii,
+ hostname_ascii + sizeof(hostname_ascii));
+ if (rc < 0)
+ return rc;
+ nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, hostname_ascii,
+ -1, NULL, 0) * sizeof(WCHAR));
if (nodesize == 0) {
err = GetLastError();
goto error;
}
+ node = hostname_ascii;
}
if (service != NULL) {
@@ -313,8 +322,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* save alloc_ptr now so we can free if error */
req->alloc = (void*)alloc_ptr;
- /* convert node string to UTF16 into allocated memory and save pointer in */
- /* the request. */
+ /* Convert node string to UTF16 into allocated memory and save pointer in the
+ * request. */
if (node != NULL) {
req->node = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8,
@@ -331,8 +340,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
req->node = NULL;
}
- /* convert service string to UTF16 into allocated memory and save pointer */
- /* in the req. */
+ /* Convert service string to UTF16 into allocated memory and save pointer in
+ * the req. */
if (service != NULL) {
req->service = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8,
@@ -369,6 +378,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (getaddrinfo_cb) {
uv__work_submit(loop,
&req->work_req,
+ UV__WORK_SLOW_IO,
uv__getaddrinfo_work,
uv__getaddrinfo_done);
return 0;
@@ -392,21 +402,15 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
DWORD bufsize;
int r;
- uv__once_init();
-
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
- if (pConvertInterfaceIndexToLuid == NULL)
- return UV_ENOSYS;
- r = pConvertInterfaceIndexToLuid(ifindex, &luid);
+ r = ConvertInterfaceIndexToLuid(ifindex, &luid);
if (r != 0)
return uv_translate_sys_error(r);
- if (pConvertInterfaceLuidToNameW == NULL)
- return UV_ENOSYS;
- r = pConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname));
+ r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname));
if (r != 0)
return uv_translate_sys_error(r);
diff --git a/Utilities/cmlibuv/src/win/getnameinfo.c b/Utilities/cmlibuv/src/win/getnameinfo.c
index 9f10cd2..b377338 100644
--- a/Utilities/cmlibuv/src/win/getnameinfo.c
+++ b/Utilities/cmlibuv/src/win/getnameinfo.c
@@ -42,7 +42,7 @@ static void uv__getnameinfo_work(struct uv__work* w) {
uv_getnameinfo_t* req;
WCHAR host[NI_MAXHOST];
WCHAR service[NI_MAXSERV];
- int ret = 0;
+ int ret;
req = container_of(w, uv_getnameinfo_t, work_req);
if (GetNameInfoW((struct sockaddr*)&req->storage,
@@ -53,27 +53,34 @@ static void uv__getnameinfo_work(struct uv__work* w) {
ARRAY_SIZE(service),
req->flags)) {
ret = WSAGetLastError();
+ req->retcode = uv__getaddrinfo_translate_error(ret);
+ return;
+ }
+
+ ret = WideCharToMultiByte(CP_UTF8,
+ 0,
+ host,
+ -1,
+ req->host,
+ sizeof(req->host),
+ NULL,
+ NULL);
+ if (ret == 0) {
+ req->retcode = uv_translate_sys_error(GetLastError());
+ return;
+ }
+
+ ret = WideCharToMultiByte(CP_UTF8,
+ 0,
+ service,
+ -1,
+ req->service,
+ sizeof(req->service),
+ NULL,
+ NULL);
+ if (ret == 0) {
+ req->retcode = uv_translate_sys_error(GetLastError());
}
- req->retcode = uv__getaddrinfo_translate_error(ret);
-
- /* convert results to UTF-8 */
- WideCharToMultiByte(CP_UTF8,
- 0,
- host,
- -1,
- req->host,
- sizeof(req->host),
- NULL,
- NULL);
-
- WideCharToMultiByte(CP_UTF8,
- 0,
- service,
- -1,
- req->service,
- sizeof(req->service),
- NULL,
- NULL);
}
@@ -138,6 +145,7 @@ int uv_getnameinfo(uv_loop_t* loop,
if (getnameinfo_cb) {
uv__work_submit(loop,
&req->work_req,
+ UV__WORK_SLOW_IO,
uv__getnameinfo_work,
uv__getnameinfo_done);
return 0;
diff --git a/Utilities/cmlibuv/src/win/handle-inl.h b/Utilities/cmlibuv/src/win/handle-inl.h
index 8d0334c..82c657d 100644
--- a/Utilities/cmlibuv/src/win/handle-inl.h
+++ b/Utilities/cmlibuv/src/win/handle-inl.h
@@ -32,7 +32,7 @@
#define DECREASE_ACTIVE_COUNT(loop, handle) \
do { \
if (--(handle)->activecnt == 0 && \
- !((handle)->flags & UV__HANDLE_CLOSING)) { \
+ !((handle)->flags & UV_HANDLE_CLOSING)) { \
uv__handle_stop((handle)); \
} \
assert((handle)->activecnt >= 0); \
@@ -53,7 +53,7 @@
assert(handle->reqs_pending > 0); \
handle->reqs_pending--; \
\
- if (handle->flags & UV__HANDLE_CLOSING && \
+ if (handle->flags & UV_HANDLE_CLOSING && \
handle->reqs_pending == 0) { \
uv_want_endgame(loop, (uv_handle_t*)handle); \
} \
@@ -62,14 +62,14 @@
#define uv__handle_closing(handle) \
do { \
- assert(!((handle)->flags & UV__HANDLE_CLOSING)); \
+ assert(!((handle)->flags & UV_HANDLE_CLOSING)); \
\
- if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \
- ((handle)->flags & UV__HANDLE_REF))) \
+ if (!(((handle)->flags & UV_HANDLE_ACTIVE) && \
+ ((handle)->flags & UV_HANDLE_REF))) \
uv__active_handle_add((uv_handle_t*) (handle)); \
\
- (handle)->flags |= UV__HANDLE_CLOSING; \
- (handle)->flags &= ~UV__HANDLE_ACTIVE; \
+ (handle)->flags |= UV_HANDLE_CLOSING; \
+ (handle)->flags &= ~UV_HANDLE_ACTIVE; \
} while (0)
@@ -126,7 +126,8 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
break;
case UV_TIMER:
- uv_timer_endgame(loop, (uv_timer_t*) handle);
+ uv__timer_close((uv_timer_t*) handle);
+ uv__handle_close(handle);
break;
case UV_PREPARE:
@@ -164,10 +165,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
INLINE static HANDLE uv__get_osfhandle(int fd)
{
- /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
- /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
- /* for invalid FDs in release builds (or if you let the assert continue). */
- /* So this wrapper function disables asserts when calling _get_osfhandle. */
+ /* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
+ * But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for
+ * invalid FDs in release builds (or if you let the assert continue). So this
+ * wrapper function disables asserts when calling _get_osfhandle. */
HANDLE handle;
UV_BEGIN_DISABLE_CRT_ASSERT();
diff --git a/Utilities/cmlibuv/src/win/handle.c b/Utilities/cmlibuv/src/win/handle.c
index 3915070..9d76c3f 100644
--- a/Utilities/cmlibuv/src/win/handle.c
+++ b/Utilities/cmlibuv/src/win/handle.c
@@ -59,15 +59,15 @@ uv_handle_type uv_guess_handle(uv_file file) {
int uv_is_active(const uv_handle_t* handle) {
- return (handle->flags & UV__HANDLE_ACTIVE) &&
- !(handle->flags & UV__HANDLE_CLOSING);
+ return (handle->flags & UV_HANDLE_ACTIVE) &&
+ !(handle->flags & UV_HANDLE_CLOSING);
}
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_loop_t* loop = handle->loop;
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
assert(0);
return;
}
@@ -150,10 +150,14 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
int uv_is_closing(const uv_handle_t* handle) {
- return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED));
+ return !!(handle->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED));
}
uv_os_fd_t uv_get_osfhandle(int fd) {
return uv__get_osfhandle(fd);
}
+
+int uv_open_osfhandle(uv_os_fd_t os_fd) {
+ return _open_osfhandle((intptr_t) os_fd, 0);
+}
diff --git a/Utilities/cmlibuv/src/win/internal.h b/Utilities/cmlibuv/src/win/internal.h
index 849bc82..206ab5f 100644
--- a/Utilities/cmlibuv/src/win/internal.h
+++ b/Utilities/cmlibuv/src/win/internal.h
@@ -29,7 +29,7 @@
#include "uv.h"
#include "../uv-common.h"
-#include "tree.h"
+#include "uv/tree.h"
#include "winapi.h"
#include "winsock.h"
@@ -62,77 +62,19 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
#endif
/*
- * Handles
- * (also see handle-inl.h)
- */
-
-/* Used by all handles. */
-#define UV_HANDLE_CLOSED 0x00000002
-#define UV_HANDLE_ENDGAME_QUEUED 0x00000008
-
-/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
-/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
-/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */
-/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */
-
-/* Used by streams and UDP handles. */
-#define UV_HANDLE_READING 0x00000100
-#define UV_HANDLE_BOUND 0x00000200
-#define UV_HANDLE_LISTENING 0x00000800
-#define UV_HANDLE_CONNECTION 0x00001000
-#define UV_HANDLE_READABLE 0x00008000
-#define UV_HANDLE_WRITABLE 0x00010000
-#define UV_HANDLE_READ_PENDING 0x00020000
-#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000
-#define UV_HANDLE_ZERO_READ 0x00080000
-#define UV_HANDLE_EMULATE_IOCP 0x00100000
-#define UV_HANDLE_BLOCKING_WRITES 0x00200000
-#define UV_HANDLE_CANCELLATION_PENDING 0x00400000
-
-/* Used by uv_tcp_t and uv_udp_t handles */
-#define UV_HANDLE_IPV6 0x01000000
-
-/* Only used by uv_tcp_t handles. */
-#define UV_HANDLE_TCP_NODELAY 0x02000000
-#define UV_HANDLE_TCP_KEEPALIVE 0x04000000
-#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000
-#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000
-#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000
-#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000
-
-/* Only used by uv_pipe_t handles. */
-#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
-#define UV_HANDLE_PIPESERVER 0x02000000
-#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
-
-/* Only used by uv_tty_t handles. */
-#define UV_HANDLE_TTY_READABLE 0x01000000
-#define UV_HANDLE_TTY_RAW 0x02000000
-#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000
-#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000
-
-/* Only used by uv_poll_t handles. */
-#define UV_HANDLE_POLL_SLOW 0x02000000
-
-
-/*
- * Requests: see req-inl.h
- */
-
-
-/*
- * Streams: see stream-inl.h
- */
-
-
-/*
* TCP
*/
+typedef enum {
+ UV__IPC_SOCKET_XFER_NONE = 0,
+ UV__IPC_SOCKET_XFER_TCP_CONNECTION,
+ UV__IPC_SOCKET_XFER_TCP_SERVER
+} uv__ipc_socket_xfer_type_t;
+
typedef struct {
WSAPROTOCOL_INFOW socket_info;
- int delayed_error;
-} uv__ipc_socket_info_ex;
+ uint32_t delayed_error;
+} uv__ipc_socket_xfer_info_t;
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
@@ -154,11 +96,13 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
-int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
- int tcp_connection);
-
-int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
- LPWSAPROTOCOL_INFOW protocol_info);
+int uv__tcp_xfer_export(uv_tcp_t* handle,
+ int pid,
+ uv__ipc_socket_xfer_type_t* xfer_type,
+ uv__ipc_socket_xfer_info_t* xfer_info);
+int uv__tcp_xfer_import(uv_tcp_t* tcp,
+ uv__ipc_socket_xfer_type_t xfer_type,
+ uv__ipc_socket_xfer_info_t* xfer_info);
/*
@@ -182,14 +126,14 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
-int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
- const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
-int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
- const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
- uv_write_cb cb);
-void uv__pipe_pause_read(uv_pipe_t* handle);
-void uv__pipe_unpause_read(uv_pipe_t* handle);
-void uv__pipe_stop_read(uv_pipe_t* handle);
+void uv__pipe_read_stop(uv_pipe_t* handle);
+int uv__pipe_write(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t bufs[],
+ size_t nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb);
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req);
@@ -252,15 +196,6 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
/*
- * Timers
- */
-void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
-
-DWORD uv__next_timeout(const uv_loop_t* loop);
-void uv_process_timers(uv_loop_t* loop);
-
-
-/*
* Loop watchers
*/
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
@@ -336,7 +271,6 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
void uv__util_init(void);
uint64_t uv__hrtime(double scale);
-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);
diff --git a/Utilities/cmlibuv/src/win/loop-watcher.c b/Utilities/cmlibuv/src/win/loop-watcher.c
index 20e4509..ad7fbea 100644
--- a/Utilities/cmlibuv/src/win/loop-watcher.c
+++ b/Utilities/cmlibuv/src/win/loop-watcher.c
@@ -27,7 +27,7 @@
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED;
uv__handle_close(handle);
diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c
index 83ee4f9..277f649 100644
--- a/Utilities/cmlibuv/src/win/pipe.c
+++ b/Utilities/cmlibuv/src/win/pipe.c
@@ -21,39 +21,28 @@
#include <assert.h>
#include <io.h>
-#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
-#include "uv.h"
-#include "internal.h"
#include "handle-inl.h"
-#include "stream-inl.h"
+#include "internal.h"
#include "req-inl.h"
+#include "stream-inl.h"
+#include "uv-common.h"
+#include "uv.h"
#include <aclapi.h>
#include <accctrl.h>
-typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t;
-
-struct uv__ipc_queue_item_s {
- /*
- * NOTE: It is important for socket_info_ex to be the first field,
- * because we will we assigning it to the pending_ipc_info.socket_info
- */
- uv__ipc_socket_info_ex socket_info_ex;
- QUEUE member;
- int tcp_connection;
-};
-
/* A zero-size buffer for use by uv_pipe_read */
static char uv_zero_[] = "";
/* Null uv_buf_t */
static const uv_buf_t uv_null_buf_ = { 0, NULL };
-/* The timeout that the pipe will wait for the remote end to write data */
-/* when the local ends wants to shut it down. */
+/* The timeout that the pipe will wait for the remote end to write data when
+ * the local ends wants to shut it down. */
static const int64_t eof_timeout = 50; /* ms */
static const int default_pending_pipe_instances = 4;
@@ -62,22 +51,44 @@ static const int default_pending_pipe_instances = 4;
static char pipe_prefix[] = "\\\\?\\pipe";
static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
-/* IPC protocol flags. */
-#define UV_IPC_RAW_DATA 0x0001
-#define UV_IPC_TCP_SERVER 0x0002
-#define UV_IPC_TCP_CONNECTION 0x0004
+/* IPC incoming xfer queue item. */
+typedef struct {
+ uv__ipc_socket_xfer_type_t xfer_type;
+ uv__ipc_socket_xfer_info_t xfer_info;
+ QUEUE member;
+} uv__ipc_xfer_queue_item_t;
+
+/* IPC frame header flags. */
+/* clang-format off */
+enum {
+ UV__IPC_FRAME_HAS_DATA = 0x01,
+ UV__IPC_FRAME_HAS_SOCKET_XFER = 0x02,
+ UV__IPC_FRAME_XFER_IS_TCP_CONNECTION = 0x04,
+ /* These are combinations of the flags above. */
+ UV__IPC_FRAME_XFER_FLAGS = 0x06,
+ UV__IPC_FRAME_VALID_FLAGS = 0x07
+};
+/* clang-format on */
/* IPC frame header. */
typedef struct {
- int flags;
- uint64_t raw_data_length;
-} uv_ipc_frame_header_t;
-
-/* IPC frame, which contains an imported TCP socket stream. */
+ uint32_t flags;
+ uint32_t reserved1; /* Ignored. */
+ uint32_t data_length; /* Must be zero if there is no data. */
+ uint32_t reserved2; /* Must be zero. */
+} uv__ipc_frame_header_t;
+
+/* To implement the IPC protocol correctly, these structures must have exactly
+ * the right size. */
+STATIC_ASSERT(sizeof(uv__ipc_frame_header_t) == 16);
+STATIC_ASSERT(sizeof(uv__ipc_socket_xfer_info_t) == 632);
+
+/* Coalesced write request. */
typedef struct {
- uv_ipc_frame_header_t header;
- uv__ipc_socket_info_ex socket_info_ex;
-} uv_ipc_frame_uv_stream;
+ uv_write_t req; /* Internal heap-allocated write request. */
+ uv_write_t* user_req; /* Pointer to user-specified uv_write_t. */
+} uv__coalesced_write_t;
+
static void eof_timer_init(uv_pipe_t* pipe);
static void eof_timer_start(uv_pipe_t* pipe);
@@ -98,15 +109,12 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
handle->reqs_pending = 0;
handle->handle = INVALID_HANDLE_VALUE;
handle->name = NULL;
- handle->pipe.conn.ipc_pid = 0;
- handle->pipe.conn.remaining_ipc_rawdata_bytes = 0;
- QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue);
- handle->pipe.conn.pending_ipc_info.queue_len = 0;
+ handle->pipe.conn.ipc_remote_pid = 0;
+ handle->pipe.conn.ipc_data_frame.payload_remaining = 0;
+ QUEUE_INIT(&handle->pipe.conn.ipc_xfer_queue);
+ handle->pipe.conn.ipc_xfer_queue_length = 0;
handle->ipc = ipc;
handle->pipe.conn.non_overlapped_writes_tail = NULL;
- handle->pipe.conn.readfile_thread = NULL;
-
- UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ);
return 0;
}
@@ -117,10 +125,9 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
handle->read_req.data = handle;
handle->pipe.conn.eof_timer = NULL;
assert(!(handle->flags & UV_HANDLE_PIPESERVER));
- if (pCancelSynchronousIo &&
- handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
- uv_mutex_init(&handle->pipe.conn.readfile_mutex);
- handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
+ if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ handle->pipe.conn.readfile_thread_handle = NULL;
+ InitializeCriticalSection(&handle->pipe.conn.readfile_thread_lock);
}
}
@@ -347,12 +354,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
FILE_PIPE_LOCAL_INFORMATION pipe_info;
- uv__ipc_queue_item_t* item;
-
- if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
- uv_mutex_destroy(&handle->pipe.conn.readfile_mutex);
- }
+ uv__ipc_xfer_queue_item_t* xfer_queue_item;
if ((handle->flags & UV_HANDLE_CONNECTION) &&
handle->stream.conn.shutdown_req != NULL &&
@@ -362,7 +364,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Clear the shutdown_req field so we don't go here again. */
handle->stream.conn.shutdown_req = NULL;
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
UNREGISTER_HANDLE_REQ(loop, handle, req);
/* Already closing. Cancel the shutdown. */
@@ -423,33 +425,33 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
}
- if (handle->flags & UV__HANDLE_CLOSING &&
+ if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
if (handle->flags & UV_HANDLE_CONNECTION) {
/* Free pending sockets */
- while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) {
+ while (!QUEUE_EMPTY(&handle->pipe.conn.ipc_xfer_queue)) {
QUEUE* q;
SOCKET socket;
- q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue);
+ q = QUEUE_HEAD(&handle->pipe.conn.ipc_xfer_queue);
QUEUE_REMOVE(q);
- item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
+ xfer_queue_item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member);
/* Materialize socket and close it */
socket = WSASocketW(FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
- &item->socket_info_ex.socket_info,
+ &xfer_queue_item->xfer_info.socket_info,
0,
WSA_FLAG_OVERLAPPED);
- uv__free(item);
+ uv__free(xfer_queue_item);
if (socket != INVALID_SOCKET)
closesocket(socket);
}
- handle->pipe.conn.pending_ipc_info.queue_len = 0;
+ handle->pipe.conn.ipc_xfer_queue_length = 0;
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
@@ -461,6 +463,9 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
handle->read_req.event_handle = NULL;
}
}
+
+ if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)
+ DeleteCriticalSection(&handle->pipe.conn.readfile_thread_lock);
}
if (handle->flags & UV_HANDLE_PIPESERVER) {
@@ -595,8 +600,8 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
loop = handle->loop;
assert(loop);
- /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
- /* We wait for the pipe to become available with WaitNamedPipe. */
+ /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait
+ * for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */
pipeHandle = open_named_pipe(handle->name, &duplex_flags);
@@ -706,55 +711,68 @@ error:
}
-void uv__pipe_pause_read(uv_pipe_t* handle) {
- if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- /* Pause the ReadFile task briefly, to work
- around the Windows kernel bug that causes
- any access to a NamedPipe to deadlock if
- any process has called ReadFile */
- HANDLE h;
- uv_mutex_lock(&handle->pipe.conn.readfile_mutex);
- h = handle->pipe.conn.readfile_thread;
- while (h) {
- /* spinlock: we expect this to finish quickly,
- or we are probably about to deadlock anyways
- (in the kernel), so it doesn't matter */
- pCancelSynchronousIo(h);
- SwitchToThread(); /* yield thread control briefly */
- h = handle->pipe.conn.readfile_thread;
- }
- }
-}
+void uv__pipe_interrupt_read(uv_pipe_t* handle) {
+ BOOL r;
+
+ if (!(handle->flags & UV_HANDLE_READ_PENDING))
+ return; /* No pending reads. */
+ if (handle->flags & UV_HANDLE_CANCELLATION_PENDING)
+ return; /* Already cancelled. */
+ if (handle->handle == INVALID_HANDLE_VALUE)
+ return; /* Pipe handle closed. */
+ if (!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)) {
+ /* Cancel asynchronous read. */
+ r = CancelIoEx(handle->handle, &handle->read_req.u.io.overlapped);
+ assert(r || GetLastError() == ERROR_NOT_FOUND);
-void uv__pipe_unpause_read(uv_pipe_t* handle) {
- if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- uv_mutex_unlock(&handle->pipe.conn.readfile_mutex);
+ } else {
+ /* Cancel synchronous read (which is happening in the thread pool). */
+ HANDLE thread;
+ volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle;
+
+ EnterCriticalSection(&handle->pipe.conn.readfile_thread_lock);
+
+ thread = *thread_ptr;
+ if (thread == NULL) {
+ /* The thread pool thread has not yet reached the point of blocking, we
+ * can pre-empt it by setting thread_handle to INVALID_HANDLE_VALUE. */
+ *thread_ptr = INVALID_HANDLE_VALUE;
+
+ } else {
+ /* Spin until the thread has acknowledged (by setting the thread to
+ * INVALID_HANDLE_VALUE) that it is past the point of blocking. */
+ while (thread != INVALID_HANDLE_VALUE) {
+ r = CancelSynchronousIo(thread);
+ assert(r || GetLastError() == ERROR_NOT_FOUND);
+ SwitchToThread(); /* Yield thread. */
+ thread = *thread_ptr;
+ }
+ }
+
+ LeaveCriticalSection(&handle->pipe.conn.readfile_thread_lock);
}
+
+ /* Set flag to indicate that read has been cancelled. */
+ handle->flags |= UV_HANDLE_CANCELLATION_PENDING;
}
-void uv__pipe_stop_read(uv_pipe_t* handle) {
- if (pCancelIoEx &&
- !(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) &&
- !(handle->flags & UV_HANDLE_EMULATE_IOCP) &&
- handle->flags & UV_HANDLE_READING &&
- handle->read_req.type == UV_READ) {
- pCancelIoEx(handle->handle, &handle->read_req.u.io.overlapped);
- }
+void uv__pipe_read_stop(uv_pipe_t* handle) {
handle->flags &= ~UV_HANDLE_READING;
- uv__pipe_pause_read((uv_pipe_t*)handle);
- uv__pipe_unpause_read((uv_pipe_t*)handle);
+ DECREASE_ACTIVE_COUNT(handle->loop, handle);
+
+ uv__pipe_interrupt_read(handle);
}
-/* Cleans up uv_pipe_t (server or connection) and all resources associated */
-/* with it. */
+/* Cleans up uv_pipe_t (server or connection) and all resources associated with
+ * it. */
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
int i;
HANDLE pipeHandle;
- uv__pipe_stop_read(handle);
+ uv__pipe_interrupt_read(handle);
if (handle->name) {
uv__free(handle->name);
@@ -864,23 +882,22 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
uv_pipe_t* pipe_client;
uv_pipe_accept_t* req;
QUEUE* q;
- uv__ipc_queue_item_t* item;
+ uv__ipc_xfer_queue_item_t* item;
int err;
if (server->ipc) {
- if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) {
+ if (QUEUE_EMPTY(&server->pipe.conn.ipc_xfer_queue)) {
/* No valid pending sockets. */
return WSAEWOULDBLOCK;
}
- q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue);
+ q = QUEUE_HEAD(&server->pipe.conn.ipc_xfer_queue);
QUEUE_REMOVE(q);
- server->pipe.conn.pending_ipc_info.queue_len--;
- item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
+ server->pipe.conn.ipc_xfer_queue_length--;
+ item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member);
- err = uv_tcp_import((uv_tcp_t*)client,
- &item->socket_info_ex,
- item->tcp_connection);
+ err = uv__tcp_xfer_import(
+ (uv_tcp_t*) client, item->xfer_type, &item->xfer_info);
if (err != 0)
return err;
@@ -889,8 +906,8 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
} else {
pipe_client = (uv_pipe_t*)client;
- /* Find a connection instance that has been connected, but not yet */
- /* accepted. */
+ /* Find a connection instance that has been connected, but not yet
+ * accepted. */
req = server->pipe.serv.pending_accepts;
if (!req) {
@@ -908,7 +925,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
req->next_pending = NULL;
req->pipeHandle = INVALID_HANDLE_VALUE;
- if (!(server->flags & UV__HANDLE_CLOSING)) {
+ if (!(server->flags & UV_HANDLE_CLOSING)) {
uv_pipe_queue_accept(loop, server, req, FALSE);
}
}
@@ -953,74 +970,75 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
}
-static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
- int result;
- DWORD bytes;
- uv_read_t* req = (uv_read_t*) parameter;
+static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* arg) {
+ uv_read_t* req = (uv_read_t*) arg;
uv_pipe_t* handle = (uv_pipe_t*) req->data;
uv_loop_t* loop = handle->loop;
- HANDLE hThread = NULL;
+ volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle;
+ CRITICAL_SECTION* lock = &handle->pipe.conn.readfile_thread_lock;
+ HANDLE thread;
+ DWORD bytes;
DWORD err;
- uv_mutex_t *m = &handle->pipe.conn.readfile_mutex;
- assert(req != NULL);
assert(req->type == UV_READ);
assert(handle->type == UV_NAMED_PIPE);
- if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
- if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
- GetCurrentProcess(), &hThread,
- 0, FALSE, DUPLICATE_SAME_ACCESS)) {
- handle->pipe.conn.readfile_thread = hThread;
- } else {
- hThread = NULL;
- }
- uv_mutex_unlock(m);
+ err = 0;
+
+ /* Create a handle to the current thread. */
+ if (!DuplicateHandle(GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &thread,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ err = GetLastError();
+ goto out1;
}
-restart_readfile:
- if (handle->flags & UV_HANDLE_READING) {
- result = ReadFile(handle->handle,
- &uv_zero_,
- 0,
- &bytes,
- NULL);
- if (!result) {
- err = GetLastError();
- if (err == ERROR_OPERATION_ABORTED &&
- handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- if (handle->flags & UV_HANDLE_READING) {
- /* just a brief break to do something else */
- handle->pipe.conn.readfile_thread = NULL;
- /* resume after it is finished */
- uv_mutex_lock(m);
- handle->pipe.conn.readfile_thread = hThread;
- uv_mutex_unlock(m);
- goto restart_readfile;
- } else {
- result = 1; /* successfully stopped reading */
- }
- }
- }
+
+ /* The lock needs to be held when thread handle is modified. */
+ EnterCriticalSection(lock);
+ if (*thread_ptr == INVALID_HANDLE_VALUE) {
+ /* uv__pipe_interrupt_read() cancelled reading before we got here. */
+ err = ERROR_OPERATION_ABORTED;
} else {
- result = 1; /* successfully aborted read before it even started */
- }
- if (hThread) {
- assert(hThread == handle->pipe.conn.readfile_thread);
- /* mutex does not control clearing readfile_thread */
- handle->pipe.conn.readfile_thread = NULL;
- uv_mutex_lock(m);
- /* only when we hold the mutex lock is it safe to
- open or close the handle */
- CloseHandle(hThread);
- uv_mutex_unlock(m);
+ /* Let main thread know which worker thread is doing the blocking read. */
+ assert(*thread_ptr == NULL);
+ *thread_ptr = thread;
}
+ LeaveCriticalSection(lock);
- if (!result) {
- SET_REQ_ERROR(req, err);
- }
+ if (err)
+ goto out2;
+
+ /* Block the thread until data is available on the pipe, or the read is
+ * cancelled. */
+ if (!ReadFile(handle->handle, &uv_zero_, 0, &bytes, NULL))
+ err = GetLastError();
+
+ /* Let the main thread know the worker is past the point of blocking. */
+ assert(thread == *thread_ptr);
+ *thread_ptr = INVALID_HANDLE_VALUE;
+
+ /* Briefly acquire the mutex. Since the main thread holds the lock while it
+ * is spinning trying to cancel this thread's I/O, we will block here until
+ * it stops doing that. */
+ EnterCriticalSection(lock);
+ LeaveCriticalSection(lock);
+out2:
+ /* Close the handle to the current thread. */
+ CloseHandle(thread);
+
+out1:
+ /* Set request status and post a completion record to the IOCP. */
+ if (err)
+ SET_REQ_ERROR(req, err);
+ else
+ SET_REQ_SUCCESS(req);
POST_COMPLETION_FOR_REQ(loop, req);
+
return 0;
}
@@ -1102,6 +1120,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
req = &handle->read_req;
if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ handle->pipe.conn.readfile_thread_handle = NULL; /* Reset cancellation. */
if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
req,
WT_EXECUTELONGFUNCTION)) {
@@ -1169,8 +1188,8 @@ int uv_pipe_read_start(uv_pipe_t* handle,
handle->read_cb = read_cb;
handle->alloc_cb = alloc_cb;
- /* If reading was stopped and then started again, there could still be a */
- /* read request pending. */
+ /* If reading was stopped and then started again, there could still be a read
+ * request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_pipe_queue_read(loop, handle);
@@ -1226,154 +1245,110 @@ static void uv_queue_non_overlapped_write(uv_pipe_t* handle) {
}
-static int uv_pipe_write_impl(uv_loop_t* loop,
- uv_write_t* req,
- uv_pipe_t* handle,
- const uv_buf_t bufs[],
- unsigned int nbufs,
- uv_stream_t* send_handle,
- uv_write_cb cb) {
- int err;
- int result;
- uv_tcp_t* tcp_send_handle;
- uv_write_t* ipc_header_req = NULL;
- uv_ipc_frame_uv_stream ipc_frame;
+static int uv__build_coalesced_write_req(uv_write_t* user_req,
+ const uv_buf_t bufs[],
+ size_t nbufs,
+ uv_write_t** req_out,
+ uv_buf_t* write_buf_out) {
+ /* Pack into a single heap-allocated buffer:
+ * (a) a uv_write_t structure where libuv stores the actual state.
+ * (b) a pointer to the original uv_write_t.
+ * (c) data from all `bufs` entries.
+ */
+ char* heap_buffer;
+ size_t heap_buffer_length, heap_buffer_offset;
+ uv__coalesced_write_t* coalesced_write_req; /* (a) + (b) */
+ char* data_start; /* (c) */
+ size_t data_length;
+ unsigned int i;
+
+ /* Compute combined size of all combined buffers from `bufs`. */
+ data_length = 0;
+ for (i = 0; i < nbufs; i++)
+ data_length += bufs[i].len;
+
+ /* The total combined size of data buffers should not exceed UINT32_MAX,
+ * because WriteFile() won't accept buffers larger than that. */
+ if (data_length > UINT32_MAX)
+ return WSAENOBUFS; /* Maps to UV_ENOBUFS. */
+
+ /* Compute heap buffer size. */
+ heap_buffer_length = sizeof *coalesced_write_req + /* (a) + (b) */
+ data_length; /* (c) */
+
+ /* Allocate buffer. */
+ heap_buffer = uv__malloc(heap_buffer_length);
+ if (heap_buffer == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
+
+ /* Copy uv_write_t information to the buffer. */
+ coalesced_write_req = (uv__coalesced_write_t*) heap_buffer;
+ coalesced_write_req->req = *user_req; /* copy (a) */
+ coalesced_write_req->req.coalesced = 1;
+ coalesced_write_req->user_req = user_req; /* copy (b) */
+ heap_buffer_offset = sizeof *coalesced_write_req; /* offset (a) + (b) */
+
+ /* Copy data buffers to the heap buffer. */
+ data_start = &heap_buffer[heap_buffer_offset];
+ for (i = 0; i < nbufs; i++) {
+ memcpy(&heap_buffer[heap_buffer_offset],
+ bufs[i].base,
+ bufs[i].len); /* copy (c) */
+ heap_buffer_offset += bufs[i].len; /* offset (c) */
+ }
+ assert(heap_buffer_offset == heap_buffer_length);
+
+ /* Set out arguments and return. */
+ *req_out = &coalesced_write_req->req;
+ *write_buf_out = uv_buf_init(data_start, (unsigned int) data_length);
+ return 0;
+}
- if (nbufs != 1 && (nbufs != 0 || !send_handle)) {
- return ERROR_NOT_SUPPORTED;
- }
- /* Only TCP handles are supported for sharing. */
- if (send_handle && ((send_handle->type != UV_TCP) ||
- (!(send_handle->flags & UV_HANDLE_BOUND) &&
- !(send_handle->flags & UV_HANDLE_CONNECTION)))) {
- return ERROR_NOT_SUPPORTED;
- }
+static int uv__pipe_write_data(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t bufs[],
+ size_t nbufs,
+ uv_write_cb cb,
+ int copy_always) {
+ int err;
+ int result;
+ uv_buf_t write_buf;
assert(handle->handle != INVALID_HANDLE_VALUE);
UV_REQ_INIT(req, UV_WRITE);
req->handle = (uv_stream_t*) handle;
+ req->send_handle = NULL;
req->cb = cb;
- req->ipc_header = 0;
+ /* Private fields. */
+ req->coalesced = 0;
req->event_handle = NULL;
req->wait_handle = INVALID_HANDLE_VALUE;
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
-
- if (handle->ipc) {
- assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
- ipc_frame.header.flags = 0;
-
- /* Use the IPC framing protocol. */
- if (send_handle) {
- tcp_send_handle = (uv_tcp_t*)send_handle;
-
- if (handle->pipe.conn.ipc_pid == 0) {
- handle->pipe.conn.ipc_pid = uv_current_pid();
- }
-
- err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid,
- &ipc_frame.socket_info_ex.socket_info);
- if (err) {
- return err;
- }
-
- ipc_frame.socket_info_ex.delayed_error = tcp_send_handle->delayed_error;
-
- ipc_frame.header.flags |= UV_IPC_TCP_SERVER;
-
- if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) {
- ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION;
- }
- }
-
- if (nbufs == 1) {
- ipc_frame.header.flags |= UV_IPC_RAW_DATA;
- ipc_frame.header.raw_data_length = bufs[0].len;
- }
-
- /*
- * Use the provided req if we're only doing a single write.
- * If we're doing multiple writes, use ipc_header_write_req to do
- * the first write, and then use the provided req for the second write.
- */
- if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
- ipc_header_req = req;
- } else {
- /*
- * Try to use the preallocated write req if it's available.
- * Otherwise allocate a new one.
- */
- if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
- ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
- } else {
- ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t));
- if (!ipc_header_req) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
- }
-
- 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;
- }
-
- /* Write the header or the whole frame. */
- memset(&ipc_header_req->u.io.overlapped, 0,
- sizeof(ipc_header_req->u.io.overlapped));
-
- /* Using overlapped IO, but wait for completion before returning.
- This write is blocking because ipc_frame is on stack. */
- ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
- if (!ipc_header_req->u.io.overlapped.hEvent) {
- uv_fatal_error(GetLastError(), "CreateEvent");
- }
-
- result = WriteFile(handle->handle,
- &ipc_frame,
- ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
- sizeof(ipc_frame) : sizeof(ipc_frame.header),
- NULL,
- &ipc_header_req->u.io.overlapped);
- if (!result && GetLastError() != ERROR_IO_PENDING) {
- err = GetLastError();
- CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
+ req->write_buffer = uv_null_buf_;
+
+ if (nbufs == 0) {
+ /* Write empty buffer. */
+ write_buf = uv_null_buf_;
+ } else if (nbufs == 1 && !copy_always) {
+ /* Write directly from bufs[0]. */
+ write_buf = bufs[0];
+ } else {
+ /* Coalesce all `bufs` into one big buffer. This also creates a new
+ * write-request structure that replaces the old one. */
+ err = uv__build_coalesced_write_req(req, bufs, nbufs, &req, &write_buf);
+ if (err != 0)
return err;
- }
-
- if (!result) {
- /* Request not completed immediately. Wait for it.*/
- if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) !=
- WAIT_OBJECT_0) {
- err = GetLastError();
- CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
- return err;
- }
- }
- ipc_header_req->u.io.queued_bytes = 0;
- CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
- ipc_header_req->u.io.overlapped.hEvent = NULL;
-
- REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
- handle->reqs_pending++;
- handle->stream.conn.write_reqs_pending++;
-
- /* If we don't have any raw data to write - we're done. */
- if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
- return 0;
- }
}
if ((handle->flags &
(UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) ==
(UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) {
DWORD bytes;
- result = WriteFile(handle->handle,
- bufs[0].base,
- bufs[0].len,
- &bytes,
- NULL);
+ result =
+ WriteFile(handle->handle, write_buf.base, write_buf.len, &bytes, NULL);
if (!result) {
err = GetLastError();
@@ -1389,14 +1364,14 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
} else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
- req->write_buffer = bufs[0];
+ req->write_buffer = write_buf;
uv_insert_non_overlapped_write_req(handle, req);
if (handle->stream.conn.write_reqs_pending == 0) {
uv_queue_non_overlapped_write(handle);
}
/* Request queued by the kernel. */
- req->u.io.queued_bytes = bufs[0].len;
+ req->u.io.queued_bytes = write_buf.len;
handle->write_queue_size += req->u.io.queued_bytes;
} else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
/* Using overlapped IO, but wait for completion before returning */
@@ -1406,8 +1381,8 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
}
result = WriteFile(handle->handle,
- bufs[0].base,
- bufs[0].len,
+ write_buf.base,
+ write_buf.len,
NULL,
&req->u.io.overlapped);
@@ -1422,13 +1397,13 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->u.io.queued_bytes = 0;
} else {
/* Request queued by the kernel. */
- req->u.io.queued_bytes = bufs[0].len;
+ req->u.io.queued_bytes = write_buf.len;
handle->write_queue_size += req->u.io.queued_bytes;
if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) {
err = GetLastError();
CloseHandle(req->u.io.overlapped.hEvent);
- return uv_translate_sys_error(err);
+ return err;
}
}
CloseHandle(req->u.io.overlapped.hEvent);
@@ -1439,8 +1414,8 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
return 0;
} else {
result = WriteFile(handle->handle,
- bufs[0].base,
- bufs[0].len,
+ write_buf.base,
+ write_buf.len,
NULL,
&req->u.io.overlapped);
@@ -1453,7 +1428,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->u.io.queued_bytes = 0;
} else {
/* Request queued by the kernel. */
- req->u.io.queued_bytes = bufs[0].len;
+ req->u.io.queued_bytes = write_buf.len;
handle->write_queue_size += req->u.io.queued_bytes;
}
@@ -1478,35 +1453,143 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
}
-int uv_pipe_write(uv_loop_t* loop,
- uv_write_t* req,
- uv_pipe_t* handle,
- const uv_buf_t bufs[],
- unsigned int nbufs,
- uv_write_cb cb) {
- return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb);
+static DWORD uv__pipe_get_ipc_remote_pid(uv_pipe_t* handle) {
+ DWORD* pid = &handle->pipe.conn.ipc_remote_pid;
+
+ /* If the both ends of the IPC pipe are owned by the same process,
+ * the remote end pid may not yet be set. If so, do it here.
+ * TODO: this is weird; it'd probably better to use a handshake. */
+ if (*pid == 0)
+ *pid = GetCurrentProcessId();
+
+ return *pid;
+}
+
+
+int uv__pipe_write_ipc(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t data_bufs[],
+ size_t data_buf_count,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
+ uv_buf_t stack_bufs[6];
+ uv_buf_t* bufs;
+ size_t buf_count, buf_index;
+ uv__ipc_frame_header_t frame_header;
+ uv__ipc_socket_xfer_type_t xfer_type = UV__IPC_SOCKET_XFER_NONE;
+ uv__ipc_socket_xfer_info_t xfer_info;
+ uint64_t data_length;
+ size_t i;
+ int err;
+
+ /* Compute the combined size of data buffers. */
+ data_length = 0;
+ for (i = 0; i < data_buf_count; i++)
+ data_length += data_bufs[i].len;
+ if (data_length > UINT32_MAX)
+ return WSAENOBUFS; /* Maps to UV_ENOBUFS. */
+
+ /* Prepare the frame's socket xfer payload. */
+ if (send_handle != NULL) {
+ uv_tcp_t* send_tcp_handle = (uv_tcp_t*) send_handle;
+
+ /* Verify that `send_handle` it is indeed a tcp handle. */
+ if (send_tcp_handle->type != UV_TCP)
+ return ERROR_NOT_SUPPORTED;
+
+ /* Export the tcp handle. */
+ err = uv__tcp_xfer_export(send_tcp_handle,
+ uv__pipe_get_ipc_remote_pid(handle),
+ &xfer_type,
+ &xfer_info);
+ if (err != 0)
+ return err;
+ }
+
+ /* Compute the number of uv_buf_t's required. */
+ buf_count = 1 + data_buf_count; /* Frame header and data buffers. */
+ if (send_handle != NULL)
+ buf_count += 1; /* One extra for the socket xfer information. */
+
+ /* Use the on-stack buffer array if it is big enough; otherwise allocate
+ * space for it on the heap. */
+ if (buf_count < ARRAY_SIZE(stack_bufs)) {
+ /* Use on-stack buffer array. */
+ bufs = stack_bufs;
+ } else {
+ /* Use heap-allocated buffer array. */
+ bufs = uv__calloc(buf_count, sizeof(uv_buf_t));
+ if (bufs == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
+ }
+ buf_index = 0;
+
+ /* Initialize frame header and add it to the buffers list. */
+ memset(&frame_header, 0, sizeof frame_header);
+ bufs[buf_index++] = uv_buf_init((char*) &frame_header, sizeof frame_header);
+
+ if (send_handle != NULL) {
+ /* Add frame header flags. */
+ switch (xfer_type) {
+ case UV__IPC_SOCKET_XFER_TCP_CONNECTION:
+ frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER |
+ UV__IPC_FRAME_XFER_IS_TCP_CONNECTION;
+ break;
+ case UV__IPC_SOCKET_XFER_TCP_SERVER:
+ frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER;
+ break;
+ default:
+ assert(0); /* Unreachable. */
+ }
+ /* Add xfer info buffer. */
+ bufs[buf_index++] = uv_buf_init((char*) &xfer_info, sizeof xfer_info);
+ }
+
+ if (data_length > 0) {
+ /* Update frame header. */
+ frame_header.flags |= UV__IPC_FRAME_HAS_DATA;
+ frame_header.data_length = (uint32_t) data_length;
+ /* Add data buffers to buffers list. */
+ for (i = 0; i < data_buf_count; i++)
+ bufs[buf_index++] = data_bufs[i];
+ }
+
+ /* Write buffers. We set the `always_copy` flag, so it is not a problem that
+ * some of the written data lives on the stack. */
+ err = uv__pipe_write_data(loop, req, handle, bufs, buf_count, cb, 1);
+
+ /* If we had to heap-allocate the bufs array, free it now. */
+ if (bufs != stack_bufs) {
+ uv__free(bufs);
+ }
+
+ return err;
}
-int uv_pipe_write2(uv_loop_t* loop,
+int uv__pipe_write(uv_loop_t* loop,
uv_write_t* req,
uv_pipe_t* handle,
const uv_buf_t bufs[],
- unsigned int nbufs,
+ size_t nbufs,
uv_stream_t* send_handle,
uv_write_cb cb) {
- if (!handle->ipc) {
- return WSAEINVAL;
+ if (handle->ipc) {
+ /* IPC pipe write: use framing protocol. */
+ return uv__pipe_write_ipc(loop, req, handle, bufs, nbufs, send_handle, cb);
+ } else {
+ /* Non-IPC pipe write: put data on the wire directly. */
+ assert(send_handle == NULL);
+ return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0);
}
-
- return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb);
}
static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
uv_buf_t buf) {
- /* If there is an eof timer running, we don't need it any more, */
- /* so discard it. */
+ /* If there is an eof timer running, we don't need it any more, so discard
+ * it. */
eof_timer_destroy(handle);
handle->flags &= ~UV_HANDLE_READABLE;
@@ -1518,8 +1601,8 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
uv_buf_t buf) {
- /* If there is an eof timer running, we don't need it any more, */
- /* so discard it. */
+ /* If there is an eof timer running, we don't need it any more, so discard
+ * it. */
eof_timer_destroy(handle);
uv_read_stop((uv_stream_t*) handle);
@@ -1530,10 +1613,7 @@ static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
int error, uv_buf_t buf) {
- if (error == ERROR_OPERATION_ABORTED) {
- /* do nothing (equivalent to EINTR) */
- }
- else if (error == ERROR_BROKEN_PIPE) {
+ if (error == ERROR_BROKEN_PIPE) {
uv_pipe_read_eof(loop, handle, buf);
} else {
uv_pipe_read_error(loop, handle, error, buf);
@@ -1541,152 +1621,228 @@ static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
}
-void uv__pipe_insert_pending_socket(uv_pipe_t* handle,
- uv__ipc_socket_info_ex* info,
- int tcp_connection) {
- uv__ipc_queue_item_t* item;
+static void uv__pipe_queue_ipc_xfer_info(
+ uv_pipe_t* handle,
+ uv__ipc_socket_xfer_type_t xfer_type,
+ uv__ipc_socket_xfer_info_t* xfer_info) {
+ uv__ipc_xfer_queue_item_t* item;
- item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item));
+ item = (uv__ipc_xfer_queue_item_t*) uv__malloc(sizeof(*item));
if (item == NULL)
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex));
- item->tcp_connection = tcp_connection;
- QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member);
- handle->pipe.conn.pending_ipc_info.queue_len++;
+ item->xfer_type = xfer_type;
+ item->xfer_info = *xfer_info;
+
+ QUEUE_INSERT_TAIL(&handle->pipe.conn.ipc_xfer_queue, &item->member);
+ handle->pipe.conn.ipc_xfer_queue_length++;
+}
+
+
+/* Read an exact number of bytes from a pipe. If an error or end-of-file is
+ * encountered before the requested number of bytes are read, an error is
+ * returned. */
+static int uv__pipe_read_exactly(HANDLE h, void* buffer, DWORD count) {
+ DWORD bytes_read, bytes_read_now;
+
+ bytes_read = 0;
+ while (bytes_read < count) {
+ if (!ReadFile(h,
+ (char*) buffer + bytes_read,
+ count - bytes_read,
+ &bytes_read_now,
+ NULL)) {
+ return GetLastError();
+ }
+
+ bytes_read += bytes_read_now;
+ }
+
+ assert(bytes_read == count);
+ return 0;
}
-void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
- uv_req_t* req) {
- DWORD bytes, avail;
+static DWORD uv__pipe_read_data(uv_loop_t* loop,
+ uv_pipe_t* handle,
+ DWORD suggested_bytes,
+ DWORD max_bytes) {
+ DWORD bytes_read;
uv_buf_t buf;
- uv_ipc_frame_uv_stream ipc_frame;
+ /* Ask the user for a buffer to read data into. */
+ buf = uv_buf_init(NULL, 0);
+ handle->alloc_cb((uv_handle_t*) handle, suggested_bytes, &buf);
+ if (buf.base == NULL || buf.len == 0) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+ return 0; /* Break out of read loop. */
+ }
+
+ /* Ensure we read at most the smaller of:
+ * (a) the length of the user-allocated buffer.
+ * (b) the maximum data length as specified by the `max_bytes` argument.
+ */
+ if (max_bytes > buf.len)
+ max_bytes = buf.len;
+
+ /* Read into the user buffer. */
+ if (!ReadFile(handle->handle, buf.base, max_bytes, &bytes_read, NULL)) {
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf);
+ return 0; /* Break out of read loop. */
+ }
+
+ /* Call the read callback. */
+ handle->read_cb((uv_stream_t*) handle, bytes_read, &buf);
+
+ return bytes_read;
+}
+
+
+static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) {
+ uint32_t* data_remaining = &handle->pipe.conn.ipc_data_frame.payload_remaining;
+ int err;
+
+ if (*data_remaining > 0) {
+ /* Read frame data payload. */
+ DWORD bytes_read =
+ uv__pipe_read_data(loop, handle, *data_remaining, *data_remaining);
+ *data_remaining -= bytes_read;
+ return bytes_read;
+
+ } else {
+ /* Start of a new IPC frame. */
+ uv__ipc_frame_header_t frame_header;
+ uint32_t xfer_flags;
+ uv__ipc_socket_xfer_type_t xfer_type;
+ uv__ipc_socket_xfer_info_t xfer_info;
+
+ /* Read the IPC frame header. */
+ err = uv__pipe_read_exactly(
+ handle->handle, &frame_header, sizeof frame_header);
+ if (err)
+ goto error;
+
+ /* Validate that flags are valid. */
+ if ((frame_header.flags & ~UV__IPC_FRAME_VALID_FLAGS) != 0)
+ goto invalid;
+ /* Validate that reserved2 is zero. */
+ if (frame_header.reserved2 != 0)
+ goto invalid;
+
+ /* Parse xfer flags. */
+ xfer_flags = frame_header.flags & UV__IPC_FRAME_XFER_FLAGS;
+ if (xfer_flags & UV__IPC_FRAME_HAS_SOCKET_XFER) {
+ /* Socket coming -- determine the type. */
+ xfer_type = xfer_flags & UV__IPC_FRAME_XFER_IS_TCP_CONNECTION
+ ? UV__IPC_SOCKET_XFER_TCP_CONNECTION
+ : UV__IPC_SOCKET_XFER_TCP_SERVER;
+ } else if (xfer_flags == 0) {
+ /* No socket. */
+ xfer_type = UV__IPC_SOCKET_XFER_NONE;
+ } else {
+ /* Invalid flags. */
+ goto invalid;
+ }
+
+ /* Parse data frame information. */
+ if (frame_header.flags & UV__IPC_FRAME_HAS_DATA) {
+ *data_remaining = frame_header.data_length;
+ } else if (frame_header.data_length != 0) {
+ /* Data length greater than zero but data flag not set -- invalid. */
+ goto invalid;
+ }
+
+ /* If no socket xfer info follows, return here. Data will be read in a
+ * subsequent invocation of uv__pipe_read_ipc(). */
+ if (xfer_type == UV__IPC_SOCKET_XFER_NONE)
+ return sizeof frame_header; /* Number of bytes read. */
+
+ /* Read transferred socket information. */
+ err = uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info);
+ if (err)
+ goto error;
+
+ /* Store the pending socket info. */
+ uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info);
+
+ /* Return number of bytes read. */
+ return sizeof frame_header + sizeof xfer_info;
+ }
+
+invalid:
+ /* Invalid frame. */
+ err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */
+
+error:
+ uv_pipe_read_error_or_eof(loop, handle, err, uv_null_buf_);
+ return 0; /* Break out of read loop. */
+}
+
+
+void uv_process_pipe_read_req(uv_loop_t* loop,
+ uv_pipe_t* handle,
+ uv_req_t* req) {
assert(handle->type == UV_NAMED_PIPE);
- handle->flags &= ~UV_HANDLE_READ_PENDING;
+ handle->flags &= ~(UV_HANDLE_READ_PENDING | UV_HANDLE_CANCELLATION_PENDING);
+ DECREASE_PENDING_REQ_COUNT(handle);
eof_timer_stop(handle);
- if (!REQ_SUCCESS(req)) {
- /* An error occurred doing the 0-read. */
- if (handle->flags & UV_HANDLE_READING) {
- uv_pipe_read_error_or_eof(loop,
- handle,
- GET_REQ_ERROR(req),
- uv_null_buf_);
- }
- } else {
- /* Do non-blocking reads until the buffer is empty */
- while (handle->flags & UV_HANDLE_READING) {
- if (!PeekNamedPipe(handle->handle,
- NULL,
- 0,
- NULL,
- &avail,
- NULL)) {
- uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
- break;
- }
+ /* At this point, we're done with bookkeeping. If the user has stopped
+ * reading the pipe in the meantime, there is nothing left to do, since there
+ * is no callback that we can call. */
+ if (!(handle->flags & UV_HANDLE_READING))
+ return;
- if (avail == 0) {
- /* There is nothing to read after all. */
- break;
- }
+ if (!REQ_SUCCESS(req)) {
+ /* An error occurred doing the zero-read. */
+ DWORD err = GET_REQ_ERROR(req);
- if (handle->ipc) {
- /* Use the IPC framing protocol to read the incoming data. */
- if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) {
- /* We're reading a new frame. First, read the header. */
- assert(avail >= sizeof(ipc_frame.header));
-
- if (!ReadFile(handle->handle,
- &ipc_frame.header,
- sizeof(ipc_frame.header),
- &bytes,
- NULL)) {
- uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
- uv_null_buf_);
- break;
- }
-
- assert(bytes == sizeof(ipc_frame.header));
- assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA |
- UV_IPC_TCP_CONNECTION));
-
- if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) {
- assert(avail - sizeof(ipc_frame.header) >=
- sizeof(ipc_frame.socket_info_ex));
-
- /* Read the TCP socket info. */
- if (!ReadFile(handle->handle,
- &ipc_frame.socket_info_ex,
- sizeof(ipc_frame) - sizeof(ipc_frame.header),
- &bytes,
- NULL)) {
- uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
- uv_null_buf_);
- break;
- }
-
- assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header));
-
- /* Store the pending socket info. */
- uv__pipe_insert_pending_socket(
- handle,
- &ipc_frame.socket_info_ex,
- ipc_frame.header.flags & UV_IPC_TCP_CONNECTION);
- }
-
- if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
- handle->pipe.conn.remaining_ipc_rawdata_bytes =
- ipc_frame.header.raw_data_length;
- continue;
- }
- } else {
- avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes);
- }
- }
+ /* If the read was cancelled by uv__pipe_interrupt_read(), the request may
+ * indicate an ERROR_OPERATION_ABORTED error. This error isn't relevant to
+ * the user; we'll start a new zero-read at the end of this function. */
+ if (err != ERROR_OPERATION_ABORTED)
+ uv_pipe_read_error_or_eof(loop, handle, err, uv_null_buf_);
- buf = uv_buf_init(NULL, 0);
- handle->alloc_cb((uv_handle_t*) handle, avail, &buf);
- if (buf.base == NULL || buf.len == 0) {
- handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+ } else {
+ /* The zero-read completed without error, indicating there is data
+ * available in the kernel buffer. */
+ DWORD avail;
+
+ /* Get the number of bytes available. */
+ avail = 0;
+ if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL))
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
+
+ /* Read until we've either read all the bytes available, or the 'reading'
+ * flag is cleared. */
+ while (avail > 0 && handle->flags & UV_HANDLE_READING) {
+ /* Depending on the type of pipe, read either IPC frames or raw data. */
+ DWORD bytes_read =
+ handle->ipc ? uv__pipe_read_ipc(loop, handle)
+ : uv__pipe_read_data(loop, handle, avail, (DWORD) -1);
+
+ /* If no bytes were read, treat this as an indication that an error
+ * occurred, and break out of the read loop. */
+ if (bytes_read == 0)
break;
- }
- assert(buf.base != NULL);
-
- if (ReadFile(handle->handle,
- buf.base,
- min(buf.len, avail),
- &bytes,
- NULL)) {
- /* Successful read */
- if (handle->ipc) {
- assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes);
- handle->pipe.conn.remaining_ipc_rawdata_bytes =
- handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes;
- }
- handle->read_cb((uv_stream_t*)handle, bytes, &buf);
- /* Read again only if bytes == buf.len */
- if (bytes <= buf.len) {
- break;
- }
- } else {
- uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf);
+ /* It is possible that more bytes were read than we thought were
+ * available. To prevent `avail` from underflowing, break out of the loop
+ * if this is the case. */
+ if (bytes_read > avail)
break;
- }
- }
- /* Post another 0-read if still reading and not closing. */
- if ((handle->flags & UV_HANDLE_READING) &&
- !(handle->flags & UV_HANDLE_READ_PENDING)) {
- uv_pipe_queue_read(loop, handle);
+ /* Recompute the number of bytes available. */
+ avail -= bytes_read;
}
}
- DECREASE_PENDING_REQ_COUNT(handle);
+ /* Start another zero-read request if necessary. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_pipe_queue_read(loop, handle);
+ }
}
@@ -1712,17 +1868,19 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
}
}
- if (req->ipc_header) {
- if (req == &handle->pipe.conn.ipc_header_write_req) {
- req->type = UV_UNKNOWN_REQ;
- } else {
- uv__free(req);
- }
- } else {
- if (req->cb) {
- err = GET_REQ_ERROR(req);
- req->cb(req, uv_translate_sys_error(err));
- }
+ err = GET_REQ_ERROR(req);
+
+ /* If this was a coalesced write, extract pointer to the user_provided
+ * uv_write_t structure so we can pass the expected pointer to the callback,
+ * then free the heap-allocated write req. */
+ if (req->coalesced) {
+ uv__coalesced_write_t* coalesced_write =
+ container_of(req, uv__coalesced_write_t, req);
+ req = coalesced_write->user_req;
+ uv__free(coalesced_write);
+ }
+ if (req->cb) {
+ req->cb(req, uv_translate_sys_error(err));
}
handle->stream.conn.write_reqs_pending--;
@@ -1748,7 +1906,7 @@ void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
assert(handle->type == UV_NAMED_PIPE);
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
/* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */
assert(req->pipeHandle == INVALID_HANDLE_VALUE);
DECREASE_PENDING_REQ_COUNT(handle);
@@ -1768,7 +1926,7 @@ void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
}
- if (!(handle->flags & UV__HANDLE_CLOSING)) {
+ if (!(handle->flags & UV_HANDLE_CLOSING)) {
uv_pipe_queue_accept(loop, handle, req, FALSE);
}
}
@@ -1806,19 +1964,19 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
UNREGISTER_HANDLE_REQ(loop, handle, req);
if (handle->flags & UV_HANDLE_READABLE) {
- /* Initialize and optionally start the eof timer. Only do this if the */
- /* pipe is readable and we haven't seen EOF come in ourselves. */
+ /* Initialize and optionally start the eof timer. Only do this if the pipe
+ * is readable and we haven't seen EOF come in ourselves. */
eof_timer_init(handle);
- /* If reading start the timer right now. */
- /* Otherwise uv_pipe_queue_read will start it. */
+ /* If reading start the timer right now. Otherwise uv_pipe_queue_read will
+ * start it. */
if (handle->flags & UV_HANDLE_READ_PENDING) {
eof_timer_start(handle);
}
} else {
- /* This pipe is not readable. We can just close it to let the other end */
- /* know that we're done writing. */
+ /* This pipe is not readable. We can just close it to let the other end
+ * know that we're done writing. */
close_pipe(handle);
}
@@ -1869,17 +2027,16 @@ static void eof_timer_cb(uv_timer_t* timer) {
assert(pipe->type == UV_NAMED_PIPE);
- /* This should always be true, since we start the timer only */
- /* in uv_pipe_queue_read after successfully calling ReadFile, */
- /* or in uv_process_pipe_shutdown_req if a read is pending, */
- /* and we always immediately stop the timer in */
- /* uv_process_pipe_read_req. */
+ /* This should always be true, since we start the timer only in
+ * uv_pipe_queue_read after successfully calling ReadFile, or in
+ * uv_process_pipe_shutdown_req if a read is pending, and we always
+ * immediately stop the timer in uv_process_pipe_read_req. */
assert(pipe->flags & UV_HANDLE_READ_PENDING);
- /* If there are many packets coming off the iocp then the timer callback */
- /* may be called before the read request is coming off the queue. */
- /* Therefore we check here if the read request has completed but will */
- /* be processed later. */
+ /* If there are many packets coming off the iocp then the timer callback may
+ * be called before the read request is coming off the queue. Therefore we
+ * check here if the read request has completed but will be processed later.
+ */
if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
return;
@@ -1888,12 +2045,12 @@ static void eof_timer_cb(uv_timer_t* timer) {
/* Force both ends off the pipe. */
close_pipe(pipe);
- /* Stop reading, so the pending read that is going to fail will */
- /* not be reported to the user. */
+ /* Stop reading, so the pending read that is going to fail will not be
+ * reported to the user. */
uv_read_stop((uv_stream_t*) pipe);
- /* Report the eof and update flags. This will get reported even if the */
- /* user stopped reading in the meantime. TODO: is that okay? */
+ /* Report the eof and update flags. This will get reported even if the user
+ * stopped reading in the meantime. TODO: is that okay? */
uv_pipe_read_eof(loop, pipe, uv_null_buf_);
}
@@ -1980,8 +2137,8 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
- pipe->pipe.conn.ipc_pid = uv_os_getppid();
- assert(pipe->pipe.conn.ipc_pid != -1);
+ pipe->pipe.conn.ipc_remote_pid = uv_os_getppid();
+ assert(pipe->pipe.conn.ipc_remote_pid != (DWORD) -1);
}
return 0;
}
@@ -2006,7 +2163,15 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
return UV_EINVAL;
}
- uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */
+ /* NtQueryInformationFile will block if another thread is performing a
+ * blocking operation on the queried handle. If the pipe handle is
+ * synchronous, there may be a worker thread currently calling ReadFile() on
+ * the pipe handle, which could cause a deadlock. To avoid this, interrupt
+ * the read. */
+ if (handle->flags & UV_HANDLE_CONNECTION &&
+ handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ uv__pipe_interrupt_read((uv_pipe_t*) handle); /* cast away const warning */
+ }
nt_status = pNtQueryInformationFile(handle->handle,
&io_status,
@@ -2097,7 +2262,6 @@ error:
uv__free(name_info);
cleanup:
- uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
return err;
}
@@ -2105,7 +2269,7 @@ cleanup:
int uv_pipe_pending_count(uv_pipe_t* handle) {
if (!handle->ipc)
return 0;
- return handle->pipe.conn.pending_ipc_info.queue_len;
+ return handle->pipe.conn.ipc_xfer_queue_length;
}
@@ -2138,14 +2302,14 @@ int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
if (!handle->ipc)
return UV_UNKNOWN_HANDLE;
- if (handle->pipe.conn.pending_ipc_info.queue_len == 0)
+ if (handle->pipe.conn.ipc_xfer_queue_length == 0)
return UV_UNKNOWN_HANDLE;
else
return UV_TCP;
}
int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
- SID_IDENTIFIER_AUTHORITY sid_world = SECURITY_WORLD_SID_AUTHORITY;
+ SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY };
PACL old_dacl, new_dacl;
PSECURITY_DESCRIPTOR sd;
EXPLICIT_ACCESS ea;
@@ -2180,7 +2344,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
error = GetLastError();
goto clean_sid;
}
-
+
memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
if (mode & UV_READABLE)
ea.grfAccessPermissions |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
diff --git a/Utilities/cmlibuv/src/win/poll.c b/Utilities/cmlibuv/src/win/poll.c
index a648ba7..3c66786 100644
--- a/Utilities/cmlibuv/src/win/poll.c
+++ b/Utilities/cmlibuv/src/win/poll.c
@@ -75,7 +75,7 @@ static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) {
static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
uv_req_t* req;
AFD_POLL_INFO* afd_poll_info;
- DWORD result;
+ int result;
/* Find a yet unsubmitted req to submit. */
if (handle->submitted_events_1 == 0) {
@@ -91,16 +91,16 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
handle->mask_events_1 = handle->events;
handle->mask_events_2 = 0;
} else {
- /* Just wait until there's an unsubmitted req. */
- /* This will happen almost immediately as one of the 2 outstanding */
- /* requests is about to return. When this happens, */
- /* uv__fast_poll_process_poll_req will be called, and the pending */
- /* events, if needed, will be processed in a subsequent request. */
+ /* Just wait until there's an unsubmitted req. This will happen almost
+ * immediately as one of the 2 outstanding requests is about to return.
+ * When this happens, uv__fast_poll_process_poll_req will be called, and
+ * the pending events, if needed, will be processed in a subsequent
+ * request. */
return;
}
- /* Setting Exclusive to TRUE makes the other poll request return if there */
- /* is any. */
+ /* Setting Exclusive to TRUE makes the other poll request return if there is
+ * any. */
afd_poll_info->Exclusive = TRUE;
afd_poll_info->NumberOfHandles = 1;
afd_poll_info->Timeout.QuadPart = INT64_MAX;
@@ -136,7 +136,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
AFD_POLL_INFO afd_poll_info;
- DWORD result;
+ int result;
afd_poll_info.Exclusive = TRUE;
afd_poll_info.NumberOfHandles = 1;
@@ -218,7 +218,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if ((handle->events & ~(handle->submitted_events_1 |
handle->submitted_events_2)) != 0) {
uv__fast_poll_submit_poll_req(loop, handle);
- } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+ } else if ((handle->flags & UV_HANDLE_CLOSING) &&
handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -228,7 +228,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV__HANDLE_CLOSING));
+ assert(!(handle->flags & UV_HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
handle->events = events;
@@ -257,8 +257,8 @@ static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return 0;
} else {
- /* Cancel outstanding poll requests by executing another, unique poll */
- /* request that forces the outstanding ones to return. */
+ /* Cancel outstanding poll requests by executing another, unique poll
+ * request that forces the outstanding ones to return. */
return uv__fast_poll_cancel_poll_req(loop, handle);
}
}
@@ -316,9 +316,8 @@ static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop,
return INVALID_SOCKET;
}
- /* If we didn't (try) to create a peer socket yet, try to make one. Don't */
- /* try again if the peer socket creation failed earlier for the same */
- /* protocol. */
+ /* If we didn't (try) to create a peer socket yet, try to make one. Don't try
+ * again if the peer socket creation failed earlier for the same protocol. */
peer_socket = loop->poll_peer_sockets[index];
if (peer_socket == 0) {
peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info);
@@ -357,8 +356,8 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
efds.fd_count = 0;
}
- /* Make the select() time out after 3 minutes. If select() hangs because */
- /* the user closed the socket, we will at least not hang indefinitely. */
+ /* Make the select() time out after 3 minutes. If select() hangs because the
+ * user closed the socket, we will at least not hang indefinitely. */
timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0;
@@ -462,7 +461,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if ((handle->events & ~(handle->submitted_events_1 |
handle->submitted_events_2)) != 0) {
uv__slow_poll_submit_poll_req(loop, handle);
- } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+ } else if ((handle->flags & UV_HANDLE_CLOSING) &&
handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -472,7 +471,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV__HANDLE_CLOSING));
+ assert(!(handle->flags & UV_HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
handle->events = events;
@@ -522,10 +521,10 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR)
return uv_translate_sys_error(WSAGetLastError());
- /* Try to obtain a base handle for the socket. This increases this chances */
- /* that we find an AFD handle and are able to use the fast poll mechanism. */
- /* This will always fail on windows XP/2k3, since they don't support the */
- /* SIO_BASE_HANDLE ioctl. */
+/* Try to obtain a base handle for the socket. This increases this chances that
+ * we find an AFD handle and are able to use the fast poll mechanism. This will
+ * always fail on windows XP/2k3, since they don't support the. SIO_BASE_HANDLE
+ * ioctl. */
#ifndef NDEBUG
base_socket = INVALID_SOCKET;
#endif
@@ -557,9 +556,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
return uv_translate_sys_error(WSAGetLastError());
}
- /* Get the peer socket that is needed to enable fast poll. If the returned */
- /* value is NULL, the protocol is not implemented by MSAFD and we'll have */
- /* to use slow mode. */
+ /* Get the peer socket that is needed to enable fast poll. If the returned
+ * value is NULL, the protocol is not implemented by MSAFD and we'll have to
+ * use slow mode. */
peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info);
if (peer_socket != INVALID_SOCKET) {
@@ -634,7 +633,7 @@ int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
- assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(handle->flags & UV_HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
assert(handle->submitted_events_1 == 0);
diff --git a/Utilities/cmlibuv/src/win/process-stdio.c b/Utilities/cmlibuv/src/win/process-stdio.c
index 032e309..355d618 100644
--- a/Utilities/cmlibuv/src/win/process-stdio.c
+++ b/Utilities/cmlibuv/src/win/process-stdio.c
@@ -103,12 +103,12 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
DWORD client_access = 0;
HANDLE child_pipe = INVALID_HANDLE_VALUE;
int err;
+ int overlap;
if (flags & UV_READABLE_PIPE) {
- /* The server needs inbound access too, otherwise CreateNamedPipe() */
- /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */
- /* probe the state of the write buffer when we're trying to shutdown */
- /* the pipe. */
+ /* The server needs inbound access too, otherwise CreateNamedPipe() won't
+ * give us the FILE_READ_ATTRIBUTES permission. We need that to probe the
+ * state of the write buffer when we're trying to shutdown the pipe. */
server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
}
@@ -131,12 +131,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
+ overlap = server_pipe->ipc || (flags & UV_OVERLAPPED_PIPE);
child_pipe = CreateFileA(pipe_name,
client_access,
0,
&sa,
OPEN_EXISTING,
- server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
+ overlap ? FILE_FLAG_OVERLAPPED : 0,
NULL);
if (child_pipe == INVALID_HANDLE_VALUE) {
err = GetLastError();
@@ -159,8 +160,8 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
}
#endif
- /* Do a blocking ConnectNamedPipe. This should not block because we have */
- /* both ends of the pipe created. */
+ /* Do a blocking ConnectNamedPipe. This should not block because we have both
+ * ends of the pipe created. */
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) {
err = GetLastError();
@@ -194,11 +195,11 @@ static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
HANDLE current_process;
- /* _get_osfhandle will sometimes return -2 in case of an error. This seems */
- /* to happen when fd <= 2 and the process' corresponding stdio handle is */
- /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */
- /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */
- /* use the duplicate. Therefore we filter out known-invalid handles here. */
+ /* _get_osfhandle will sometimes return -2 in case of an error. This seems to
+ * happen when fd <= 2 and the process' corresponding stdio handle is set to
+ * NULL. Unfortunately DuplicateHandle will happily duplicate (HANDLE) -2, so
+ * this situation goes unnoticed until someone tries to use the duplicate.
+ * Therefore we filter out known-invalid handles here. */
if (handle == INVALID_HANDLE_VALUE ||
handle == NULL ||
handle == (HANDLE) -2) {
@@ -284,8 +285,8 @@ int uv__stdio_create(uv_loop_t* loop,
return ERROR_OUTOFMEMORY;
}
- /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
- /* clean up on failure. */
+ /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can clean
+ * up on failure. */
CHILD_STDIO_COUNT(buffer) = count;
for (i = 0; i < count; i++) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
@@ -303,12 +304,12 @@ int uv__stdio_create(uv_loop_t* loop,
switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
UV_INHERIT_STREAM)) {
case UV_IGNORE:
- /* Starting a process with no stdin/stout/stderr can confuse it. */
- /* So no matter what the user specified, we make sure the first */
- /* three FDs are always open in their typical modes, e.g. stdin */
- /* be readable and stdout/err should be writable. For FDs > 2, don't */
- /* do anything - all handles in the stdio buffer are initialized with */
- /* INVALID_HANDLE_VALUE, which should be okay. */
+ /* Starting a process with no stdin/stout/stderr can confuse it. So no
+ * matter what the user specified, we make sure the first three FDs are
+ * always open in their typical modes, e. g. stdin be readable and
+ * stdout/err should be writable. For FDs > 2, don't do anything - all
+ * handles in the stdio buffer are initialized with.
+ * INVALID_HANDLE_VALUE, which should be okay. */
if (i <= 2) {
DWORD access = (i == 0) ? FILE_GENERIC_READ :
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
@@ -323,14 +324,14 @@ int uv__stdio_create(uv_loop_t* loop,
break;
case UV_CREATE_PIPE: {
- /* Create a pair of two connected pipe ends; one end is turned into */
- /* an uv_pipe_t for use by the parent. The other one is given to */
- /* the child. */
+ /* Create a pair of two connected pipe ends; one end is turned into an
+ * uv_pipe_t for use by the parent. The other one is given to the
+ * child. */
uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
HANDLE child_pipe = INVALID_HANDLE_VALUE;
- /* Create a new, connected pipe pair. stdio[i].stream should point */
- /* to an uninitialized, but not connected pipe handle. */
+ /* Create a new, connected pipe pair. stdio[i]. stream should point to
+ * an uninitialized, but not connected pipe handle. */
assert(fdopt.data.stream->type == UV_NAMED_PIPE);
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
@@ -354,8 +355,8 @@ int uv__stdio_create(uv_loop_t* loop,
/* Make an inheritable duplicate of the handle. */
err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle);
if (err) {
- /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */
- /* error. */
+ /* If fdopt. data. fd is not valid and fd <= 2, then ignore the
+ * error. */
if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
@@ -418,8 +419,8 @@ int uv__stdio_create(uv_loop_t* loop,
if (stream_handle == NULL ||
stream_handle == INVALID_HANDLE_VALUE) {
- /* The handle is already closed, or not yet created, or the */
- /* stream type is not supported. */
+ /* The handle is already closed, or not yet created, or the stream
+ * type is not supported. */
err = ERROR_NOT_SUPPORTED;
goto error;
}
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index 25cfe87..24037b3 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -360,8 +360,8 @@ static WCHAR* search_path(const WCHAR *file,
return NULL;
}
- /* Find the start of the filename so we can split the directory from the */
- /* name. */
+ /* Find the start of the filename so we can split the directory from the
+ * name. */
for (file_name_start = (WCHAR*)file + file_len;
file_name_start > file
&& file_name_start[-1] != L'\\'
@@ -556,8 +556,8 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
arg_count++;
}
- /* Adjust for potential quotes. Also assume the worst-case scenario */
- /* that every character needs escaping, so we need twice as much space. */
+ /* Adjust for potential quotes. Also assume the worst-case scenario that
+ * every character needs escaping, so we need twice as much space. */
dst_len = dst_len * 2 + arg_count * 2;
/* Allocate buffer for the final command line. */
@@ -739,7 +739,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
}
}
*ptr_copy = NULL;
- assert(env_len == ptr - dst_copy);
+ assert(env_len == (size_t) (ptr - dst_copy));
/* sort our (UTF-16) copy */
qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp);
@@ -799,7 +799,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
var_size = GetEnvironmentVariableW(required_vars[i].wide,
ptr,
(int) (env_len - (ptr - dst)));
- if (var_size != len-1) { /* race condition? */
+ if (var_size != (DWORD) (len - 1)) { /* TODO: handle race condition? */
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
}
}
@@ -815,7 +815,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
}
/* Terminate with an extra NULL. */
- assert(env_len == (ptr - dst));
+ assert(env_len == (size_t) (ptr - dst));
*ptr = L'\0';
uv__free(dst_copy);
@@ -831,8 +831,13 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
*/
static WCHAR* find_path(WCHAR *env) {
for (; env != NULL && *env != 0; env += wcslen(env) + 1) {
- if (wcsncmp(env, L"PATH=", 5) == 0)
+ if ((env[0] == L'P' || env[0] == L'p') &&
+ (env[1] == L'A' || env[1] == L'a') &&
+ (env[2] == L'T' || env[2] == L't') &&
+ (env[3] == L'H' || env[3] == L'h') &&
+ (env[4] == L'=')) {
return &env[5];
+ }
}
return NULL;
@@ -865,9 +870,9 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
assert(handle->exit_cb_pending);
handle->exit_cb_pending = 0;
- /* If we're closing, don't call the exit callback. Just schedule a close */
- /* callback now. */
- if (handle->flags & UV__HANDLE_CLOSING) {
+ /* If we're closing, don't call the exit callback. Just schedule a close
+ * callback now. */
+ if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return;
}
@@ -878,14 +883,14 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
handle->wait_handle = INVALID_HANDLE_VALUE;
}
- /* Set the handle to inactive: no callbacks will be made after the exit */
- /* callback.*/
+ /* Set the handle to inactive: no callbacks will be made after the exit
+ * callback. */
uv__handle_stop(handle);
if (GetExitCodeProcess(handle->process_handle, &status)) {
exit_code = status;
} else {
- /* Unable to to obtain the exit code. This should never happen. */
+ /* Unable to obtain the exit code. This should never happen. */
exit_code = uv_translate_sys_error(GetLastError());
}
@@ -900,8 +905,8 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
uv__handle_closing(handle);
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
- /* This blocks until either the wait was cancelled, or the callback has */
- /* completed. */
+ /* This blocks until either the wait was cancelled, or the callback has
+ * completed. */
BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
if (!r) {
/* This should never happen, and if it happens, we can't recover... */
@@ -919,7 +924,7 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
assert(!handle->exit_cb_pending);
- assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(handle->flags & UV_HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
/* Clean-up the process handle. */
@@ -965,6 +970,8 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_SETGID |
UV_PROCESS_SETUID |
UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_HIDE_CONSOLE |
+ UV_PROCESS_WINDOWS_HIDE_GUI |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
err = uv_utf8_to_utf16_alloc(options->file, &application);
@@ -1066,7 +1073,8 @@ int uv_spawn(uv_loop_t* loop,
process_flags = CREATE_UNICODE_ENVIRONMENT;
- if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
+ if ((options->flags & UV_PROCESS_WINDOWS_HIDE_CONSOLE) ||
+ (options->flags & UV_PROCESS_WINDOWS_HIDE)) {
/* Avoid creating console window if stdio is not inherited. */
for (i = 0; i < options->stdio_count; i++) {
if (options->stdio[i].flags & UV_INHERIT_FD)
@@ -1074,7 +1082,9 @@ int uv_spawn(uv_loop_t* loop,
if (i == options->stdio_count - 1)
process_flags |= CREATE_NO_WINDOW;
}
-
+ }
+ if ((options->flags & UV_PROCESS_WINDOWS_HIDE_GUI) ||
+ (options->flags & UV_PROCESS_WINDOWS_HIDE)) {
/* Use SW_HIDE to avoid any potential process window. */
startup.wShowWindow = SW_HIDE;
} else {
@@ -1160,14 +1170,13 @@ int uv_spawn(uv_loop_t* loop,
}
}
- /* Spawn succeeded */
- /* Beyond this point, failure is reported asynchronously. */
+ /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
process->process_handle = info.hProcess;
process->pid = info.dwProcessId;
- /* If the process isn't spawned as detached, assign to the global job */
- /* object so windows will kill it when the parent process dies. */
+ /* If the process isn't spawned as detached, assign to the global job object
+ * so windows will kill it when the parent process dies. */
if (!(options->flags & UV_PROCESS_DETACHED)) {
uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
@@ -1194,7 +1203,8 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE &&
((uv_pipe_t*) fdopt->data.stream)->ipc) {
- ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
+ ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_remote_pid =
+ info.dwProcessId;
}
}
@@ -1210,8 +1220,8 @@ int uv_spawn(uv_loop_t* loop,
assert(!err);
- /* Make the handle active. It will remain active until the exit callback */
- /* is made or the handle is closed, whichever happens first. */
+ /* Make the handle active. It will remain active until the exit callback is
+ * made or the handle is closed, whichever happens first. */
uv__handle_start(process);
/* Cleanup, whether we succeeded or failed. */
@@ -1242,16 +1252,16 @@ static int uv__kill(HANDLE process_handle, int signum) {
case SIGTERM:
case SIGKILL:
case SIGINT: {
- /* Unconditionally terminate the process. On Windows, killed processes */
- /* normally return 1. */
+ /* Unconditionally terminate the process. On Windows, killed processes
+ * normally return 1. */
DWORD status;
int err;
if (TerminateProcess(process_handle, 1))
return 0;
- /* If the process already exited before TerminateProcess was called, */
- /* TerminateProcess will fail with ERROR_ACCESS_DENIED. */
+ /* If the process already exited before TerminateProcess was called,.
+ * TerminateProcess will fail with ERROR_ACCESS_DENIED. */
err = GetLastError();
if (err == ERROR_ACCESS_DENIED &&
GetExitCodeProcess(process_handle, &status) &&
diff --git a/Utilities/cmlibuv/src/win/req.c b/Utilities/cmlibuv/src/win/req.c
deleted file mode 100644
index 111cc5e..0000000
--- a/Utilities/cmlibuv/src/win/req.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright Joyent, Inc. and other Node 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 <assert.h>
-
-#include "uv.h"
-#include "internal.h"
diff --git a/Utilities/cmlibuv/src/win/signal.c b/Utilities/cmlibuv/src/win/signal.c
index a174da1..276dc60 100644
--- a/Utilities/cmlibuv/src/win/signal.c
+++ b/Utilities/cmlibuv/src/win/signal.c
@@ -47,13 +47,13 @@ void uv_signals_init(void) {
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
- /* Compare signums first so all watchers with the same signnum end up */
- /* adjacent. */
+ /* 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;
- /* Sort by loop pointer, so we can easily look up the first item after */
- /* { .signum = x, .loop = NULL } */
+ /* Sort by loop pointer, so we can easily look up the first item after
+ * { .signum = x, .loop = NULL }. */
if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
@@ -90,7 +90,7 @@ int uv__signal_dispatch(int signum) {
unsigned long previous = InterlockedExchange(
(volatile LONG*) &handle->pending_signum, signum);
- if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED)
+ if (handle->flags & UV_SIGNAL_ONE_SHOT_DISPATCHED)
continue;
if (!previous) {
@@ -98,8 +98,8 @@ int uv__signal_dispatch(int signum) {
}
dispatched = 1;
- if (handle->flags & UV__SIGNAL_ONE_SHOT)
- handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED;
+ if (handle->flags & UV_SIGNAL_ONE_SHOT)
+ handle->flags |= UV_SIGNAL_ONE_SHOT_DISPATCHED;
}
LeaveCriticalSection(&uv__signal_lock);
@@ -118,10 +118,10 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_CLOSE_EVENT:
if (uv__signal_dispatch(SIGHUP)) {
- /* Windows will terminate the process after the control handler */
- /* returns. After that it will just terminate our process. Therefore */
- /* block the signal handler so the main loop has some time to pick */
- /* up the signal and do something for a few seconds. */
+ /* Windows will terminate the process after the control handler
+ * returns. After that it will just terminate our process. Therefore
+ * block the signal handler so the main loop has some time to pick up
+ * the signal and do something for a few seconds. */
Sleep(INFINITE);
return TRUE;
}
@@ -129,8 +129,8 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
- /* These signals are only sent to services. Services have their own */
- /* notification mechanism, so there's no point in handling these. */
+ /* These signals are only sent to services. Services have their own
+ * notification mechanism, so there's no point in handling these. */
default:
/* We don't handle these. */
@@ -190,13 +190,13 @@ int uv__signal_start(uv_signal_t* handle,
int signum,
int oneshot) {
/* Test for invalid signal values. */
- if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
+ if (signum <= 0 || signum >= NSIG)
return UV_EINVAL;
- /* Short circuit: if the signal watcher is already watching {signum} don't */
- /* go through the process of deregistering and registering the handler. */
- /* Additionally, this avoids pending signals getting lost in the (small) */
- /* time frame that handle->signum == 0. */
+ /* Short circuit: if the signal watcher is already watching {signum} don't go
+ * through the process of deregistering and registering the handler.
+ * Additionally, this avoids pending signals getting lost in the (small) time
+ * frame that handle->signum == 0. */
if (signum == handle->signum) {
handle->signal_cb = signal_cb;
return 0;
@@ -213,7 +213,7 @@ int uv__signal_start(uv_signal_t* handle,
handle->signum = signum;
if (oneshot)
- handle->flags |= UV__SIGNAL_ONE_SHOT;
+ handle->flags |= UV_SIGNAL_ONE_SHOT;
RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
@@ -237,16 +237,16 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
(volatile LONG*) &handle->pending_signum, 0);
assert(dispatched_signum != 0);
- /* Check if the pending signal equals the signum that we are watching for. */
- /* These can get out of sync when the handler is stopped and restarted */
- /* while the signal_req is pending. */
+ /* Check if the pending signal equals the signum that we are watching for.
+ * These can get out of sync when the handler is stopped and restarted while
+ * the signal_req is pending. */
if (dispatched_signum == handle->signum)
handle->signal_cb(handle, dispatched_signum);
- if (handle->flags & UV__SIGNAL_ONE_SHOT)
+ if (handle->flags & UV_SIGNAL_ONE_SHOT)
uv_signal_stop(handle);
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
/* When it is closing, it must be stopped at this point. */
assert(handle->signum == 0);
uv_want_endgame(loop, (uv_handle_t*) handle);
@@ -265,7 +265,7 @@ void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) {
- assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(handle->flags & UV_HANDLE_CLOSING);
assert(!(handle->flags & UV_HANDLE_CLOSED));
assert(handle->signum == 0);
diff --git a/Utilities/cmlibuv/src/win/stream.c b/Utilities/cmlibuv/src/win/stream.c
index 13cbfdc..7656627 100644
--- a/Utilities/cmlibuv/src/win/stream.c
+++ b/Utilities/cmlibuv/src/win/stream.c
@@ -105,12 +105,10 @@ int uv_read_stop(uv_stream_t* handle) {
err = 0;
if (handle->type == UV_TTY) {
err = uv_tty_read_stop((uv_tty_t*) handle);
+ } else if (handle->type == UV_NAMED_PIPE) {
+ uv__pipe_read_stop((uv_pipe_t*) handle);
} else {
- if (handle->type == UV_NAMED_PIPE) {
- uv__pipe_stop_read((uv_pipe_t*) handle);
- } else {
- handle->flags &= ~UV_HANDLE_READING;
- }
+ handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(handle->loop, handle);
}
@@ -136,7 +134,8 @@ int uv_write(uv_write_t* req,
err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
break;
case UV_NAMED_PIPE:
- err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb);
+ err = uv__pipe_write(
+ loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb);
break;
case UV_TTY:
err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
@@ -158,25 +157,18 @@ int uv_write2(uv_write_t* req,
uv_loop_t* loop = handle->loop;
int err;
- if (!(handle->flags & UV_HANDLE_WRITABLE)) {
- return UV_EPIPE;
+ if (send_handle == NULL) {
+ return uv_write(req, handle, bufs, nbufs, cb);
}
- err = ERROR_INVALID_PARAMETER;
- switch (handle->type) {
- case UV_NAMED_PIPE:
- err = uv_pipe_write2(loop,
- req,
- (uv_pipe_t*) handle,
- bufs,
- nbufs,
- send_handle,
- cb);
- break;
- default:
- assert(0);
+ if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
+ return UV_EINVAL;
+ } else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ return UV_EPIPE;
}
+ err = uv__pipe_write(
+ loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb);
return uv_translate_sys_error(err);
}
@@ -184,7 +176,7 @@ int uv_write2(uv_write_t* req,
int uv_try_write(uv_stream_t* stream,
const uv_buf_t bufs[],
unsigned int nbufs) {
- if (stream->flags & UV__HANDLE_CLOSING)
+ if (stream->flags & UV_HANDLE_CLOSING)
return UV_EBADF;
if (!(stream->flags & UV_HANDLE_WRITABLE))
return UV_EPIPE;
diff --git a/Utilities/cmlibuv/src/win/tcp.c b/Utilities/cmlibuv/src/win/tcp.c
index 39c1ff0..3ce5548 100644
--- a/Utilities/cmlibuv/src/win/tcp.c
+++ b/Utilities/cmlibuv/src/win/tcp.c
@@ -99,8 +99,8 @@ static int uv_tcp_set_socket(uv_loop_t* loop,
if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0))
return GetLastError();
- /* Associate it with the I/O completion port. */
- /* Use uv_handle_t pointer as completion key. */
+ /* Associate it with the I/O completion port. Use uv_handle_t pointer as
+ * completion key. */
if (CreateIoCompletionPort((HANDLE)socket,
loop->iocp,
(ULONG_PTR)socket,
@@ -118,15 +118,12 @@ static int uv_tcp_set_socket(uv_loop_t* loop,
non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
}
- if (pSetFileCompletionNotificationModes &&
- !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) {
- if (pSetFileCompletionNotificationModes((HANDLE) socket,
- FILE_SKIP_SET_EVENT_ON_HANDLE |
- FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
- handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
- } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+ if (!(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) {
+ UCHAR sfcnm_flags =
+ FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
+ if (!SetFileCompletionNotificationModes((HANDLE) socket, sfcnm_flags))
return GetLastError();
- }
+ handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
}
if (handle->flags & UV_HANDLE_TCP_NODELAY) {
@@ -220,7 +217,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
err = 0;
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
err = ERROR_OPERATION_ABORTED;
} else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) {
err = WSAGetLastError();
@@ -236,7 +233,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
return;
}
- if (handle->flags & UV__HANDLE_CLOSING &&
+ if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
@@ -326,9 +323,9 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
on = (flags & UV_TCP_IPV6ONLY) != 0;
- /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
- /* available, or when run on XP/2003 which have no support for dualstack */
- /* sockets. For now we're silently ignoring the error. */
+ /* TODO: how to handle errors? This may fail if there is no ipv4 stack
+ * available, or when run on XP/2003 which have no support for dualstack
+ * sockets. For now we're silently ignoring the error. */
setsockopt(handle->socket,
IPPROTO_IPV6,
IPV6_V6ONLY,
@@ -626,9 +623,9 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
uv_tcp_queue_accept(handle, req);
}
- /* Initialize other unused requests too, because uv_tcp_endgame */
- /* doesn't know how how many requests were initialized, so it will */
- /* try to clean up {uv_simultaneous_server_accepts} requests. */
+ /* Initialize other unused requests too, because uv_tcp_endgame doesn't
+ * know how many requests were initialized, so it will 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(req, UV_ACCEPT);
@@ -683,7 +680,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
req->next_pending = NULL;
req->accept_socket = INVALID_SOCKET;
- if (!(server->flags & UV__HANDLE_CLOSING)) {
+ if (!(server->flags & UV_HANDLE_CLOSING)) {
/* Check if we're in a middle of changing the number of pending accepts. */
if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
uv_tcp_queue_accept(server, req);
@@ -721,8 +718,8 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
handle->alloc_cb = alloc_cb;
INCREASE_ACTIVE_COUNT(loop, handle);
- /* If reading was stopped and then started again, there could still be a */
- /* read request pending. */
+ /* If reading was stopped and then started again, there could still be a read
+ * request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
!handle->read_req.event_handle) {
@@ -948,6 +945,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req) {
DWORD bytes, flags, err;
uv_buf_t buf;
+ int count;
assert(handle->type == UV_TCP);
@@ -965,8 +963,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
err = GET_REQ_SOCK_ERROR(req);
if (err == WSAECONNABORTED) {
- /*
- * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
+ /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
*/
err = WSAECONNRESET;
}
@@ -1003,7 +1000,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
}
/* Do nonblocking reads until the buffer is empty */
- while (handle->flags & UV_HANDLE_READING) {
+ count = 32;
+ while ((handle->flags & UV_HANDLE_READING) && (count-- > 0)) {
buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
if (buf.base == NULL || buf.len == 0) {
@@ -1046,8 +1044,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
DECREASE_ACTIVE_COUNT(loop, handle);
if (err == WSAECONNABORTED) {
- /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */
- /* Unix. */
+ /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with
+ * Unix. */
err = WSAECONNRESET;
}
@@ -1119,10 +1117,9 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
assert(handle->type == UV_TCP);
- /* If handle->accepted_socket is not a valid socket, then */
- /* uv_queue_accept must have failed. This is a serious error. We stop */
- /* accepting connections and report this error to the connection */
- /* callback. */
+ /* If handle->accepted_socket is not a valid socket, then uv_queue_accept
+ * must have failed. This is a serious error. We stop accepting connections
+ * and report this error to the connection callback. */
if (req->accept_socket == INVALID_SOCKET) {
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING;
@@ -1147,9 +1144,9 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
}
} else {
- /* Error related to accepted socket is ignored because the server */
- /* socket may still be healthy. If the server socket is broken */
- /* uv_queue_accept will detect it. */
+ /* Error related to accepted socket is ignored because the server socket
+ * may still be healthy. If the server socket is broken uv_queue_accept
+ * will detect it. */
closesocket(req->accept_socket);
req->accept_socket = INVALID_SOCKET;
if (handle->flags & UV_HANDLE_LISTENING) {
@@ -1171,7 +1168,7 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
err = 0;
if (REQ_SUCCESS(req)) {
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
/* use UV_ECANCELED for consistency with Unix */
err = ERROR_OPERATION_ABORTED;
} else if (setsockopt(handle->socket,
@@ -1194,40 +1191,76 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
}
-int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
- int tcp_connection) {
+int uv__tcp_xfer_export(uv_tcp_t* handle,
+ int target_pid,
+ uv__ipc_socket_xfer_type_t* xfer_type,
+ uv__ipc_socket_xfer_info_t* xfer_info) {
+ if (handle->flags & UV_HANDLE_CONNECTION) {
+ *xfer_type = UV__IPC_SOCKET_XFER_TCP_CONNECTION;
+ } else {
+ *xfer_type = UV__IPC_SOCKET_XFER_TCP_SERVER;
+ /* We're about to share the socket with another process. Because this is a
+ * listening socket, we assume that the other process will be accepting
+ * connections on it. Thus, before sharing the socket with another process,
+ * we call listen here in the parent process. */
+ if (!(handle->flags & UV_HANDLE_LISTENING)) {
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return ERROR_NOT_SUPPORTED;
+ }
+ if (handle->delayed_error == 0 &&
+ listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
+ handle->delayed_error = WSAGetLastError();
+ }
+ }
+ }
+
+ if (WSADuplicateSocketW(handle->socket, target_pid, &xfer_info->socket_info))
+ return WSAGetLastError();
+ xfer_info->delayed_error = handle->delayed_error;
+
+ /* Mark the local copy of the handle as 'shared' so we behave in a way that's
+ * friendly to the process(es) that we share the socket with. */
+ handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
+
+ return 0;
+}
+
+
+int uv__tcp_xfer_import(uv_tcp_t* tcp,
+ uv__ipc_socket_xfer_type_t xfer_type,
+ uv__ipc_socket_xfer_info_t* xfer_info) {
int err;
- SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO,
- FROM_PROTOCOL_INFO,
- FROM_PROTOCOL_INFO,
- &socket_info_ex->socket_info,
- 0,
- WSA_FLAG_OVERLAPPED);
+ SOCKET socket;
+
+ assert(xfer_type == UV__IPC_SOCKET_XFER_TCP_SERVER ||
+ xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION);
+
+ socket = WSASocketW(FROM_PROTOCOL_INFO,
+ FROM_PROTOCOL_INFO,
+ FROM_PROTOCOL_INFO,
+ &xfer_info->socket_info,
+ 0,
+ WSA_FLAG_OVERLAPPED);
if (socket == INVALID_SOCKET) {
return WSAGetLastError();
}
- err = uv_tcp_set_socket(tcp->loop,
- tcp,
- socket,
- socket_info_ex->socket_info.iAddressFamily,
- 1);
+ err = uv_tcp_set_socket(
+ tcp->loop, tcp, socket, xfer_info->socket_info.iAddressFamily, 1);
if (err) {
closesocket(socket);
return err;
}
- if (tcp_connection) {
+ tcp->delayed_error = xfer_info->delayed_error;
+ tcp->flags |= UV_HANDLE_BOUND | UV_HANDLE_SHARED_TCP_SOCKET;
+
+ if (xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION) {
uv_connection_init((uv_stream_t*)tcp);
tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
}
- tcp->flags |= UV_HANDLE_BOUND;
- tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
-
- tcp->delayed_error = socket_info_ex->delayed_error;
-
tcp->loop->active_tcp_streams++;
return 0;
}
@@ -1273,39 +1306,6 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
}
-int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
- LPWSAPROTOCOL_INFOW protocol_info) {
- if (!(handle->flags & UV_HANDLE_CONNECTION)) {
- /*
- * We're about to share the socket with another process. Because
- * this is a listening socket, we assume that the other process will
- * be accepting connections on it. So, before sharing the socket
- * with another process, we call listen here in the parent process.
- */
-
- if (!(handle->flags & UV_HANDLE_LISTENING)) {
- if (!(handle->flags & UV_HANDLE_BOUND)) {
- return ERROR_INVALID_PARAMETER;
- }
-
- if (!(handle->delayed_error)) {
- if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
- handle->delayed_error = WSAGetLastError();
- }
- }
- }
- }
-
- if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) {
- return WSAGetLastError();
- }
-
- handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
-
- return 0;
-}
-
-
int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
if (handle->flags & UV_HANDLE_CONNECTION) {
return UV_EINVAL;
@@ -1346,8 +1346,8 @@ static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
uv_tcp_non_ifs_lsp_ipv4;
- /* If there are non-ifs LSPs then try to obtain a base handle for the */
- /* socket. This will always fail on Windows XP/3k. */
+ /* If there are non-ifs LSPs then try to obtain a base handle for the socket.
+ * This will always fail on Windows XP/3k. */
if (non_ifs_lsp) {
DWORD bytes;
if (WSAIoctl(socket,
@@ -1379,38 +1379,37 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
int close_socket = 1;
if (tcp->flags & UV_HANDLE_READ_PENDING) {
- /* In order for winsock to do a graceful close there must not be any */
- /* any pending reads, or the socket must be shut down for writing */
+ /* In order for winsock to do a graceful close there must not be any any
+ * pending reads, or the socket must be shut down for writing */
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
shutdown(tcp->socket, SD_SEND);
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
- /* In case of a shared socket, we try to cancel all outstanding I/O, */
- /* If that works, don't close the socket yet - wait for the read req to */
- /* return and close the socket in uv_tcp_endgame. */
+ /* In case of a shared socket, we try to cancel all outstanding I/O,. If
+ * that works, don't close the socket yet - wait for the read req to
+ * return and close the socket in uv_tcp_endgame. */
close_socket = 0;
} else {
- /* When cancelling isn't possible - which could happen when an LSP is */
- /* present on an old Windows version, we will have to close the socket */
- /* with a read pending. That is not nice because trailing sent bytes */
- /* may not make it to the other side. */
+ /* When cancelling isn't possible - which could happen when an LSP is
+ * present on an old Windows version, we will have to close the socket
+ * with a read pending. That is not nice because trailing sent bytes may
+ * not make it to the other side. */
}
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
tcp->tcp.serv.accept_reqs != NULL) {
- /* Under normal circumstances closesocket() will ensure that all pending */
- /* accept reqs are canceled. However, when the socket is shared the */
- /* presence of another reference to the socket in another process will */
- /* keep the accept reqs going, so we have to ensure that these are */
- /* canceled. */
+ /* Under normal circumstances closesocket() will ensure that all pending
+ * accept reqs are canceled. However, when the socket is shared the
+ * presence of another reference to the socket in another process will keep
+ * the accept reqs going, so we have to ensure that these are canceled. */
if (uv_tcp_try_cancel_io(tcp) != 0) {
- /* When cancellation is not possible, there is another option: we can */
- /* close the incoming sockets, which will also cancel the accept */
- /* operations. However this is not cool because we might inadvertently */
- /* close a socket that just accepted a new connection, which will */
- /* cause the connection to be aborted. */
+ /* When cancellation is not possible, there is another option: we can
+ * close the incoming sockets, which will also cancel the accept
+ * operations. However this is not cool because we might inadvertently
+ * close a socket that just accepted a new connection, which will cause
+ * the connection to be aborted. */
unsigned int i;
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
diff --git a/Utilities/cmlibuv/src/win/thread.c b/Utilities/cmlibuv/src/win/thread.c
index 9eaad77..fd4b7c9 100644
--- a/Utilities/cmlibuv/src/win/thread.c
+++ b/Utilities/cmlibuv/src/win/thread.c
@@ -23,29 +23,15 @@
#include <limits.h>
#include <stdlib.h>
+#if defined(__MINGW64_VERSION_MAJOR)
+/* MemoryBarrier expands to __mm_mfence in some cases (x86+sse2), which may
+ * require this header in some versions of mingw64. */
+#include <intrin.h>
+#endif
+
#include "uv.h"
#include "internal.h"
-
-#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
-
-static int uv_cond_fallback_init(uv_cond_t* cond);
-static void uv_cond_fallback_destroy(uv_cond_t* cond);
-static void uv_cond_fallback_signal(uv_cond_t* cond);
-static void uv_cond_fallback_broadcast(uv_cond_t* cond);
-static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
-static int uv_cond_fallback_timedwait(uv_cond_t* cond,
- uv_mutex_t* mutex, uint64_t timeout);
-
-static int uv_cond_condvar_init(uv_cond_t* cond);
-static void uv_cond_condvar_destroy(uv_cond_t* cond);
-static void uv_cond_condvar_signal(uv_cond_t* cond);
-static void uv_cond_condvar_broadcast(uv_cond_t* cond);
-static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex);
-static int uv_cond_condvar_timedwait(uv_cond_t* cond,
- uv_mutex_t* mutex, uint64_t timeout);
-
-
static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
DWORD result;
HANDLE existing_event, created_event;
@@ -69,8 +55,8 @@ static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
guard->ran = 1;
} else {
- /* We lost the race. Destroy the event we created and wait for the */
- /* existing one to become signaled. */
+ /* We lost the race. Destroy the event we created and wait for the existing
+ * one to become signaled. */
CloseHandle(created_event);
result = WaitForSingleObject(existing_event, INFINITE);
assert(result == WAIT_OBJECT_0);
@@ -138,7 +124,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
ctx->arg = arg;
/* Create the thread in suspended state so we have a chance to pass
- * its own creation handle to it */
+ * its own creation handle to it */
thread = (HANDLE) _beginthreadex(NULL,
0,
uv__thread_start,
@@ -377,220 +363,35 @@ int uv_sem_trywait(uv_sem_t* sem) {
}
-/* This condition variable implementation is based on the SetEvent solution
- * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
- * We could not use the SignalObjectAndWait solution (section 3.4) because
- * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
- * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
- */
-
-static int uv_cond_fallback_init(uv_cond_t* cond) {
- int err;
-
- /* Initialize the count to 0. */
- cond->fallback.waiters_count = 0;
-
- InitializeCriticalSection(&cond->fallback.waiters_count_lock);
-
- /* Create an auto-reset event. */
- cond->fallback.signal_event = CreateEvent(NULL, /* no security */
- FALSE, /* auto-reset event */
- FALSE, /* non-signaled initially */
- NULL); /* unnamed */
- if (!cond->fallback.signal_event) {
- err = GetLastError();
- goto error2;
- }
-
- /* Create a manual-reset event. */
- cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */
- TRUE, /* manual-reset */
- FALSE, /* non-signaled */
- NULL); /* unnamed */
- if (!cond->fallback.broadcast_event) {
- err = GetLastError();
- goto error;
- }
-
- return 0;
-
-error:
- CloseHandle(cond->fallback.signal_event);
-error2:
- DeleteCriticalSection(&cond->fallback.waiters_count_lock);
- return uv_translate_sys_error(err);
-}
-
-
-static int uv_cond_condvar_init(uv_cond_t* cond) {
- pInitializeConditionVariable(&cond->cond_var);
- return 0;
-}
-
-
int uv_cond_init(uv_cond_t* cond) {
- uv__once_init();
-
- if (HAVE_CONDVAR_API())
- return uv_cond_condvar_init(cond);
- else
- return uv_cond_fallback_init(cond);
-}
-
-
-static void uv_cond_fallback_destroy(uv_cond_t* cond) {
- if (!CloseHandle(cond->fallback.broadcast_event))
- abort();
- if (!CloseHandle(cond->fallback.signal_event))
- abort();
- DeleteCriticalSection(&cond->fallback.waiters_count_lock);
-}
-
-
-static void uv_cond_condvar_destroy(uv_cond_t* cond) {
- /* nothing to do */
+ InitializeConditionVariable(&cond->cond_var);
+ return 0;
}
void uv_cond_destroy(uv_cond_t* cond) {
- if (HAVE_CONDVAR_API())
- uv_cond_condvar_destroy(cond);
- else
- uv_cond_fallback_destroy(cond);
-}
-
-
-static void uv_cond_fallback_signal(uv_cond_t* cond) {
- int have_waiters;
-
- /* Avoid race conditions. */
- EnterCriticalSection(&cond->fallback.waiters_count_lock);
- have_waiters = cond->fallback.waiters_count > 0;
- LeaveCriticalSection(&cond->fallback.waiters_count_lock);
-
- if (have_waiters)
- SetEvent(cond->fallback.signal_event);
-}
-
-
-static void uv_cond_condvar_signal(uv_cond_t* cond) {
- pWakeConditionVariable(&cond->cond_var);
+ /* nothing to do */
+ (void) &cond;
}
void uv_cond_signal(uv_cond_t* cond) {
- if (HAVE_CONDVAR_API())
- uv_cond_condvar_signal(cond);
- else
- uv_cond_fallback_signal(cond);
-}
-
-
-static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
- int have_waiters;
-
- /* Avoid race conditions. */
- EnterCriticalSection(&cond->fallback.waiters_count_lock);
- have_waiters = cond->fallback.waiters_count > 0;
- LeaveCriticalSection(&cond->fallback.waiters_count_lock);
-
- if (have_waiters)
- SetEvent(cond->fallback.broadcast_event);
-}
-
-
-static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
- pWakeAllConditionVariable(&cond->cond_var);
+ WakeConditionVariable(&cond->cond_var);
}
void uv_cond_broadcast(uv_cond_t* cond) {
- if (HAVE_CONDVAR_API())
- uv_cond_condvar_broadcast(cond);
- else
- uv_cond_fallback_broadcast(cond);
-}
-
-
-static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
- DWORD dwMilliseconds) {
- DWORD result;
- int last_waiter;
- HANDLE handles[2] = {
- cond->fallback.signal_event,
- cond->fallback.broadcast_event
- };
-
- /* Avoid race conditions. */
- EnterCriticalSection(&cond->fallback.waiters_count_lock);
- cond->fallback.waiters_count++;
- LeaveCriticalSection(&cond->fallback.waiters_count_lock);
-
- /* It's ok to release the <mutex> here since Win32 manual-reset events */
- /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */
- /* bug. */
- uv_mutex_unlock(mutex);
-
- /* Wait for either event to become signaled due to <uv_cond_signal> being */
- /* called or <uv_cond_broadcast> being called. */
- result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
-
- EnterCriticalSection(&cond->fallback.waiters_count_lock);
- cond->fallback.waiters_count--;
- last_waiter = result == WAIT_OBJECT_0 + 1
- && cond->fallback.waiters_count == 0;
- LeaveCriticalSection(&cond->fallback.waiters_count_lock);
-
- /* Some thread called <pthread_cond_broadcast>. */
- if (last_waiter) {
- /* We're the last waiter to be notified or to stop waiting, so reset the */
- /* the manual-reset event. */
- ResetEvent(cond->fallback.broadcast_event);
- }
-
- /* Reacquire the <mutex>. */
- uv_mutex_lock(mutex);
-
- if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1)
- return 0;
-
- if (result == WAIT_TIMEOUT)
- return UV_ETIMEDOUT;
-
- abort();
- return -1; /* Satisfy the compiler. */
-}
-
-
-static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
- if (uv_cond_wait_helper(cond, mutex, INFINITE))
- abort();
-}
-
-
-static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
- if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
- abort();
+ WakeAllConditionVariable(&cond->cond_var);
}
void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
- if (HAVE_CONDVAR_API())
- uv_cond_condvar_wait(cond, mutex);
- else
- uv_cond_fallback_wait(cond, mutex);
-}
-
-
-static int uv_cond_fallback_timedwait(uv_cond_t* cond,
- uv_mutex_t* mutex, uint64_t timeout) {
- return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
+ if (!SleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
+ abort();
}
-
-static int uv_cond_condvar_timedwait(uv_cond_t* cond,
- uv_mutex_t* mutex, uint64_t timeout) {
- if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
+ if (SleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
return 0;
if (GetLastError() != ERROR_TIMEOUT)
abort();
@@ -598,15 +399,6 @@ static int uv_cond_condvar_timedwait(uv_cond_t* cond,
}
-int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
- uint64_t timeout) {
- if (HAVE_CONDVAR_API())
- return uv_cond_condvar_timedwait(cond, mutex, timeout);
- else
- return uv_cond_fallback_timedwait(cond, mutex, timeout);
-}
-
-
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
int err;
diff --git a/Utilities/cmlibuv/src/win/timer.c b/Utilities/cmlibuv/src/win/timer.c
deleted file mode 100644
index 7e006fe..0000000
--- a/Utilities/cmlibuv/src/win/timer.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* Copyright Joyent, Inc. and other Node 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 <assert.h>
-#include <limits.h>
-
-#include "uv.h"
-#include "internal.h"
-#include "tree.h"
-#include "handle-inl.h"
-
-
-/* The number of milliseconds in one second. */
-#define UV__MILLISEC 1000
-
-
-void uv_update_time(uv_loop_t* loop) {
- uint64_t new_time = uv__hrtime(UV__MILLISEC);
- assert(new_time >= loop->time);
- loop->time = new_time;
-}
-
-
-static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
- if (a->due < b->due)
- return -1;
- if (a->due > b->due)
- return 1;
- /*
- * compare start_id when both has the same due. start_id is
- * allocated with loop->timer_counter in uv_timer_start().
- */
- if (a->start_id < b->start_id)
- return -1;
- if (a->start_id > b->start_id)
- return 1;
- return 0;
-}
-
-
-RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare)
-
-
-int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
- uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER);
- handle->timer_cb = NULL;
- handle->repeat = 0;
-
- return 0;
-}
-
-
-void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
- if (handle->flags & UV__HANDLE_CLOSING) {
- assert(!(handle->flags & UV_HANDLE_CLOSED));
- uv__handle_close(handle);
- }
-}
-
-
-static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) {
- uint64_t clamped_timeout;
-
- clamped_timeout = loop_time + timeout;
- if (clamped_timeout < timeout)
- clamped_timeout = (uint64_t) -1;
-
- return clamped_timeout;
-}
-
-
-int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
- uint64_t repeat) {
- uv_loop_t* loop = handle->loop;
- uv_timer_t* old;
-
- if (timer_cb == NULL)
- return UV_EINVAL;
-
- if (uv__is_active(handle))
- uv_timer_stop(handle);
-
- handle->timer_cb = timer_cb;
- handle->due = get_clamped_due_time(loop->time, timeout);
- handle->repeat = repeat;
- uv__handle_start(handle);
-
- /* start_id is the second index to be compared in uv__timer_cmp() */
- handle->start_id = handle->loop->timer_counter++;
-
- old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle);
- assert(old == NULL);
-
- return 0;
-}
-
-
-int uv_timer_stop(uv_timer_t* handle) {
- uv_loop_t* loop = handle->loop;
-
- if (!uv__is_active(handle))
- return 0;
-
- RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
- uv__handle_stop(handle);
-
- return 0;
-}
-
-
-int uv_timer_again(uv_timer_t* handle) {
- /* If timer_cb is NULL that means that the timer was never started. */
- if (!handle->timer_cb) {
- return UV_EINVAL;
- }
-
- if (handle->repeat) {
- uv_timer_stop(handle);
- uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
- }
-
- return 0;
-}
-
-
-void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
- assert(handle->type == UV_TIMER);
- handle->repeat = repeat;
-}
-
-
-uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
- assert(handle->type == UV_TIMER);
- return handle->repeat;
-}
-
-
-DWORD uv__next_timeout(const uv_loop_t* loop) {
- uv_timer_t* timer;
- int64_t delta;
-
- /* Check if there are any running timers
- * Need to cast away const first, since RB_MIN doesn't know what we are
- * going to do with this return value, it can't be marked const
- */
- timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
- if (timer) {
- delta = timer->due - loop->time;
- if (delta >= UINT_MAX - 1) {
- /* A timeout value of UINT_MAX means infinite, so that's no good. */
- return UINT_MAX - 1;
- } else if (delta < 0) {
- /* Negative timeout values are not allowed */
- return 0;
- } else {
- return (DWORD)delta;
- }
- } else {
- /* No timers */
- return INFINITE;
- }
-}
-
-
-void uv_process_timers(uv_loop_t* loop) {
- uv_timer_t* timer;
-
- /* Call timer callbacks */
- for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
- timer != NULL && timer->due <= loop->time;
- timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
-
- uv_timer_stop(timer);
- uv_timer_again(timer);
- timer->timer_cb((uv_timer_t*) timer);
- }
-}
diff --git a/Utilities/cmlibuv/src/win/tty.c b/Utilities/cmlibuv/src/win/tty.c
index ecf7bc9..f38e9a8 100644
--- a/Utilities/cmlibuv/src/win/tty.c
+++ b/Utilities/cmlibuv/src/win/tty.c
@@ -25,7 +25,7 @@
#include <stdlib.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
-# include "stdint-msvc2008.h"
+# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
@@ -164,7 +164,7 @@ void uv_console_init(void) {
OPEN_EXISTING,
0,
0);
- if (uv__tty_console_handle != NULL) {
+ if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
NULL,
WT_EXECUTELONGFUNCTION);
@@ -172,9 +172,12 @@ void uv_console_init(void) {
}
-int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
+int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) {
+ BOOL readable;
+ DWORD NumberOfEvents;
HANDLE handle;
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+ (void)unused;
uv__once_init();
handle = (HANDLE) uv__get_osfhandle(fd);
@@ -199,14 +202,15 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
fd = -1;
}
+ readable = GetNumberOfConsoleInputEvents(handle, &NumberOfEvents);
if (!readable) {
/* Obtain the screen buffer info with the output handle. */
if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) {
return uv_translate_sys_error(GetLastError());
}
- /* Obtain the the tty_output_lock because the virtual window state is */
- /* shared between all uv_tty_t handles. */
+ /* Obtain the tty_output_lock because the virtual window state is shared
+ * between all uv_tty_t handles. */
uv_sem_wait(&uv_tty_output_lock);
if (uv__vterm_state == UV_UNCHECKED)
@@ -356,6 +360,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
}
} else {
was_reading = 0;
+ alloc_cb = NULL;
+ read_cb = NULL;
}
uv_sem_wait(&uv_tty_output_lock);
@@ -382,12 +388,6 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
}
-int uv_is_tty(uv_file file) {
- DWORD result;
- return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0;
-}
-
-
int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
CONSOLE_SCREEN_BUFFER_INFO info;
@@ -484,8 +484,8 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
bytes = MAX_INPUT_BUFFER_LENGTH;
}
- /* At last, unicode! */
- /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
+ /* At last, unicode! One utf-16 codeunit never takes more than 3 utf-8
+ * codeunits to encode. */
chars = bytes / 3;
status = InterlockedExchange(&uv__read_console_status, IN_PROGRESS);
@@ -620,10 +620,10 @@ static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl,
}
switch (code) {
- /* These mappings are the same as Cygwin's. Unmodified and alt-modified */
- /* keypad keys comply with linux console, modifiers comply with xterm */
- /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */
- /* f6..f12 with and without modifiers comply with rxvt. */
+ /* These mappings are the same as Cygwin's. Unmodified and alt-modified
+ * keypad keys comply with linux console, modifiers comply with xterm
+ * modifier usage. F1. f12 and shift-f1. f10 comply with linux console, f6.
+ * f12 with and without modifiers comply with rxvt. */
VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~")
VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~")
VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B")
@@ -706,8 +706,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
goto out;
}
- /* Windows sends a lot of events that we're not interested in, so buf */
- /* will be allocated on demand, when there's actually something to emit. */
+ /* Windows sends a lot of events that we're not interested in, so buf will be
+ * allocated on demand, when there's actually something to emit. */
buf = uv_null_buf_;
buf_used = 0;
@@ -733,16 +733,17 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
continue;
}
- /* Ignore keyup events, unless the left alt key was held and a valid */
- /* unicode character was emitted. */
- if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
- KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
+ /* Ignore keyup events, unless the left alt key was held and a valid
+ * unicode character was emitted. */
+ if (!KEV.bKeyDown &&
+ KEV.wVirtualKeyCode != VK_MENU &&
+ KEV.uChar.UnicodeChar != 0) {
continue;
}
- /* Ignore keypresses to numpad number keys if the left alt is held */
- /* because the user is composing a character, or windows simulating */
- /* this. */
+ /* Ignore keypresses to numpad number keys if the left alt is held
+ * because the user is composing a character, or windows simulating this.
+ */
if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
!(KEV.dwControlKeyState & ENHANCED_KEY) &&
(KEV.wVirtualKeyCode == VK_INSERT ||
@@ -779,8 +780,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
continue;
}
- /* Prefix with \u033 if alt was held, but alt was not used as part */
- /* a compose sequence. */
+ /* Prefix with \u033 if alt was held, but alt was not used as part a
+ * compose sequence. */
if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
&& !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
@@ -793,8 +794,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (KEV.uChar.UnicodeChar >= 0xDC00 &&
KEV.uChar.UnicodeChar < 0xE000) {
/* UTF-16 surrogate pair */
- WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate,
- KEV.uChar.UnicodeChar};
+ WCHAR utf16_buffer[2];
+ utf16_buffer[0] = handle->tty.rd.last_utf16_high_surrogate;
+ utf16_buffer[1] = KEV.uChar.UnicodeChar;
char_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
@@ -818,8 +820,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Whatever happened, the last character wasn't a high surrogate. */
handle->tty.rd.last_utf16_high_surrogate = 0;
- /* If the utf16 character(s) couldn't be converted something must */
- /* be wrong. */
+ /* If the utf16 character(s) couldn't be converted something must be
+ * wrong. */
if (!char_len) {
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
@@ -943,21 +945,15 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
handle->read_cb((uv_stream_t*) handle,
uv_translate_sys_error(GET_REQ_ERROR(req)),
&buf);
- } else {
- /* The read was cancelled, or whatever we don't care */
- handle->read_cb((uv_stream_t*) handle, 0, &buf);
}
-
} else {
- if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
- /* Read successful */
- /* TODO: read unicode, convert to utf-8 */
+ if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING) &&
+ req->u.io.overlapped.InternalHigh != 0) {
+ /* Read successful. TODO: read unicode, convert to utf-8 */
DWORD bytes = req->u.io.overlapped.InternalHigh;
handle->read_cb((uv_stream_t*) handle, bytes, &buf);
- } else {
- handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
- handle->read_cb((uv_stream_t*) handle, 0, &buf);
}
+ handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
}
/* Wait for more input events. */
@@ -975,9 +971,9 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
assert(handle->type == UV_TTY);
assert(handle->flags & UV_HANDLE_TTY_READABLE);
- /* If the read_line_buffer member is zero, it must have been an raw read. */
- /* Otherwise it was a line-buffered read. */
- /* FIXME: This is quite obscure. Use a flag or something. */
+ /* If the read_line_buffer member is zero, it must have been an raw read.
+ * Otherwise it was a line-buffered read. FIXME: This is quite obscure. Use a
+ * flag or something. */
if (handle->tty.rd.read_line_buffer.len == 0) {
uv_process_tty_read_raw_req(loop, handle, req);
} else {
@@ -999,14 +995,14 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
handle->read_cb = read_cb;
handle->alloc_cb = alloc_cb;
- /* If reading was stopped and then started again, there could still be a */
- /* read request pending. */
+ /* If reading was stopped and then started again, there could still be a read
+ * request pending. */
if (handle->flags & UV_HANDLE_READ_PENDING) {
return 0;
}
- /* Maybe the user stopped reading half-way while processing key events. */
- /* Short-circuit if this could be the case. */
+ /* Maybe the user stopped reading half-way while processing key events.
+ * Short-circuit if this could be the case. */
if (handle->tty.rd.last_key_len > 0) {
SET_REQ_SUCCESS(&handle->read_req);
uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
@@ -1033,9 +1029,10 @@ int uv_tty_read_stop(uv_tty_t* handle) {
return 0;
if (handle->flags & UV_HANDLE_TTY_RAW) {
- /* Cancel raw read */
- /* Write some bullshit event to force the console wait to return. */
+ /* Cancel raw read. Write some bullshit event to force the console wait to
+ * return. */
memset(&record, 0, sizeof record);
+ record.EventType = FOCUS_EVENT;
if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
return GetLastError();
}
@@ -1116,8 +1113,8 @@ static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
uv_tty_virtual_offset = info->dwCursorPosition.Y;
} else if (uv_tty_virtual_offset < info->dwCursorPosition.Y -
uv_tty_virtual_height + 1) {
- /* If suddenly find the cursor outside of the virtual window, it must */
- /* have somehow scrolled. Update the virtual window offset. */
+ /* If suddenly find the cursor outside of the virtual window, it must have
+ * somehow scrolled. Update the virtual window offset. */
uv_tty_virtual_offset = info->dwCursorPosition.Y -
uv_tty_virtual_height + 1;
}
@@ -1304,8 +1301,8 @@ static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
x2 = 0;
x2r = 1;
} else {
- /* Clear to end of row. We pretend the console is 65536 characters wide, */
- /* uv_tty_make_real_coord will clip it to the actual console width. */
+ /* Clear to end of row. We pretend the console is 65536 characters wide,
+ * uv_tty_make_real_coord will clip it to the actual console width. */
x2 = 0xffff;
x2r = 0;
}
@@ -1613,8 +1610,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs,
DWORD* error) {
- /* We can only write 8k characters at a time. Windows can't handle */
- /* much more characters in a single console write anyway. */
+ /* We can only write 8k characters at a time. Windows can't handle much more
+ * characters in a single console write anyway. */
WCHAR utf16_buf[MAX_CONSOLE_CHAR];
WCHAR* utf16_buffer;
DWORD utf16_buf_used = 0;
@@ -1650,9 +1647,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
unsigned char previous_eol = handle->tty.wr.previous_eol;
unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state;
- /* Store the error here. If we encounter an error, stop trying to do i/o */
- /* but keep parsing the buffer so we leave the parser in a consistent */
- /* state. */
+ /* Store the error here. If we encounter an error, stop trying to do i/o but
+ * keep parsing the buffer so we leave the parser in a consistent state. */
*error = ERROR_SUCCESS;
utf16_buffer = utf16_buf;
@@ -1700,9 +1696,9 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
for (j = 0; j < buf.len; j++) {
unsigned char c = buf.base[j];
- /* Run the character through the utf8 decoder We happily accept non */
- /* shortest form encodings and invalid code points - there's no real */
- /* harm that can be done. */
+ /* Run the character through the utf8 decoder We happily accept non
+ * shortest form encodings and invalid code points - there's no real harm
+ * that can be done. */
if (utf8_bytes_left == 0) {
/* Read utf-8 start byte */
DWORD first_zero_bit;
@@ -1742,8 +1738,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* Start byte where continuation was expected. */
utf8_bytes_left = 0;
utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
- /* Patch buf offset so this character will be parsed again as a */
- /* start byte. */
+ /* Patch buf offset so this character will be parsed again as a start
+ * byte. */
j--;
}
@@ -1776,8 +1772,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case '_':
case 'P':
case ']':
- /* Not supported, but we'll have to parse until we see a stop */
- /* code, e.g. ESC \ or BEL. */
+ /* Not supported, but we'll have to parse until we see a stop code,
+ * e. g. ESC \ or BEL. */
ansi_parser_state = ANSI_ST_CONTROL;
continue;
@@ -1859,8 +1855,9 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
continue;
} else {
- /* If ANSI_IN_ARG is not set, add another argument and */
- /* default it to 0. */
+ /* If ANSI_IN_ARG is not set, add another argument and default it
+ * to 0. */
+
/* Check for too many arguments */
if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE;
@@ -1874,9 +1871,9 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
} else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
handle->tty.wr.ansi_csi_argc == 0) {
- /* Ignores '?' if it is the first character after CSI[ */
- /* This is an extension character from the VT100 codeset */
- /* that is supported and used by most ANSI terminals today. */
+ /* Ignores '?' if it is the first character after CSI[. This is an
+ * extension character from the VT100 codeset that is supported and
+ * used by most ANSI terminals today. */
continue;
} else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
@@ -2006,8 +2003,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
continue;
} else {
- /* We don't support commands that use private mode characters or */
- /* intermediaries. Ignore the rest of the sequence. */
+ /* We don't support commands that use private mode characters or
+ * intermediaries. Ignore the rest of the sequence. */
ansi_parser_state |= ANSI_IGNORE;
continue;
}
@@ -2020,8 +2017,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
}
} else if (ansi_parser_state & ANSI_ST_CONTROL) {
- /* Unsupported control code */
- /* Ignore everything until we see BEL or ESC \ */
+ /* Unsupported control code.
+ * Ignore everything until we see `BEL` or `ESC \`. */
if (ansi_parser_state & ANSI_IN_STRING) {
if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) {
if (utf8_codepoint == '"') {
@@ -2055,9 +2052,9 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
abort();
}
- /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */
- /* windows console doesn't really support UTF-16, so just emit the */
- /* replacement character. */
+ /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the windows
+ * console doesn't really support UTF-16, so just emit the replacement
+ * character. */
if (utf8_codepoint > 0xffff) {
utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
}
@@ -2071,10 +2068,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
utf16_buf[utf16_buf_used++] = L'\r';
utf16_buf[utf16_buf_used++] = L'\n';
} else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) {
- /* \n was followed by \r; do not print the \r, since */
- /* the source was either \r\n\r (so the second \r is */
- /* redundant) or was \n\r (so the \n was processed */
- /* by the last case and an \r automatically inserted). */
+ /* \n was followed by \r; do not print the \r, since the source was
+ * either \r\n\r (so the second \r is redundant) or was \n\r (so the
+ * \n was processed by the last case and an \r automatically
+ * inserted). */
} else {
/* \r without \n; print \r as-is. */
ENSURE_BUFFER_SPACE(1);
@@ -2182,14 +2179,14 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
void uv_tty_close(uv_tty_t* handle) {
assert(handle->u.fd == -1 || handle->u.fd > 2);
+ if (handle->flags & UV_HANDLE_READING)
+ uv_tty_read_stop(handle);
+
if (handle->u.fd == -1)
CloseHandle(handle->handle);
else
close(handle->u.fd);
- if (handle->flags & UV_HANDLE_READING)
- uv_tty_read_stop(handle);
-
handle->u.fd = -1;
handle->handle = INVALID_HANDLE_VALUE;
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
@@ -2209,7 +2206,7 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
/* TTY shutdown is really just a no-op */
if (handle->stream.conn.shutdown_req->cb) {
- if (handle->flags & UV__HANDLE_CLOSING) {
+ if (handle->flags & UV_HANDLE_CLOSING) {
handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED);
} else {
handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0);
@@ -2222,10 +2219,10 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
return;
}
- if (handle->flags & UV__HANDLE_CLOSING &&
+ if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) {
- /* The wait handle used for raw reading should be unregistered when the */
- /* wait callback runs. */
+ /* The wait handle used for raw reading should be unregistered when the
+ * wait callback runs. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
handle->tty.rd.read_raw_wait == NULL);
diff --git a/Utilities/cmlibuv/src/win/udp.c b/Utilities/cmlibuv/src/win/udp.c
index cd1d0e0..37df849 100644
--- a/Utilities/cmlibuv/src/win/udp.c
+++ b/Utilities/cmlibuv/src/win/udp.c
@@ -74,8 +74,8 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
return GetLastError();
}
- /* Associate it with the I/O completion port. */
- /* Use uv_handle_t pointer as completion key. */
+ /* Associate it with the I/O completion port. Use uv_handle_t pointer as
+ * completion key. */
if (CreateIoCompletionPort((HANDLE)socket,
loop->iocp,
(ULONG_PTR)socket,
@@ -83,31 +83,28 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
return GetLastError();
}
- if (pSetFileCompletionNotificationModes) {
- /* All known Windows that support SetFileCompletionNotificationModes */
- /* have a bug that makes it impossible to use this function in */
- /* conjunction with datagram sockets. We can work around that but only */
- /* if the user is using the default UDP driver (AFD) and has no other */
- /* LSPs stacked on top. Here we check whether that is the case. */
- opt_len = (int) sizeof info;
- if (getsockopt(socket,
- SOL_SOCKET,
- SO_PROTOCOL_INFOW,
- (char*) &info,
- &opt_len) == SOCKET_ERROR) {
- return GetLastError();
- }
+ /* All known Windows that support SetFileCompletionNotificationModes have a
+ * bug that makes it impossible to use this function in conjunction with
+ * datagram sockets. We can work around that but only if the user is using
+ * the default UDP driver (AFD) and has no other. LSPs stacked on top. Here
+ * we check whether that is the case. */
+ opt_len = (int) sizeof info;
+ if (getsockopt(
+ socket, SOL_SOCKET, SO_PROTOCOL_INFOW, (char*) &info, &opt_len) ==
+ SOCKET_ERROR) {
+ return GetLastError();
+ }
- if (info.ProtocolChain.ChainLen == 1) {
- if (pSetFileCompletionNotificationModes((HANDLE)socket,
- FILE_SKIP_SET_EVENT_ON_HANDLE |
- FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
- handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
- handle->func_wsarecv = uv_wsarecv_workaround;
- handle->func_wsarecvfrom = uv_wsarecvfrom_workaround;
- } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
- return GetLastError();
- }
+ if (info.ProtocolChain.ChainLen == 1) {
+ if (SetFileCompletionNotificationModes(
+ (HANDLE) socket,
+ FILE_SKIP_SET_EVENT_ON_HANDLE |
+ FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
+ handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
+ handle->func_wsarecv = uv_wsarecv_workaround;
+ handle->func_wsarecvfrom = uv_wsarecvfrom_workaround;
+ } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+ return GetLastError();
}
}
@@ -191,7 +188,7 @@ void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
- if (handle->flags & UV__HANDLE_CLOSING &&
+ if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
uv__handle_close(handle);
@@ -245,12 +242,12 @@ static int uv_udp_maybe_bind(uv_udp_t* handle,
handle->flags |= UV_HANDLE_IPV6;
if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
- /* On windows IPV6ONLY is on by default. */
- /* If the user doesn't specify it libuv turns it off. */
+ /* On windows IPV6ONLY is on by default. If the user doesn't specify it
+ * libuv turns it off. */
- /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
- /* available, or when run on XP/2003 which have no support for dualstack */
- /* sockets. For now we're silently ignoring the error. */
+ /* TODO: how to handle errors? This may fail if there is no ipv4 stack
+ * available, or when run on XP/2003 which have no support for dualstack
+ * sockets. For now we're silently ignoring the error. */
setsockopt(handle->socket,
IPPROTO_IPV6,
IPV6_V6ONLY,
@@ -369,7 +366,7 @@ int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
int err;
if (handle->flags & UV_HANDLE_READING) {
- return WSAEALREADY;
+ return UV_EALREADY;
}
err = uv_udp_maybe_bind(handle,
@@ -377,7 +374,7 @@ int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
sizeof(uv_addr_ip4_any_),
0);
if (err)
- return err;
+ return uv_translate_sys_error(err);
handle->flags |= UV_HANDLE_READING;
INCREASE_ACTIVE_COUNT(loop, handle);
@@ -386,8 +383,8 @@ int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
handle->recv_cb = recv_cb;
handle->alloc_cb = alloc_cb;
- /* If reading was stopped and then started again, there could still be a */
- /* recv request pending. */
+ /* If reading was stopped and then started again, there could still be a recv
+ * request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_udp_queue_recv(loop, handle);
@@ -467,19 +464,19 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
if (!REQ_SUCCESS(req)) {
DWORD err = GET_REQ_SOCK_ERROR(req);
if (err == WSAEMSGSIZE) {
- /* Not a real error, it just indicates that the received packet */
- /* was bigger than the receive buffer. */
+ /* Not a real error, it just indicates that the received packet was
+ * bigger than the receive buffer. */
} else if (err == WSAECONNRESET || err == WSAENETRESET) {
- /* A previous sendto operation failed; ignore this error. If */
- /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */
- /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */
- /* immediately queue a new receive. */
+ /* A previous sendto operation failed; ignore this error. If zero-reading
+ * we need to call WSARecv/WSARecvFrom _without_ the. MSG_PEEK flag to
+ * clear out the error queue. For nonzero reads, immediately queue a new
+ * receive. */
if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
goto done;
}
} else {
- /* A real error occurred. Report the error to the user only if we're */
- /* currently reading. */
+ /* A real error occurred. Report the error to the user only if we're
+ * currently reading. */
if (handle->flags & UV_HANDLE_READING) {
uv_udp_recv_stop(handle);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
@@ -503,8 +500,8 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
struct sockaddr_storage from;
int from_len;
- /* Do a nonblocking receive */
- /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
+ /* Do a nonblocking receive.
+ * TODO: try to read multiple datagrams at once. FIONREAD maybe? */
buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
if (buf.base == NULL || buf.len == 0) {
@@ -741,7 +738,7 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
return UV_EINVAL;
}
- if (!(handle->flags & UV_HANDLE_BOUND))
+ if (handle->socket == INVALID_SOCKET)
return UV_EBADF;
if (addr_st.ss_family == AF_INET) {
@@ -772,7 +769,7 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
BOOL optval = (BOOL) value;
- if (!(handle->flags & UV_HANDLE_BOUND))
+ if (handle->socket == INVALID_SOCKET)
return UV_EBADF;
if (setsockopt(handle->socket,
@@ -818,7 +815,7 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
return UV_EINVAL; \
} \
\
- if (!(handle->flags & UV_HANDLE_BOUND)) \
+ if (handle->socket == INVALID_SOCKET) \
return UV_EBADF; \
\
if (!(handle->flags & UV_HANDLE_IPV6)) { \
diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c
index 49b5bc7..9237891 100644
--- a/Utilities/cmlibuv/src/win/util.c
+++ b/Utilities/cmlibuv/src/win/util.c
@@ -74,10 +74,6 @@
static char *process_title;
static CRITICAL_SECTION process_title_lock;
-/* Cached copy of the process id, written once. */
-static DWORD current_pid = 0;
-
-
/* Interval (in seconds) of the high-resolution clock. */
static double hrtime_interval_ = 0;
@@ -149,8 +145,8 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
uv__free(utf16_buffer);
- /* utf8_len *does* include the terminating null at this point, but the */
- /* returned size shouldn't. */
+ /* utf8_len *does* include the terminating null at this point, but the
+ * returned size shouldn't. */
*size_ptr = utf8_len - 1;
return 0;
@@ -173,16 +169,16 @@ int uv_cwd(char* buffer, size_t* size) {
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
} else if (utf16_len > MAX_PATH) {
- /* This should be impossible; however the CRT has a code path to deal */
- /* with this scenario, so I added a check anyway. */
+ /* This should be impossible; however the CRT has a code path to deal with
+ * this scenario, so I added a check anyway. */
return UV_EIO;
}
/* utf16_len contains the length, *not* including the terminating null. */
utf16_buffer[utf16_len] = L'\0';
- /* The returned directory should not have a trailing slash, unless it */
- /* points at a drive root, like c:\. Remove it if needed.*/
+ /* The returned directory should not have a trailing slash, unless it points
+ * at a drive root, like c:\. Remove it if needed. */
if (utf16_buffer[utf16_len - 1] == L'\\' &&
!(utf16_len == 3 && utf16_buffer[1] == L':')) {
utf16_len--;
@@ -239,9 +235,9 @@ int uv_chdir(const char* dir) {
utf16_buffer,
MAX_PATH) == 0) {
DWORD error = GetLastError();
- /* The maximum length of the current working directory is 260 chars, */
- /* including terminating null. If it doesn't fit, the path name must be */
- /* too long. */
+ /* The maximum length of the current working directory is 260 chars,
+ * including terminating null. If it doesn't fit, the path name must be too
+ * long. */
if (error == ERROR_INSUFFICIENT_BUFFER) {
return UV_ENAMETOOLONG;
} else {
@@ -253,9 +249,9 @@ int uv_chdir(const char* dir) {
return uv_translate_sys_error(GetLastError());
}
- /* Windows stores the drive-local path in an "hidden" environment variable, */
- /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */
- /* update this, so we'll have to do it. */
+ /* Windows stores the drive-local path in an "hidden" environment variable,
+ * which has the form "=C:=C:\Windows". SetCurrentDirectory does not update
+ * this, so we'll have to do it. */
utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
@@ -263,8 +259,8 @@ int uv_chdir(const char* dir) {
return UV_EIO;
}
- /* The returned directory should not have a trailing slash, unless it */
- /* points at a drive root, like c:\. Remove it if needed. */
+ /* The returned directory should not have a trailing slash, unless it points
+ * at a drive root, like c:\. Remove it if needed. */
if (utf16_buffer[utf16_len - 1] == L'\\' &&
!(utf16_len == 3 && utf16_buffer[1] == L':')) {
utf16_len--;
@@ -272,8 +268,8 @@ int uv_chdir(const char* dir) {
}
if (utf16_len < 2 || utf16_buffer[1] != L':') {
- /* Doesn't look like a drive letter could be there - probably an UNC */
- /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */
+ /* Doesn't look like a drive letter could be there - probably an UNC path.
+ * TODO: Need to handle win32 namespaces like \\?\C:\ ? */
drive_letter = 0;
} else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
drive_letter = utf16_buffer[0];
@@ -359,14 +355,6 @@ uv_pid_t uv_os_getppid(void) {
}
-int uv_current_pid(void) {
- if (current_pid == 0) {
- current_pid = GetCurrentProcessId();
- }
- return current_pid;
-}
-
-
char** uv_setup_args(int argc, char** argv) {
return argv;
}
@@ -828,6 +816,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
int is_vista_or_greater;
ULONG flags;
+ *addresses_ptr = NULL;
+ *count_ptr = 0;
+
is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
if (is_vista_or_greater) {
flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
@@ -842,17 +833,17 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
}
- /* Fetch the size of the adapters reported by windows, and then get the */
- /* list itself. */
+ /* Fetch the size of the adapters reported by windows, and then get the list
+ * itself. */
win_address_buf_size = 0;
win_address_buf = NULL;
for (;;) {
ULONG r;
- /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */
- /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
- /* win_address_buf_size. */
+ /* If win_address_buf is 0, then GetAdaptersAddresses will fail with.
+ * ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in
+ * win_address_buf_size. */
r = GetAdaptersAddresses(AF_UNSPEC,
flags,
NULL,
@@ -866,8 +857,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
switch (r) {
case ERROR_BUFFER_OVERFLOW:
- /* This happens when win_address_buf is NULL or too small to hold */
- /* all adapters. */
+ /* This happens when win_address_buf is NULL or too small to hold all
+ * adapters. */
win_address_buf = uv__malloc(win_address_buf_size);
if (win_address_buf == NULL)
return UV_ENOMEM;
@@ -901,15 +892,15 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
return UV_ENOBUFS;
default:
- /* Other (unspecified) errors can happen, but we don't have any */
- /* special meaning for them. */
+ /* Other (unspecified) errors can happen, but we don't have any special
+ * meaning for them. */
assert(r != ERROR_SUCCESS);
return uv_translate_sys_error(r);
}
}
- /* Count the number of enabled interfaces and compute how much space is */
- /* needed to store their info. */
+ /* Count the number of enabled interfaces and compute how much space is
+ * needed to store their info. */
count = 0;
uv_address_buf_size = 0;
@@ -919,9 +910,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
int name_size;
- /* Interfaces that are not 'up' should not be reported. Also skip */
- /* interfaces that have no associated unicast address, as to avoid */
- /* allocating space for the name for this interface. */
+ /* Interfaces that are not 'up' should not be reported. Also skip
+ * interfaces that have no associated unicast address, as to avoid
+ * allocating space for the name for this interface. */
if (adapter->OperStatus != IfOperStatusUp ||
adapter->FirstUnicastAddress == NULL)
continue;
@@ -941,8 +932,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
}
uv_address_buf_size += name_size;
- /* Count the number of addresses associated with this interface, and */
- /* compute the size. */
+ /* Count the number of addresses associated with this interface, and
+ * compute the size. */
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
adapter->FirstUnicastAddress;
unicast_address != NULL;
@@ -959,8 +950,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
return UV_ENOMEM;
}
- /* Compute the start of the uv_interface_address_t array, and the place in */
- /* the buffer where the interface names will be stored. */
+ /* Compute the start of the uv_interface_address_t array, and the place in
+ * the buffer where the interface names will be stored. */
uv_address = uv_address_buf;
name_buf = (char*) (uv_address_buf + count);
@@ -1199,8 +1190,8 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
return UV_EIO;
}
- /* The returned directory should not have a trailing slash, unless it */
- /* points at a drive root, like c:\. Remove it if needed.*/
+ /* The returned directory should not have a trailing slash, unless it points
+ * at a drive root, like c:\. Remove it if needed. */
if (path[len - 1] == L'\\' &&
!(len == 3 && path[1] == L':')) {
len--;
@@ -1542,3 +1533,214 @@ int uv_os_gethostname(char* buffer, size_t* size) {
*size = len;
return 0;
}
+
+
+static int uv__get_handle(uv_pid_t pid, int access, HANDLE* handle) {
+ int r;
+
+ if (pid == 0)
+ *handle = GetCurrentProcess();
+ else
+ *handle = OpenProcess(access, FALSE, pid);
+
+ if (*handle == NULL) {
+ r = GetLastError();
+
+ if (r == ERROR_INVALID_PARAMETER)
+ return UV_ESRCH;
+ else
+ return uv_translate_sys_error(r);
+ }
+
+ return 0;
+}
+
+
+int uv_os_getpriority(uv_pid_t pid, int* priority) {
+ HANDLE handle;
+ int r;
+
+ if (priority == NULL)
+ return UV_EINVAL;
+
+ r = uv__get_handle(pid, PROCESS_QUERY_LIMITED_INFORMATION, &handle);
+
+ if (r != 0)
+ return r;
+
+ r = GetPriorityClass(handle);
+
+ if (r == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ } else {
+ /* Map Windows priority classes to Unix nice values. */
+ if (r == REALTIME_PRIORITY_CLASS)
+ *priority = UV_PRIORITY_HIGHEST;
+ else if (r == HIGH_PRIORITY_CLASS)
+ *priority = UV_PRIORITY_HIGH;
+ else if (r == ABOVE_NORMAL_PRIORITY_CLASS)
+ *priority = UV_PRIORITY_ABOVE_NORMAL;
+ else if (r == NORMAL_PRIORITY_CLASS)
+ *priority = UV_PRIORITY_NORMAL;
+ else if (r == BELOW_NORMAL_PRIORITY_CLASS)
+ *priority = UV_PRIORITY_BELOW_NORMAL;
+ else /* IDLE_PRIORITY_CLASS */
+ *priority = UV_PRIORITY_LOW;
+
+ r = 0;
+ }
+
+ CloseHandle(handle);
+ return r;
+}
+
+
+int uv_os_setpriority(uv_pid_t pid, int priority) {
+ HANDLE handle;
+ int priority_class;
+ int r;
+
+ /* Map Unix nice values to Windows priority classes. */
+ if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
+ return UV_EINVAL;
+ else if (priority < UV_PRIORITY_HIGH)
+ priority_class = REALTIME_PRIORITY_CLASS;
+ else if (priority < UV_PRIORITY_ABOVE_NORMAL)
+ priority_class = HIGH_PRIORITY_CLASS;
+ else if (priority < UV_PRIORITY_NORMAL)
+ priority_class = ABOVE_NORMAL_PRIORITY_CLASS;
+ else if (priority < UV_PRIORITY_BELOW_NORMAL)
+ priority_class = NORMAL_PRIORITY_CLASS;
+ else if (priority < UV_PRIORITY_LOW)
+ priority_class = BELOW_NORMAL_PRIORITY_CLASS;
+ else
+ priority_class = IDLE_PRIORITY_CLASS;
+
+ r = uv__get_handle(pid, PROCESS_SET_INFORMATION, &handle);
+
+ if (r != 0)
+ return r;
+
+ if (SetPriorityClass(handle, priority_class) == 0)
+ r = uv_translate_sys_error(GetLastError());
+
+ CloseHandle(handle);
+ return r;
+}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ /* Implementation loosely based on
+ https://github.com/gagern/gnulib/blob/master/lib/uname.c */
+ OSVERSIONINFOW os_info;
+ SYSTEM_INFO system_info;
+ int processor_level;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ uv__once_init();
+ os_info.dwOSVersionInfoSize = sizeof(os_info);
+ os_info.szCSDVersion[0] = L'\0';
+
+ /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx()
+ if RtlGetVersion() is not available. */
+ if (pRtlGetVersion) {
+ pRtlGetVersion(&os_info);
+ } else {
+ /* Silence GetVersionEx() deprecation warning. */
+ #pragma warning(suppress : 4996)
+ if (GetVersionExW(&os_info) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+ }
+
+ /* Populate the version field. */
+ if (WideCharToMultiByte(CP_UTF8,
+ 0,
+ os_info.szCSDVersion,
+ -1,
+ buffer->version,
+ sizeof(buffer->version),
+ NULL,
+ NULL) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+
+ /* Populate the sysname field. */
+#ifdef __MINGW32__
+ r = snprintf(buffer->sysname,
+ sizeof(buffer->sysname),
+ "MINGW32_NT-%u.%u",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion);
+ assert(r < sizeof(buffer->sysname));
+#else
+ uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname));
+#endif
+
+ /* Populate the release field. */
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%d.%d.%d",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion,
+ (unsigned int) os_info.dwBuildNumber);
+ assert(r < sizeof(buffer->release));
+
+ /* Populate the machine field. */
+ GetSystemInfo(&system_info);
+
+ switch (system_info.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+ uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine));
+
+ if (system_info.wProcessorLevel > 3) {
+ processor_level = system_info.wProcessorLevel < 6 ?
+ system_info.wProcessorLevel : 6;
+ buffer->machine[1] = '0' + processor_level;
+ }
+
+ break;
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+ uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ case PROCESSOR_ARCHITECTURE_ALPHA64:
+ uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_PPC:
+ uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_SHX:
+ uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ARM:
+ uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
+ break;
+ default:
+ uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
+ break;
+ }
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/Utilities/cmlibuv/src/win/winapi.c b/Utilities/cmlibuv/src/win/winapi.c
index c330786..fbbbcee 100644
--- a/Utilities/cmlibuv/src/win/winapi.c
+++ b/Utilities/cmlibuv/src/win/winapi.c
@@ -26,6 +26,7 @@
/* Ntdll function pointers */
+sRtlGetVersion pRtlGetVersion;
sRtlNtStatusToDosError pRtlNtStatusToDosError;
sNtDeviceIoControlFile pNtDeviceIoControlFile;
sNtQueryInformationFile pNtQueryInformationFile;
@@ -34,20 +35,8 @@ sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
sNtQueryDirectoryFile pNtQueryDirectoryFile;
sNtQuerySystemInformation pNtQuerySystemInformation;
-
/* Kernel32 function pointers */
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
-sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
-sCreateSymbolicLinkW pCreateSymbolicLinkW;
-sCancelIoEx pCancelIoEx;
-sInitializeConditionVariable pInitializeConditionVariable;
-sSleepConditionVariableCS pSleepConditionVariableCS;
-sSleepConditionVariableSRW pSleepConditionVariableSRW;
-sWakeAllConditionVariable pWakeAllConditionVariable;
-sWakeConditionVariable pWakeConditionVariable;
-sCancelSynchronousIo pCancelSynchronousIo;
-sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
-
/* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
@@ -55,22 +44,21 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
/* User32.dll function pointer */
sSetWinEventHook pSetWinEventHook;
-/* iphlpapi.dll function pointer */
-sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid = NULL;
-sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW = NULL;
void uv_winapi_init(void) {
HMODULE ntdll_module;
- HMODULE kernel32_module;
HMODULE powrprof_module;
HMODULE user32_module;
- HMODULE iphlpapi_module;
+ HMODULE kernel32_module;
ntdll_module = GetModuleHandleA("ntdll.dll");
if (ntdll_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
}
+ pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
+ "RtlGetVersion");
+
pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
ntdll_module,
"RtlNtStatusToDosError");
@@ -127,37 +115,6 @@ void uv_winapi_init(void) {
kernel32_module,
"GetQueuedCompletionStatusEx");
- pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
- GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");
-
- pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
- GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
-
- pCancelIoEx = (sCancelIoEx)
- GetProcAddress(kernel32_module, "CancelIoEx");
-
- pInitializeConditionVariable = (sInitializeConditionVariable)
- GetProcAddress(kernel32_module, "InitializeConditionVariable");
-
- pSleepConditionVariableCS = (sSleepConditionVariableCS)
- GetProcAddress(kernel32_module, "SleepConditionVariableCS");
-
- pSleepConditionVariableSRW = (sSleepConditionVariableSRW)
- GetProcAddress(kernel32_module, "SleepConditionVariableSRW");
-
- pWakeAllConditionVariable = (sWakeAllConditionVariable)
- GetProcAddress(kernel32_module, "WakeAllConditionVariable");
-
- pWakeConditionVariable = (sWakeConditionVariable)
- GetProcAddress(kernel32_module, "WakeConditionVariable");
-
- pCancelSynchronousIo = (sCancelSynchronousIo)
- GetProcAddress(kernel32_module, "CancelSynchronousIo");
-
- pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW)
- GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW");
-
-
powrprof_module = LoadLibraryA("powrprof.dll");
if (powrprof_module != NULL) {
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
@@ -170,11 +127,4 @@ void uv_winapi_init(void) {
GetProcAddress(user32_module, "SetWinEventHook");
}
- iphlpapi_module = LoadLibraryA("iphlpapi.dll");
- if (iphlpapi_module != NULL) {
- pConvertInterfaceIndexToLuid = (sConvertInterfaceIndexToLuid)
- GetProcAddress(iphlpapi_module, "ConvertInterfaceIndexToLuid");
- pConvertInterfaceLuidToNameW = (sConvertInterfaceLuidToNameW)
- GetProcAddress(iphlpapi_module, "ConvertInterfaceLuidToNameW");
- }
}
diff --git a/Utilities/cmlibuv/src/win/winapi.h b/Utilities/cmlibuv/src/win/winapi.h
index ae384b7..1e49b57 100644
--- a/Utilities/cmlibuv/src/win/winapi.h
+++ b/Utilities/cmlibuv/src/win/winapi.h
@@ -4076,8 +4076,8 @@
# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L)
#endif
-/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */
-/* DDK got it wrong! */
+/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the DDK
+ * got it wrong! */
#ifdef NTSTATUS_FROM_WIN32
# undef NTSTATUS_FROM_WIN32
#endif
@@ -4109,6 +4109,9 @@
#endif
/* from winternl.h */
+#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32_)
+#define __UNICODE_STRING_DEFINED
+#endif
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
@@ -4524,6 +4527,9 @@ typedef VOID (NTAPI *PIO_APC_ROUTINE)
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved);
+typedef NTSTATUS (NTAPI *sRtlGetVersion)
+ (PRTL_OSVERSIONINFOW lpVersionInformation);
+
typedef ULONG (NTAPI *sRtlNtStatusToDosError)
(NTSTATUS Status);
@@ -4659,48 +4665,6 @@ typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx)
DWORD dwMilliseconds,
BOOL fAlertable);
-typedef BOOL (WINAPI* sSetFileCompletionNotificationModes)
- (HANDLE FileHandle,
- UCHAR Flags);
-
-typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
- (LPCWSTR lpSymlinkFileName,
- LPCWSTR lpTargetFileName,
- DWORD dwFlags);
-
-typedef BOOL (WINAPI* sCancelIoEx)
- (HANDLE hFile,
- LPOVERLAPPED lpOverlapped);
-
-typedef VOID (WINAPI* sInitializeConditionVariable)
- (PCONDITION_VARIABLE ConditionVariable);
-
-typedef BOOL (WINAPI* sSleepConditionVariableCS)
- (PCONDITION_VARIABLE ConditionVariable,
- PCRITICAL_SECTION CriticalSection,
- DWORD dwMilliseconds);
-
-typedef BOOL (WINAPI* sSleepConditionVariableSRW)
- (PCONDITION_VARIABLE ConditionVariable,
- PSRWLOCK SRWLock,
- DWORD dwMilliseconds,
- ULONG Flags);
-
-typedef VOID (WINAPI* sWakeAllConditionVariable)
- (PCONDITION_VARIABLE ConditionVariable);
-
-typedef VOID (WINAPI* sWakeConditionVariable)
- (PCONDITION_VARIABLE ConditionVariable);
-
-typedef BOOL (WINAPI* sCancelSynchronousIo)
- (HANDLE hThread);
-
-typedef DWORD (WINAPI* sGetFinalPathNameByHandleW)
- (HANDLE hFile,
- LPWSTR lpszFilePath,
- DWORD cchFilePath,
- DWORD dwFlags);
-
/* from powerbase.h */
#ifndef DEVICE_NOTIFY_CALLBACK
# define DEVICE_NOTIFY_CALLBACK 2
@@ -4755,6 +4719,7 @@ typedef HWINEVENTHOOK (WINAPI *sSetWinEventHook)
/* Ntdll function pointers */
+extern sRtlGetVersion pRtlGetVersion;
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
extern sNtQueryInformationFile pNtQueryInformationFile;
@@ -4763,20 +4728,8 @@ extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
extern sNtQuerySystemInformation pNtQuerySystemInformation;
-
/* Kernel32 function pointers */
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
-extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
-extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
-extern sCancelIoEx pCancelIoEx;
-extern sInitializeConditionVariable pInitializeConditionVariable;
-extern sSleepConditionVariableCS pSleepConditionVariableCS;
-extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
-extern sWakeAllConditionVariable pWakeAllConditionVariable;
-extern sWakeConditionVariable pWakeConditionVariable;
-extern sCancelSynchronousIo pCancelSynchronousIo;
-extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
-
/* Powrprof.dll function pointer */
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
@@ -4784,19 +4737,4 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi
/* User32.dll function pointer */
extern sSetWinEventHook pSetWinEventHook;
-/* iphlpapi.dll function pointer */
-union _NET_LUID_LH;
-typedef DWORD (WINAPI *sConvertInterfaceIndexToLuid)(
- ULONG InterfaceIndex,
- union _NET_LUID_LH *InterfaceLuid);
-
-typedef DWORD (WINAPI *sConvertInterfaceLuidToNameW)(
- const union _NET_LUID_LH *InterfaceLuid,
- PWSTR InterfaceName,
- size_t Length);
-
-extern sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid;
-extern sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW;
-
-
#endif /* UV_WIN_WINAPI_H_ */
diff --git a/Utilities/cmlibuv/src/win/winsock.c b/Utilities/cmlibuv/src/win/winsock.c
index 8418895..5e7da2a 100644
--- a/Utilities/cmlibuv/src/win/winsock.c
+++ b/Utilities/cmlibuv/src/win/winsock.c
@@ -256,8 +256,8 @@ int uv_ntstatus_to_winsock_error(NTSTATUS status) {
default:
if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
(status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
- /* It's a windows error that has been previously mapped to an */
- /* ntstatus code. */
+ /* It's a windows error that has been previously mapped to an ntstatus
+ * code. */
return (DWORD) (status & 0xffff);
} else {
/* The default fallback for unmappable ntstatus codes. */
@@ -519,8 +519,8 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
sizeof *info_out);
if (overlapped == NULL) {
- /* If this is a blocking operation, wait for the event to become */
- /* signaled, and then grab the real status from the io status block. */
+ /* If this is a blocking operation, wait for the event to become signaled,
+ * and then grab the real status from the io status block. */
if (status == STATUS_PENDING) {
DWORD r = WaitForSingleObject(event, INFINITE);
diff --git a/bootstrap b/bootstrap
index dcc3a83..901bc10 100755
--- a/bootstrap
+++ b/bootstrap
@@ -491,8 +491,11 @@ KWSYS_FILES="\
if ${cmake_system_mingw}; then
LIBUV_C_SOURCES="\
src/fs-poll.c \
+ src/idna.c
src/inet.c \
src/threadpool.c \
+ src/strscpy.c \
+ src/timer.c \
src/uv-common.c \
src/win/async.c \
src/win/core.c \
@@ -509,12 +512,10 @@ if ${cmake_system_mingw}; then
src/win/poll.c \
src/win/process-stdio.c \
src/win/process.c \
- src/win/req.c \
src/win/signal.c \
src/win/stream.c \
src/win/tcp.c \
src/win/thread.c \
- src/win/timer.c \
src/win/tty.c \
src/win/udp.c \
src/win/util.c \
@@ -523,6 +524,8 @@ if ${cmake_system_mingw}; then
"
else
LIBUV_C_SOURCES="\
+ src/strscpy.c \
+ src/timer.c \
src/uv-common.c \
src/unix/cmake-bootstrap.c \
src/unix/core.c \
@@ -537,7 +540,6 @@ else
src/unix/process.c \
src/unix/signal.c \
src/unix/stream.c \
- src/unix/timer.c \
"
fi