summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Options.h1
-rw-r--r--src/Output.h2
-rw-r--r--src/Utils.h1
-rw-r--r--src/kwsys/.gitattributes16
-rw-r--r--src/kwsys/CMakeLists.txt1292
-rw-r--r--src/kwsys/CONTRIBUTING.rst35
-rw-r--r--src/kwsys/Configure.h.in131
-rw-r--r--src/kwsys/Copyright.txt31
-rw-r--r--src/kwsys/Encoding.h.in79
-rw-r--r--src/kwsys/EncodingC.c85
-rw-r--r--src/kwsys/Process.h.in462
-rw-r--r--src/kwsys/ProcessUNIX.c3058
-rw-r--r--src/kwsys/ProcessWin32.c3017
-rw-r--r--src/kwsys/README.txt12
-rw-r--r--src/kwsys/System.c301
-rw-r--r--src/kwsys/System.h.in69
-rw-r--r--src/kwsys/kwsysPlatformTests.cmake219
-rw-r--r--src/kwsys/kwsysPlatformTestsC.c100
-rw-r--r--src/kwsys/kwsysPlatformTestsCXX.cxx699
-rw-r--r--src/kwsys/kwsysPrivate.h41
21 files changed, 0 insertions, 9652 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f3f80c4..b1acad3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,7 +66,6 @@ add_executable(castxml
Utils.cxx Utils.h
)
target_link_libraries(castxml
- cxsys
${clang_libs}
${llvm_libs}
)
diff --git a/src/Options.h b/src/Options.h
index 0c7ffd9..d81c421 100644
--- a/src/Options.h
+++ b/src/Options.h
@@ -16,7 +16,6 @@
#ifndef CASTXML_OPTIONS_H
#define CASTXML_OPTIONS_H
-#include <cxsys/Configure.h>
#include <string>
#include <vector>
diff --git a/src/Output.h b/src/Output.h
index db1982b..5c5ee11 100644
--- a/src/Output.h
+++ b/src/Output.h
@@ -16,8 +16,6 @@
#ifndef CASTXML_OUTPUT_H
#define CASTXML_OUTPUT_H
-#include <cxsys/Configure.h>
-
namespace llvm {
class raw_ostream;
}
diff --git a/src/Utils.h b/src/Utils.h
index a29e96f..e53c006 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -16,7 +16,6 @@
#ifndef CASTXML_UTILS_H
#define CASTXML_UTILS_H
-#include <cxsys/Configure.h>
#include <string>
/// findResources - Call from main() to find resources
diff --git a/src/kwsys/.gitattributes b/src/kwsys/.gitattributes
deleted file mode 100644
index 248786e..0000000
--- a/src/kwsys/.gitattributes
+++ /dev/null
@@ -1,16 +0,0 @@
-.git* export-ignore
-.gitattributes -export-ignore
-
-/GitSetup export-ignore
-/SetupForDevelopment.sh export-ignore eol=lf
-
-/CONTRIBUTING.rst conflict-marker-size=78
-
-*.c whitespace=tab-in-indent,no-lf-at-eof
-*.h whitespace=tab-in-indent,no-lf-at-eof
-*.h.in whitespace=tab-in-indent,no-lf-at-eof
-*.cxx whitespace=tab-in-indent,no-lf-at-eof
-*.hxx whitespace=tab-in-indent,no-lf-at-eof
-*.hxx.in whitespace=tab-in-indent,no-lf-at-eof
-*.txt whitespace=tab-in-indent,no-lf-at-eof
-*.cmake whitespace=tab-in-indent,no-lf-at-eof
diff --git a/src/kwsys/CMakeLists.txt b/src/kwsys/CMakeLists.txt
deleted file mode 100644
index 9b26553..0000000
--- a/src/kwsys/CMakeLists.txt
+++ /dev/null
@@ -1,1292 +0,0 @@
-#=============================================================================
-# KWSys - Kitware System Library
-# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-
-# The Kitware System Library is intended to be included in other
-# projects. It is completely configurable in that the library's
-# namespace can be configured and the components that are included can
-# be selected invididually.
-
-# Typical usage is to import the kwsys directory tree into a
-# subdirectory under a parent project and enable the classes that will
-# be used. All classes are disabled by default. The CMake listfile
-# above this one configures the library as follows:
-#
-# SET(KWSYS_NAMESPACE foosys)
-# SET(KWSYS_USE_Directory 1) # Enable Directory class.
-# SUBDIRS(kwsys)
-#
-# Optional settings are as follows:
-#
-# KWSYS_HEADER_ROOT = The directory into which to generate the kwsys headers.
-# A directory called "${KWSYS_NAMESPACE}" will be
-# created under this root directory to hold the files.
-#
-# Example:
-#
-# SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
-# INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
-#
-# KWSYS_IOS_FORCE_OLD = Force use of old non-ANSI C++ streams even if
-# new streams are available. This may be used
-# by projects that cannot configure their
-# streams library.
-# Example:
-#
-# SET(KWSYS_IOS_FORCE_OLD 1)
-#
-#
-# Optional settings to setup install rules are as follows:
-#
-# KWSYS_INSTALL_BIN_DIR = The installation target directories into
-# KWSYS_INSTALL_LIB_DIR which the libraries and headers from
-# KWSYS_INSTALL_INCLUDE_DIR kwsys should be installed by a "make install".
-# The values should be specified relative to
-# the installation prefix and NOT start with '/'.
-# KWSYS_INSTALL_DOC_DIR = The installation target directory for documentation
-# such as copyright information.
-#
-# KWSYS_INSTALL_COMPONENT_NAME_RUNTIME = Name of runtime and development
-# KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT installation components.
-# If not given the install rules
-# will not be in any component.
-#
-# KWSYS_INSTALL_EXPORT_NAME = The EXPORT option value for install(TARGETS) calls.
-#
-# Example:
-#
-# SET(KWSYS_INSTALL_BIN_DIR bin)
-# SET(KWSYS_INSTALL_LIB_DIR lib)
-# SET(KWSYS_INSTALL_INCLUDE_DIR include)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
-
-# Once configured, kwsys should be used as follows from C or C++ code:
-#
-# #include <foosys/Directory.hxx>
-# ...
-# foosys::Directory directory;
-#
-
-# NOTE: This library is intended for internal use by Kitware-driven
-# projects. In order to keep it simple no attempt will be made to
-# maintain backward compatibility when changes are made to KWSys.
-# When an incompatible change is made Kitware's projects that use
-# KWSys will be fixed, but no notification will necessarily be sent to
-# any outside mailing list and no documentation of the change will be
-# written.
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
-IF(POLICY CMP0025)
- CMAKE_POLICY(SET CMP0025 NEW)
-ENDIF()
-IF(POLICY CMP0056)
- CMAKE_POLICY(SET CMP0056 NEW)
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# If a namespace is not specified, use "kwsys" and enable testing.
-# This should be the case only when kwsys is not included inside
-# another project and is being tested.
-IF(NOT KWSYS_NAMESPACE)
- SET(KWSYS_NAMESPACE "kwsys")
- SET(KWSYS_STANDALONE 1)
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# The project name is that of the specified namespace.
-PROJECT(${KWSYS_NAMESPACE})
-
-# Tell CMake how to follow dependencies of sources in this directory.
-SET_PROPERTY(DIRECTORY
- PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
- "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>"
- )
-
-# Select library components.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- SET(KWSYS_ENABLE_C 1)
- # Enable all components.
- SET(KWSYS_USE_Base64 1)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_DynamicLoader 1)
- SET(KWSYS_USE_Encoding 1)
- SET(KWSYS_USE_Glob 1)
- SET(KWSYS_USE_MD5 1)
- SET(KWSYS_USE_Process 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_CommandLineArguments 1)
- SET(KWSYS_USE_FundamentalType 1)
- SET(KWSYS_USE_Terminal 1)
- SET(KWSYS_USE_IOStream 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_String 1)
- SET(KWSYS_USE_SystemInformation 1)
- SET(KWSYS_USE_CPU 1)
-ENDIF()
-
-# Enforce component dependencies.
-IF(KWSYS_USE_SystemTools)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Glob)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Process)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_USE_Process 1)
-ENDIF()
-IF(KWSYS_USE_System)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Directory)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_FStream)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-
-# Setup the large file support default.
-IF(KWSYS_LFS_DISABLE)
- SET(KWSYS_LFS_REQUESTED 0)
-ELSE()
- SET(KWSYS_LFS_REQUESTED 1)
-ENDIF()
-
-# Specify default 8 bit encoding for Windows
-IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
- SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
-ENDIF()
-
-# Enable testing if building standalone.
-IF(KWSYS_STANDALONE)
- INCLUDE(Dart)
- MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
- IF(BUILD_TESTING)
- ENABLE_TESTING()
- ENDIF()
-ENDIF()
-
-# Include helper macros.
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
-INCLUDE(CheckTypeSize)
-
-# Do full dependency headers.
-INCLUDE_REGULAR_EXPRESSION("^.*$")
-
-# Use new KWSYS_INSTALL_*_DIR variable names to control installation.
-# Take defaults from the old names. Note that there was no old name
-# for the bin dir, so we take the old lib dir name so DLLs will be
-# installed in a compatible way for old code.
-IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
- "${KWSYS_HEADER_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_LIB_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
- "${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_BIN_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
- "${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
-
-# Setup header install rules.
-SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
-IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
- COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
- )
-ENDIF()
-
-# Setup library install rules.
-SET(KWSYS_INSTALL_LIBRARY_RULE)
-IF(KWSYS_INSTALL_LIB_DIR)
- IF(KWSYS_INSTALL_EXPORT_NAME)
- LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
- ENDIF()
- # Install the shared library to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR}
- )
- # Assign the shared library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
- )
- ENDIF()
-
- # Install the archive to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR}
- )
- # Assign the archive to the development component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
- )
- ENDIF()
-ENDIF()
-IF(KWSYS_INSTALL_BIN_DIR)
- # Install the runtime library to the bin directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR}
- )
- # Assign the runtime library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
- COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
- )
- ENDIF()
-ENDIF()
-
-# Do not support old KWSYS_*a_INSTALL_DIR variable names.
-SET(KWSYS_HEADER_INSTALL_DIR)
-SET(KWSYS_LIBRARY_INSTALL_DIR)
-
-# Generated source files will need this header.
-STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
- KWSYS_IN_SOURCE_BUILD)
-IF(NOT KWSYS_IN_SOURCE_BUILD)
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
- ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE)
-ENDIF()
-
-# Select plugin module file name convention.
-IF(NOT KWSYS_DynamicLoader_PREFIX)
- SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
-ENDIF()
-IF(NOT KWSYS_DynamicLoader_SUFFIX)
- SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# We require ANSI support from the C compiler. Add any needed flags.
-IF(CMAKE_ANSI_CFLAGS)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Adjust compiler flags for some platforms.
-IF(NOT CMAKE_COMPILER_IS_GNUCXX)
- IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
- STRING(REGEX MATCH "-timplicit_local"
- KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}")
- STRING(REGEX MATCH "-no_implicit_include"
- KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}")
- IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
- ENDIF()
- IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
- SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
- IF(CMAKE_CXX_COMPILER_ID MATCHES "HP")
- # it is known that version 3.85 fails and 6.25 works without these flags
- IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
- # use new C++ library and improved template support
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
- ENDIF()
- ENDIF()
- ENDIF()
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Configure Large File Support.
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDIO
- "Checking whether header cstdio is available" DIRECT)
-SET(KWSYS_LFS_AVAILABLE 0)
-IF(KWSYS_LFS_REQUESTED)
- # Large File Support is requested.
- SET(KWSYS_LFS_REQUESTED 1)
-
- # Check for large file support.
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_CXX_HAS_CSTDIO=${KWSYS_CXX_HAS_CSTDIO})
- KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_LFS_WORKS
- "Checking for Large File Support" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-
- IF(KWSYS_LFS_WORKS)
- SET(KWSYS_LFS_AVAILABLE 1)
- ENDIF()
-ELSE()
- # Large File Support is not requested.
- SET(KWSYS_LFS_REQUESTED 0)
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Configure the standard library header wrappers based on compiler's
-# capabilities and parent project's request. Enforce 0/1 as only
-# possible values for configuration into Configure.hxx.
-
-IF(0) # Not used by CastXML
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAVE_STD
- "Checking whether STL classes are in std namespace" DIRECT)
-
-IF(KWSYS_IOS_FORCE_OLD)
- SET(KWSYS_IOS_USE_ANSI 0)
-ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_ANSI
- "Checking whether ANSI stream headers are available" DIRECT)
-ENDIF()
-
-IF(KWSYS_IOS_USE_ANSI)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_STD
- "Checking whether ANSI streams are in std namespace" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_SSTREAM
- "Checking whether ANSI string stream is available" DIRECT)
-ELSE()
- SET(KWSYS_IOS_HAVE_STD 0)
- SET(KWSYS_IOS_USE_SSTREAM 0)
-ENDIF()
-
-IF(KWSYS_IOS_USE_SSTREAM)
- SET(KWSYS_IOS_USE_STRSTREAM_H 0)
- SET(KWSYS_IOS_USE_STRSTREA_H 0)
-ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREAM_H
- "Checking whether strstream.h is available" DIRECT)
- IF(KWSYS_IOS_USE_STRSTREAM_H)
- SET(KWSYS_IOS_USE_STRSTREA_H 0)
- ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREA_H
- "Checking whether strstrea.h is available" DIRECT)
- ENDIF()
-ENDIF()
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDDEF
- "Checking whether header cstddef is available" DIRECT)
-
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_NEQ_CHAR
- "Checking whether stl string has operator!= for char*" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_TRAITS
- "Checking whether stl has iterator_traits" DIRECT)
-IF(KWSYS_STL_HAS_ITERATOR_TRAITS)
- SET(KWSYS_STL_HAS_ITERATOR_CATEGORY 0)
- SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
-ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_CATEGORY
- "Checking whether stl has old iterator_category" DIRECT)
- IF(KWSYS_STL_HAS_ITERATOR_CATEGORY)
- SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
- ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS___ITERATOR_CATEGORY
- "Checking whether stl has internal __iterator_category" DIRECT)
- ENDIF()
-ENDIF()
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
- "Checking whether stl has standard template allocator" DIRECT)
-IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE)
- SET(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE 0)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_REBIND
- "Checking for rebind member of stl allocator" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
- "Checking for non-standard argument to stl allocator<>::max_size" DIRECT)
-ELSE()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
- "Checking whether stl has old non-template allocator" DIRECT)
- SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0)
- SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0)
-ENDIF()
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS
- "Checking whether stl containers support allocator objects." DIRECT)
-IF(KWSYS_IOS_USE_ANSI AND NOT WATCOM)
- # ANSI streams always have string operators.
- SET(KWSYS_STL_STRING_HAVE_OSTREAM 1)
- SET(KWSYS_STL_STRING_HAVE_ISTREAM 1)
-ELSE()
- # There may not be string operators for old streams.
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM
- "Checking whether stl string has ostream operator<<" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM
- "Checking whether stl string has istream operator>>" DIRECT)
-ENDIF()
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
- -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_BINARY
- "Checking whether ios has binary openmode" DIRECT)
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
- "Checking whether \"<>\" is needed for template friends" INVERT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_MEMBER_TEMPLATES
- "Checking for member template support" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_FULL_SPECIALIZATION
- "Checking for standard template specialization syntax" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
- "Checking whether argument dependent lookup is supported" DIRECT)
-
-IF(UNIX)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STAT_HAS_ST_MTIM
- "Checking whether struct stat has st_mtim member" DIRECT)
-ENDIF()
-
-# Check existence and uniqueness of long long and __int64.
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG
- "Checking whether C++ compiler has 'long long'" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64
- "Checking whether C++ compiler has '__int64'" DIRECT)
-IF(KWSYS_CXX_HAS___INT64)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64
- "Checking whether long and __int64 are the same type" DIRECT)
- IF(KWSYS_CXX_HAS_LONG_LONG)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
- "Checking whether long long and __int64 are the same type" DIRECT)
- ENDIF()
-ENDIF()
-
-# Enable the "long long" type if it is available. It is standard in
-# C99 and C++03 but not in earlier standards.
-IF(KWSYS_CXX_HAS_LONG_LONG)
- SET(KWSYS_USE_LONG_LONG 1)
-ELSE()
- SET(KWSYS_USE_LONG_LONG 0)
-ENDIF()
-
-# Enable the "__int64" type if it is available and unique. It is not
-# standard.
-SET(KWSYS_USE___INT64 0)
-IF(KWSYS_CXX_HAS___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
- SET(KWSYS_USE___INT64 1)
- ENDIF()
- ENDIF()
-ENDIF()
-ENDIF()
-
-IF(KWSYS_USE_FundamentalType)
- # Look for type size helper macros.
- KWSYS_PLATFORM_INFO_TEST(C KWSYS_C_TYPE_MACROS
- "Checking for C type size macros")
- SET(macro_regex ".*INFO:macro\\[([^]]*)\\].*")
- FOREACH(info ${KWSYS_C_TYPE_MACROS})
- IF("${info}" MATCHES "${macro_regex}")
- STRING(REGEX REPLACE "${macro_regex}" "\\1" macro "${info}")
- SET(KWSYS_C_HAS_MACRO_${macro} 1)
- ENDIF()
- ENDFOREACH()
-
- # Determine type sizes at preprocessing time if possible, and
- # otherwise fall back to a try-compile.
- SET(KWSYS_C_TYPE_NAME_CHAR "char")
- SET(KWSYS_C_TYPE_NAME_SHORT "short")
- SET(KWSYS_C_TYPE_NAME_INT "int")
- SET(KWSYS_C_TYPE_NAME_LONG "long")
- SET(KWSYS_C_TYPE_NAME_LONG_LONG "long long")
- SET(KWSYS_C_TYPE_NAME___INT64 "__int64")
- FOREACH(type CHAR SHORT INT LONG LONG_LONG __INT64)
- IF(KWSYS_C_HAS_MACRO___SIZEOF_${type}__)
- # Use __SIZEOF_${type}__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} __SIZEOF_${type}__")
- ELSEIF(KWSYS_C_HAS_MACRO___${type}_MAX__)
- # Use __${type}_MAX__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#if __${type}_MAX__ == 0x7f
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 1
-#elif __${type}_MAX__ == 0x7fff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 2
-#elif __${type}_MAX__ == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 4
-#elif __${type}_MAX__>>32 == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 8
-#else
-# error \"Cannot determine sizeof(${KWSYS_C_TYPE_NAME_${type}}).\"
-#endif")
- ELSE()
- # Configure a hard-coded type size.
- CHECK_TYPE_SIZE("${KWSYS_C_TYPE_NAME_${type}}" KWSYS_SIZEOF_${type})
- IF(NOT KWSYS_SIZEOF_${type})
- SET(KWSYS_SIZEOF_${type} 0)
- ENDIF()
- SET(KWSYS_C_CODE_SIZEOF_${type}
- "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} ${KWSYS_SIZEOF_${type}}")
- ENDIF()
- ENDFOREACH()
-
- IF(KWSYS_USE___INT64)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE
- "Checking whether unsigned __int64 can convert to double" DIRECT)
- ELSE()
- SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1)
- ENDIF()
-
- # Check signedness of "char" type.
- KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_CHAR_IS_SIGNED
- "Checking whether char is signed" DIRECT)
-ENDIF()
-
-IF(0) # Not used by CastXML
-IF(KWSYS_USE_Encoding)
- # Look for type size helper macros.
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
- "Checking whether wstring is available" DIRECT)
-ENDIF()
-ENDIF()
-
-IF(KWSYS_USE_IOStream)
- # Determine whether iostreams support long long.
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
- -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
- IF(KWSYS_CXX_HAS_LONG_LONG)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
- "Checking if istream supports long long" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
- "Checking if ostream supports long long" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
- SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
- ENDIF()
- IF(KWSYS_CXX_HAS___INT64)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
- "Checking if istream supports __int64" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
- "Checking if ostream supports __int64" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
- SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
- ENDIF()
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-ENDIF()
-
-IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
- SET(KWSYS_NAME_IS_KWSYS 1)
-ELSE()
- SET(KWSYS_NAME_IS_KWSYS 0)
-ENDIF()
-
-# Choose default shared/static build if not specified.
-IF(KWSYS_BUILD_SHARED MATCHES "^KWSYS_BUILD_SHARED$")
- SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
-ENDIF()
-
-IF(KWSYS_BUILD_SHARED)
- SET(KWSYS_BUILD_SHARED 1)
- SET(KWSYS_LIBRARY_TYPE SHARED)
-ELSE()
- SET(KWSYS_BUILD_SHARED 0)
- SET(KWSYS_LIBRARY_TYPE STATIC)
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Configure some implementation details.
-
-KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
- "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
-KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
- "Checking whether C compiler has ssize_t in unistd.h" DIRECT)
-SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
- COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}"
- )
-
-IF(KWSYS_USE_SystemTools)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV
- "Checking whether CXX compiler has setenv" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UNSETENV
- "Checking whether CXX compiler has unsetenv" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
- "Checking whether CXX compiler has environ in stdlib.h" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMES
- "Checking whether CXX compiler has utimes" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMENSAT
- "Checking whether CXX compiler has utimensat" DIRECT)
- SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
- KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
- KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
- KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}
- KWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES}
- KWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT}
- )
-ENDIF()
-
-IF(KWSYS_USE_SystemInformation)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
- IF(NOT CYGWIN)
- INCLUDE(CheckIncludeFiles)
- CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
- IF(KWSYS_SYS_HAS_IFADDRS_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1)
- ENDIF()
- ENDIF()
- IF(WIN32)
- INCLUDE(CheckSymbolExists)
- SET(CMAKE_REQUIRED_LIBRARIES Psapi)
- CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI)
- UNSET(CMAKE_REQUIRED_LIBRARIES)
- IF(KWSYS_SYS_HAS_PSAPI)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1)
- IF(MSVC70 OR MSVC71)
- # Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
- CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
- IF(KWSYS_SYS_HAS_MPCTL_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "BSD")
- CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
- IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
- ENDIF()
- ENDIF()
- IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
- ENDIF()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
- "Checking whether CXX compiler has rlimit64" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
- IF(KWSYS_CXX_HAS_RLIMIT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
- ENDIF()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
- "Checking whether CXX compiler has atol" DIRECT)
- IF(KWSYS_CXX_HAS_ATOL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
- ENDIF()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
- "Checking whether CXX compiler has atoll" DIRECT)
- IF(KWSYS_CXX_HAS_ATOLL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
- ENDIF()
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
- "Checking whether CXX compiler has _atoi64" DIRECT)
- IF(KWSYS_CXX_HAS__ATOI64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
- ENDIF()
- IF(UNIX)
- INCLUDE(CheckIncludeFileCXX)
- # check for simple stack trace
- # usually it's in libc but on FreeBSD
- # it's in libexecinfo
- FIND_LIBRARY(EXECINFO_LIB "execinfo")
- MARK_AS_ADVANCED(EXECINFO_LIB)
- IF (NOT EXECINFO_LIB)
- SET(EXECINFO_LIB "")
- ENDIF()
- CHECK_INCLUDE_FILE_CXX("execinfo.h" KWSYS_CXX_HAS_EXECINFOH)
- IF (KWSYS_CXX_HAS_EXECINFOH)
- # we have the backtrace header check if it
- # can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BACKTRACE
- "Checking whether backtrace works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_BACKTRACE)
- # backtrace is supported by this system and compiler.
- # now check for the more advanced capabilities.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE=1)
- # check for symbol lookup using dladdr
- CHECK_INCLUDE_FILE_CXX("dlfcn.h" KWSYS_CXX_HAS_DLFCNH)
- IF (KWSYS_CXX_HAS_DLFCNH)
- # we have symbol lookup libraries and headers
- # check if they can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_DLADDR
- "Checking whether dladdr works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_DLADDR)
- # symbol lookup is supported by this system
- # and compiler.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP=1)
- ENDIF()
- ENDIF()
- # c++ demangling support
- # check for cxxabi headers
- CHECK_INCLUDE_FILE_CXX("cxxabi.h" KWSYS_CXX_HAS_CXXABIH)
- IF (KWSYS_CXX_HAS_CXXABIH)
- # check if cxxabi can be used with this
- # system and compiler.
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CXXABI
- "Checking whether cxxabi works with this C++ compiler" DIRECT)
- IF (KWSYS_CXX_HAS_CXXABI)
- # c++ demangle using cxxabi is supported with
- # this system and compiler
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE=1)
- ENDIF()
- ENDIF()
- # basic backtrace works better with release build
- # don't bother with advanced features for release
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS_DEBUG KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS_RELWITHDEBINFO KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(BORLAND)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
- "Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
- "Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(KWSYS_USE___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
- ENDIF()
- IF(KWSYS_USE_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
- ENDIF()
-
- IF(UNIX AND NOT CYGWIN)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
- "Checking whether CXX compiler has getloadavg" DIRECT)
- IF(KWSYS_CXX_HAS_GETLOADAVG)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
- ENDIF()
- ENDIF()
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Choose a directory for the generated headers.
-IF(NOT KWSYS_HEADER_ROOT)
- SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
-ENDIF()
-SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
-INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
-
-#-----------------------------------------------------------------------------
-IF(KWSYS_INSTALL_DOC_DIR)
- # Assign the license to the runtime component since it must be
- # distributed with binary forms of this software.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
- COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
- )
- ENDIF()
-
- # Install the license under the documentation directory.
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
- DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_LICENSE_OPTIONS})
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Create STL header wrappers to block warnings in the STL headers and
-# give standard names by which they may be included.
-IF(0) # Not used by CastXML
-SET(KWSYS_STL_HEADER_EXTRA_string 1)
-FOREACH(header
- algorithm
- deque
- exception
- functional
- iterator
- list
- map
- memory
- new
- numeric
- queue
- set
- stack
- stdexcept
- string
- utility
- vector
- )
- # Configure the header wrapper.
- SET(KWSYS_STL_HEADER "${header}")
- IF(KWSYS_STL_HEADER_EXTRA_${header})
- SET(KWSYS_STL_HEADER_EXTRA
- "#define ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n# include <${KWSYS_NAMESPACE}/stl/${header}.hxx>\n#undef ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n")
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl_${header}.hxx.in
- ${KWSYS_HEADER_DIR}/stl/${header}.hxx
- @ONLY IMMEDIATE)
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
- ELSE()
- SET(KWSYS_STL_HEADER_EXTRA "")
- ENDIF()
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.hxx.in
- ${KWSYS_HEADER_DIR}/stl/${header}
- @ONLY IMMEDIATE)
-
- # Create an install target for the header wrapper.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
-
-# Provide cstddef header.
-CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_cstddef.hxx.in
- ${KWSYS_HEADER_DIR}/cstddef
- @ONLY IMMEDIATE)
-IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/cstddef
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Create streams header wrappers to give standard names by which they
-# may be included.
-FOREACH(header iostream fstream sstream iosfwd)
- # Configure the header wrapper.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_ios_${header}.h.in
- ${KWSYS_HEADER_DIR}/ios/${header}
- @ONLY IMMEDIATE)
-
- # Create an install target for the header wrapper.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/ios/${header}
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/ios
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Build a list of classes and headers we need to implement the
-# selected components. Initialize with required components.
-SET(KWSYS_CLASSES)
-SET(KWSYS_H_FILES Configure) # CastXML needs only this.
-IF(0) # Not used by CastXML
-SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String
- hashtable hash_fun hash_map hash_set
- auto_ptr
- )
-
-# Add selected C++ classes.
-SET(cppclasses
- Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments IOStream FStream SystemInformation
- )
-FOREACH(cpp ${cppclasses})
- IF(KWSYS_USE_${cpp})
- # Use the corresponding class.
- SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
-
- # Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
-ENDIF()
-
-# Add selected C components.
-FOREACH(c
- Process Base64 Encoding FundamentalType MD5 Terminal System String CPU
- )
- IF(KWSYS_USE_${c})
- # Use the corresponding header file.
- SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
-
- # Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
-
-#-----------------------------------------------------------------------------
-# Build a list of sources for the library based on components that are
-# included.
-SET(KWSYS_C_SRCS)
-SET(KWSYS_CXX_SRCS)
-
-# Add the proper sources for this platform's Process implementation.
-IF(KWSYS_USE_Process)
- IF(NOT UNIX)
- # Use the Windows implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
- ELSE()
- # Use the UNIX implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
- ENDIF()
-ENDIF()
-
-# Add selected C sources.
-FOREACH(c Base64 Encoding MD5 Terminal System String)
- IF(KWSYS_USE_${c})
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
- LIST(APPEND KWSYS_C_SRCS ${c}C.c)
- ELSE()
- LIST(APPEND KWSYS_C_SRCS ${c}.c)
- ENDIF()
- ENDIF()
-ENDFOREACH()
-
-# Configure headers of C++ classes and construct the list of sources.
-FOREACH(c ${KWSYS_CLASSES})
- # Add this source to the list of source files for the library.
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
- ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx)
- ENDIF()
-
- # Configure the header for this class.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
- @ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
-
- # Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
-
-# Configure C headers.
-FOREACH(h ${KWSYS_H_FILES})
- # Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
- @ONLY IMMEDIATE)
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
-
- # Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
-
-# Configure other C++ headers.
-FOREACH(h ${KWSYS_HXX_FILES})
- # Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
- @ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
-
- # Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
-
-#-----------------------------------------------------------------------------
-# Add the library with the configured name and list of sources.
-IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
- ADD_LIBRARY(${KWSYS_NAMESPACE} ${KWSYS_LIBRARY_TYPE}
- ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY LABELS ${KWSYS_LABELS_LIB})
- IF(KWSYS_USE_DynamicLoader)
- IF(UNIX)
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
- ENDIF()
- ENDIF()
-
- IF(KWSYS_USE_SystemInformation)
- IF(WIN32)
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ws2_32)
- IF(KWSYS_SYS_HAS_PSAPI)
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} Psapi)
- ENDIF()
- ELSEIF(UNIX)
- IF (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
- # backtrace on FreeBSD is not in libc
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${EXECINFO_LIB})
- ENDIF()
- IF (KWSYS_CXX_HAS_DLADDR)
- # for symbol lookup using dladdr
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
- ENDIF()
- ENDIF()
- ENDIF()
-
- # Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_CXX)
- SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
- ${KWSYS_PROPERTIES_CXX}
- )
- ENDIF()
-
- # Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LIBRARY_RULE})
- ENDIF()
-ENDIF()
-
-# Add a C-only library if requested.
-IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
- ADD_LIBRARY(${KWSYS_NAMESPACE}_c ${KWSYS_LIBRARY_TYPE} ${KWSYS_C_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}_c PROPERTY LABELS ${KWSYS_LABELS_LIB})
-
- # Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_C)
- SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE}_c PROPERTIES
- ${KWSYS_PROPERTIES_C}
- )
- ENDIF()
-
- # Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_NAMESPACE}_c ${KWSYS_INSTALL_LIBRARY_RULE})
- ENDIF()
-ENDIF()
-
-# For building kwsys itself, we use a macro defined on the command
-# line to configure the namespace in the C and C++ source files.
-ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
-
-# Disable deprecation warnings for standard C functions.
-IF(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel"))
- ADD_DEFINITIONS(
- -D_CRT_NONSTDC_NO_DEPRECATE
- -D_CRT_SECURE_NO_DEPRECATE
- -D_CRT_SECURE_NO_WARNINGS
- -D_SCL_SECURE_NO_DEPRECATE
- )
-ENDIF()
-
-IF(WIN32)
- # Help enforce the use of wide Windows apis.
- ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
-ENDIF()
-
-IF(KWSYS_USE_String)
- # Activate code in "String.c". See the comment in the source.
- SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
- COMPILE_FLAGS "-DKWSYS_STRING_C")
-ENDIF()
-
-IF(KWSYS_USE_Encoding)
- # Set default 8 bit encoding in "EndcodingC.c".
- SET_PROPERTY(SOURCE EncodingC.c APPEND PROPERTY COMPILE_DEFINITIONS
- KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Setup testing if not being built as part of another project.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- IF(BUILD_TESTING)
- # Compute the location of executables.
- SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- IF(EXECUTABLE_OUTPUT_PATH)
- SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
- ENDIF()
-
- # C tests
- SET(KWSYS_C_TESTS
- testEncode
- testTerminal
- )
- IF(KWSYS_STANDALONE)
- SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail)
- ENDIF()
- CREATE_TEST_SOURCELIST(
- KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c
- ${KWSYS_C_TESTS}
- )
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_NAMESPACE}_c)
- FOREACH(test ${KWSYS_C_TESTS})
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
-
- # C++ tests
- IF(NOT WATCOM)
- SET(KWSYS_CXX_TESTS
- testAutoPtr
- testHashSTL
- )
- ENDIF()
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
- testIOS
- testSystemTools
- testCommandLineArguments
- testCommandLineArguments1
- )
- IF(KWSYS_STL_HAS_WSTRING)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
- testEncoding
- )
- ENDIF()
- IF(KWSYS_USE_FStream)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
- testFStream
- )
- ENDIF()
- IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
- ENDIF()
- IF(KWSYS_USE_DynamicLoader)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader)
- # If kwsys contains the DynamicLoader, need extra library
- ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_NAMESPACE})
- ENDIF()
- CREATE_TEST_SOURCELIST(
- KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
- ${KWSYS_CXX_TESTS}
- )
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE})
-
- SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- CONFIGURE_FILE(
- ${PROJECT_SOURCE_DIR}/testSystemTools.h.in
- ${PROJECT_BINARY_DIR}/testSystemTools.h)
- INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
-
- IF(CTEST_TEST_KWSYS)
- CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- ENDIF()
-
- SET(KWSYS_TEST_ARGS_testCommandLineArguments
- --another-bool-variable
- --long3=opt
- --set-bool-arg1
- -SSS ken brad bill andy
- --some-bool-variable=true
- --some-double-variable12.5
- --some-int-variable 14
- "--some-string-variable=test string with space"
- --some-multi-argument 5 1 8 3 7 1 3 9 7 1
- -N 12.5 -SS=andy -N 1.31 -N 22
- -SS=bill -BBtrue -SS=brad
- -BBtrue
- -BBfalse
- -SS=ken
- -A
- -C=test
- --long2 hello
- )
- SET(KWSYS_TEST_ARGS_testCommandLineArguments1
- --ignored
- -n 24
- --second-ignored
- "-m=test value"
- third-ignored
- -p
- some junk at the end
- )
- FOREACH(test ${KWSYS_CXX_TESTS})
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
-
- # Process tests.
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_NAMESPACE}_c)
- IF(NOT CYGWIN)
- SET(KWSYS_TEST_PROCESS_7 7)
- ENDIF()
- FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
- ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
- SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
- ENDFOREACH()
-
- # Some Apple compilers produce bad optimizations in this source.
- IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
- SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0)
- ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
- # Tell IBM XL not to warn about our test infinite loop
- SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS -qsuppress=1500-010)
- ENDIF()
-
- # Test SharedForward
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
- ${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward
- ${PROJECT_BINARY_DIR}/testSharedForward.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_NAMESPACE}_c)
- ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
- SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
-
- # Configure some test properties.
- IF(KWSYS_STANDALONE)
- # We expect test to fail
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
- GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
- MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
- ENDIF()
-
- # Set up ctest custom configuration file.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
- ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
-
- # Suppress known consistent failures on buggy systems.
- IF(KWSYS_TEST_BOGUS_FAILURES)
- SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
- ENDIF()
-
- ENDIF()
-ENDIF()
diff --git a/src/kwsys/CONTRIBUTING.rst b/src/kwsys/CONTRIBUTING.rst
deleted file mode 100644
index 960eea4..0000000
--- a/src/kwsys/CONTRIBUTING.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-Contributing to KWSys
-*********************
-
-Overview
-========
-
-KWSys is kept in its own Git repository and shared by several projects
-via copies in their source trees. Changes to KWSys should not be made
-directly in a host project, except perhaps in maintenance branches.
-
-Please visit
-
- http://public.kitware.com/Wiki/KWSys/Git
-
-to contribute changes directly to KWSys upstream. Once changes are
-reviewed, tested, and integrated there then the copies of KWSys within
-dependent projects can be updated to get the changes.
-
-Issues
-======
-
-KWSys has no independent issue tracker. After encountering an issue
-(bug) please try to submit a patch using the above instructions.
-Otherwise please report the issue to the tracker for the project that
-hosts the copy of KWSys in which the problem was found.
-
-License
-=======
-
-We do not require any formal copyright assignment or contributor license
-agreement. Any contributions intentionally sent upstream are presumed
-to be offered under terms of the OSI-approved BSD 3-clause License.
-See `Copyright.txt`_ for details.
-
-.. _`Copyright.txt`: Copyright.txt
diff --git a/src/kwsys/Configure.h.in b/src/kwsys/Configure.h.in
deleted file mode 100644
index 70cf844..0000000
--- a/src/kwsys/Configure.h.in
+++ /dev/null
@@ -1,131 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_Configure_h
-#define @KWSYS_NAMESPACE@_Configure_h
-
-/* If we are building a kwsys .c or .cxx file, let it use the kwsys
- namespace. When not building a kwsys source file these macros are
- temporarily defined inside the headers that use them. */
-#if defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-/* Disable some warnings inside kwsys source files. */
-#if defined(KWSYS_NAMESPACE)
-# if defined(__BORLANDC__)
-# pragma warn -8027 /* function not inlined. */
-# endif
-# if defined(__INTEL_COMPILER)
-# pragma warning (disable: 1572) /* floating-point equality test */
-# endif
-# if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 3970 /* pointer to int conversion */
-# pragma set woff 3968 /* 64 bit conversion */
-# endif
-#endif
-
-/* Whether kwsys namespace is "kwsys". */
-#define @KWSYS_NAMESPACE@_NAME_IS_KWSYS @KWSYS_NAME_IS_KWSYS@
-
-/* Whether Large File Support is requested. */
-#define @KWSYS_NAMESPACE@_LFS_REQUESTED @KWSYS_LFS_REQUESTED@
-
-/* Whether Large File Support is available. */
-#if @KWSYS_NAMESPACE@_LFS_REQUESTED
-# define @KWSYS_NAMESPACE@_LFS_AVAILABLE @KWSYS_LFS_AVAILABLE@
-#endif
-
-/* Setup Large File Support if requested. */
-#if @KWSYS_NAMESPACE@_LFS_REQUESTED
- /* Since LFS is requested this header must be included before system
- headers whether or not LFS is available. */
-# if 0 && (defined(_SYS_TYPES_H) || defined(_SYS_TYPES_INCLUDED))
-# error "@KWSYS_NAMESPACE@/Configure.h must be included before sys/types.h"
-# endif
- /* Enable the large file API if it is available. */
-# if @KWSYS_NAMESPACE@_LFS_AVAILABLE && \
- !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINES)
-# if !defined(_LARGEFILE_SOURCE) && \
- !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE_SOURCE)
-# define _LARGEFILE_SOURCE
-# endif
-# if !defined(_LARGEFILE64_SOURCE) && \
- !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE64_SOURCE)
-# define _LARGEFILE64_SOURCE
-# endif
-# if !defined(_LARGE_FILES) && \
- !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGE_FILES)
-# define _LARGE_FILES
-# endif
-# if !defined(_FILE_OFFSET_BITS) && \
- !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_FILE_OFFSET_BITS)
-# define _FILE_OFFSET_BITS 64
-# endif
-# if 0 && (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64)
-# error "_FILE_OFFSET_BITS must be defined to at least 64"
-# endif
-# endif
-#endif
-
-/* Setup the export macro. */
-#if @KWSYS_BUILD_SHARED@
-# if defined(_WIN32) || defined(__CYGWIN__)
-# if defined(@KWSYS_NAMESPACE@_EXPORTS)
-# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllexport)
-# else
-# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllimport)
-# endif
-# elif __GNUC__ >= 4
-# define @KWSYS_NAMESPACE@_EXPORT __attribute__ ((visibility("default")))
-# else
-# define @KWSYS_NAMESPACE@_EXPORT
-# endif
-#else
-# define @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-/* Enable warnings that are off by default but are useful. */
-#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_ENABLE)
-# if defined(_MSC_VER)
-# pragma warning ( default : 4263 ) /* no override, call convention differs */
-# endif
-#endif
-
-/* Disable warnings that are on by default but occur in valid code. */
-#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE)
-# if defined(_MSC_VER)
-# pragma warning (disable: 4097) /* typedef is synonym for class */
-# pragma warning (disable: 4127) /* conditional expression is constant */
-# pragma warning (disable: 4244) /* possible loss in conversion */
-# pragma warning (disable: 4251) /* missing DLL-interface */
-# pragma warning (disable: 4305) /* truncation from type1 to type2 */
-# pragma warning (disable: 4309) /* truncation of constant value */
-# pragma warning (disable: 4514) /* unreferenced inline function */
-# pragma warning (disable: 4706) /* assignment in conditional expression */
-# pragma warning (disable: 4710) /* function not inlined */
-# pragma warning (disable: 4786) /* identifier truncated in debug info */
-# endif
-#endif
-
-/* MSVC 6.0 in release mode will warn about code it produces with its
- optimizer. Disable the warnings specifically for this
- configuration. Real warnings will be revealed by a debug build or
- by other compilers. */
-#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE_BOGUS)
-# if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG)
-# pragma warning ( disable : 4701 ) /* Variable may be used uninitialized. */
-# pragma warning ( disable : 4702 ) /* Unreachable code. */
-# endif
-#endif
-
-#endif
diff --git a/src/kwsys/Copyright.txt b/src/kwsys/Copyright.txt
deleted file mode 100644
index 1549a7d..0000000
--- a/src/kwsys/Copyright.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-KWSys - Kitware System Library
-Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-* Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-* Neither the names of Kitware, Inc., the Insight Software Consortium,
- nor the names of their contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/kwsys/Encoding.h.in b/src/kwsys/Encoding.h.in
deleted file mode 100644
index 591c5a8..0000000
--- a/src/kwsys/Encoding.h.in
+++ /dev/null
@@ -1,79 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_Encoding_h
-#define @KWSYS_NAMESPACE@_Encoding_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-#include <wchar.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#if !defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysEncoding kwsys_ns(Encoding)
-# define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs)
-# define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide)
-# define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs)
-# define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow)
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-
-/* Convert a narrow string to a wide string.
- On Windows, UTF-8 is assumed, and on other platforms,
- the current locale is assumed.
- */
-kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src, size_t n);
-
-/* Convert a narrow string to a wide string.
- This can return NULL if the conversion fails. */
-kwsysEXPORT wchar_t* kwsysEncoding_DupToWide(const char* src);
-
-
-/* Convert a wide string to a narrow string.
- On Windows, UTF-8 is assumed, and on other platforms,
- the current locale is assumed. */
-kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src, size_t n);
-
-/* Convert a wide string to a narrow string.
- This can return NULL if the conversion fails. */
-kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str);
-
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsys .c or .cxx file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_NAMESPACE)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysEncoding
-# undef kwsysEncoding_mbstowcs
-# undef kwsysEncoding_DupToWide
-# undef kwsysEncoding_wcstombs
-# undef kwsysEncoding_DupToNarrow
-# endif
-#endif
-
-#endif
diff --git a/src/kwsys/EncodingC.c b/src/kwsys/EncodingC.c
deleted file mode 100644
index 32b9bff..0000000
--- a/src/kwsys/EncodingC.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(Encoding.h)
-
-/* Work-around CMake dependency scanning limitation. This must
- duplicate the above list of headers. */
-#if 0
-# include "Encoding.h.in"
-#endif
-
-#include <stdlib.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* str, size_t n)
-{
- if(str == 0)
- {
- return (size_t)-1;
- }
-#ifdef _WIN32
- return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0,
- str, -1, dest, (int)n) - 1;
-#else
- return mbstowcs(dest, str, n);
-#endif
-}
-
-wchar_t* kwsysEncoding_DupToWide(const char* str)
-{
- wchar_t* ret = NULL;
- size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1;
- if(length > 0)
- {
- ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
- if(ret)
- {
- ret[0] = 0;
- kwsysEncoding_mbstowcs(ret, str, length);
- }
- }
- return ret;
-}
-
-size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* str, size_t n)
-{
- if(str == 0)
- {
- return (size_t)-1;
- }
-#ifdef _WIN32
- return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1,
- dest, (int)n, NULL, NULL) - 1;
-#else
- return wcstombs(dest, str, n);
-#endif
-}
-
-char* kwsysEncoding_DupToNarrow(const wchar_t* str)
-{
- char* ret = NULL;
- size_t length = kwsysEncoding_wcstombs(0, str, 0) + 1;
- if(length > 0)
- {
- ret = (char*)malloc(length);
- if(ret)
- {
- ret[0] = 0;
- kwsysEncoding_wcstombs(ret, str, length);
- }
- }
- return ret;
-}
diff --git a/src/kwsys/Process.h.in b/src/kwsys/Process.h.in
deleted file mode 100644
index c5ebc97..0000000
--- a/src/kwsys/Process.h.in
+++ /dev/null
@@ -1,462 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_Process_h
-#define @KWSYS_NAMESPACE@_Process_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#if !defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysProcess kwsys_ns(Process)
-# define kwsysProcess_s kwsys_ns(Process_s)
-# define kwsysProcess_New kwsys_ns(Process_New)
-# define kwsysProcess_Delete kwsys_ns(Process_Delete)
-# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
-# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
-# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
-# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
-# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
-# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
-# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
-# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
-# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
-# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
-# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
-# define kwsysProcess_Option_CreateProcessGroup kwsys_ns(Process_Option_CreateProcessGroup)
-# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
-# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
-# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
-# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
-# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
-# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
-# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
-# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
-# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
-# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
-# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
-# define kwsysProcess_GetState kwsys_ns(Process_GetState)
-# define kwsysProcess_State_e kwsys_ns(Process_State_e)
-# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
-# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
-# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
-# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
-# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
-# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
-# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
-# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
-# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
-# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
-# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
-# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
-# define kwsysProcess_Execute kwsys_ns(Process_Execute)
-# define kwsysProcess_Disown kwsys_ns(Process_Disown)
-# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
-# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
-# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
-# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
-# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
-# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
-# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
-# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
-# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
-# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
-# define kwsysProcess_Kill kwsys_ns(Process_Kill)
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/**
- * Process control data structure.
- */
-typedef struct kwsysProcess_s kwsysProcess;
-
-/* Platform-specific pipe handle type. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-typedef void* kwsysProcess_Pipe_Handle;
-#else
-typedef int kwsysProcess_Pipe_Handle;
-#endif
-
-/**
- * Create a new Process instance.
- */
-kwsysEXPORT kwsysProcess* kwsysProcess_New(void);
-
-/**
- * Delete an existing Process instance. If the instance is currently
- * executing a process, this blocks until the process terminates.
- */
-kwsysEXPORT void kwsysProcess_Delete(kwsysProcess* cp);
-
-/**
- * Set the command line to be executed. Argument is an array of
- * pointers to the command and each argument. The array must end with
- * a NULL pointer. Any previous command lines are removed. Returns
- * 1 for success and 0 otherwise.
- */
-kwsysEXPORT int kwsysProcess_SetCommand(kwsysProcess* cp,
- char const* const* command);
-
-/**
- * Add a command line to be executed. Argument is an array of
- * pointers to the command and each argument. The array must end with
- * a NULL pointer. If this is not the first command added, its
- * standard input will be connected to the standard output of the
- * previous command. Returns 1 for success and 0 otherwise.
- */
-kwsysEXPORT int kwsysProcess_AddCommand(kwsysProcess* cp,
- char const* const* command);
-
-/**
- * Set the timeout in seconds for the child process. The timeout
- * period begins when the child is executed. If the child has not
- * terminated when the timeout expires, it will be killed. A
- * non-positive (<= 0) value will disable the timeout.
- */
-kwsysEXPORT void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout);
-
-/**
- * Set the working directory for the child process. The working
- * directory can be absolute or relative to the current directory.
- * Returns 1 for success and 0 for failure.
- */
-kwsysEXPORT int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp,
- const char* dir);
-
-/**
- * Set the name of a file to be attached to the given pipe. Returns 1
- * for success and 0 for failure.
- */
-kwsysEXPORT int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe,
- const char* file);
-
-/**
- * Set whether the given pipe in the child is shared with the parent
- * process. The default is no for Pipe_STDOUT and Pipe_STDERR and yes
- * for Pipe_STDIN.
- */
-kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe,
- int shared);
-
-/**
- * Specify a platform-specific native pipe for use as one of the child
- * interface pipes. The native pipe is specified by an array of two
- * descriptors or handles. The first entry in the array (index 0)
- * should be the read end of the pipe. The second entry in the array
- * (index 1) should be the write end of the pipe. If a null pointer
- * is given the option will be disabled.
- *
- * For Pipe_STDIN the native pipe is connected to the first child in
- * the pipeline as its stdin. After the children are created the
- * write end of the pipe will be closed in the child process and the
- * read end will be closed in the parent process.
- *
- * For Pipe_STDOUT and Pipe_STDERR the pipe is connected to the last
- * child as its stdout or stderr. After the children are created the
- * write end of the pipe will be closed in the parent process and the
- * read end will be closed in the child process.
- */
-kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
- kwsysProcess_Pipe_Handle p[2]);
-
-/**
- * Get/Set a possibly platform-specific option. Possible options are:
- *
- * kwsysProcess_Option_Detach = Whether to detach the process.
- * 0 = No (default)
- * 1 = Yes
- *
- * kwsysProcess_Option_HideWindow = Whether to hide window on Windows.
- * 0 = No (default)
- * 1 = Yes
- *
- * kwsysProcess_Option_MergeOutput = Whether to merge stdout/stderr.
- * No content will be returned as stderr.
- * Any actual stderr will be on stdout.
- * 0 = No (default)
- * 1 = Yes
- *
- * kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand
- * should treat the first argument
- * as a verbatim command line
- * and ignore the rest of the arguments.
- * 0 = No (default)
- * 1 = Yes
- *
- * kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a
- * new process group. This is
- * useful if you want to send Ctrl+C
- * to the process. On UNIX, also
- * places the process in a new
- * session.
- * 0 = No (default)
- * 1 = Yes
- */
-kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId);
-kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId,
- int value);
-enum kwsysProcess_Option_e
-{
- kwsysProcess_Option_HideWindow,
- kwsysProcess_Option_Detach,
- kwsysProcess_Option_MergeOutput,
- kwsysProcess_Option_Verbatim,
- kwsysProcess_Option_CreateProcessGroup
-};
-
-/**
- * Get the current state of the Process instance. Possible states are:
- *
- * kwsysProcess_State_Starting = Execute has not yet been called.
- * kwsysProcess_State_Error = Error administrating the child process.
- * kwsysProcess_State_Exception = Child process exited abnormally.
- * kwsysProcess_State_Executing = Child process is currently running.
- * kwsysProcess_State_Exited = Child process exited normally.
- * kwsysProcess_State_Expired = Child process's timeout expired.
- * kwsysProcess_State_Killed = Child process terminated by Kill method.
- * kwsysProcess_State_Disowned = Child is no longer managed by this object.
- */
-kwsysEXPORT int kwsysProcess_GetState(kwsysProcess* cp);
-enum kwsysProcess_State_e
-{
- kwsysProcess_State_Starting,
- kwsysProcess_State_Error,
- kwsysProcess_State_Exception,
- kwsysProcess_State_Executing,
- kwsysProcess_State_Exited,
- kwsysProcess_State_Expired,
- kwsysProcess_State_Killed,
- kwsysProcess_State_Disowned
-};
-
-/**
- * When GetState returns "Exception", this method returns a
- * platform-independent description of the exceptional behavior that
- * caused the child to terminate abnormally. Possible exceptions are:
- *
- * kwsysProcess_Exception_None = No exceptional behavior occurred.
- * kwsysProcess_Exception_Fault = Child crashed with a memory fault.
- * kwsysProcess_Exception_Illegal = Child crashed with an illegal instruction.
- * kwsysProcess_Exception_Interrupt = Child was interrupted by user (Cntl-C/Break).
- * kwsysProcess_Exception_Numerical = Child crashed with a numerical exception.
- * kwsysProcess_Exception_Other = Child terminated for another reason.
- */
-kwsysEXPORT int kwsysProcess_GetExitException(kwsysProcess* cp);
-enum kwsysProcess_Exception_e
-{
- kwsysProcess_Exception_None,
- kwsysProcess_Exception_Fault,
- kwsysProcess_Exception_Illegal,
- kwsysProcess_Exception_Interrupt,
- kwsysProcess_Exception_Numerical,
- kwsysProcess_Exception_Other
-};
-
-/**
- * When GetState returns "Exited" or "Exception", this method returns
- * the platform-specific raw exit code of the process. UNIX platforms
- * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access
- * this value. Windows users should compare the value to the various
- * EXCEPTION_* values.
- *
- * If GetState returns "Exited", use GetExitValue to get the
- * platform-independent child return value.
- */
-kwsysEXPORT int kwsysProcess_GetExitCode(kwsysProcess* cp);
-
-/**
- * When GetState returns "Exited", this method returns the child's
- * platform-independent exit code (such as the value returned by the
- * child's main).
- */
-kwsysEXPORT int kwsysProcess_GetExitValue(kwsysProcess* cp);
-
-/**
- * When GetState returns "Error", this method returns a string
- * describing the problem. Otherwise, it returns NULL.
- */
-kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp);
-
-/**
- * When GetState returns "Exception", this method returns a string
- * describing the problem. Otherwise, it returns NULL.
- */
-kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp);
-
-/**
- * Start executing the child process.
- */
-kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp);
-
-/**
- * Stop management of a detached child process. This closes any pipes
- * being read. If the child was not created with the
- * kwsysProcess_Option_Detach option, this method does nothing. This
- * is because disowning a non-detached process will cause the child
- * exit signal to be left unhandled until this process exits.
- */
-kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp);
-
-/**
- * Block until data are available on a pipe, a timeout expires, or the
- * child process terminates. Arguments are as follows:
- *
- * data = If data are read, the pointer to which this points is
- * set to point to the data.
- * length = If data are read, the integer to which this points is
- * set to the length of the data read.
- * timeout = Specifies the maximum time this call may block. Upon
- * return after reading data, the time elapsed is subtracted
- * from the timeout value. If this timeout expires, the
- * value is set to 0. A NULL pointer passed for this argument
- * indicates no timeout for the call. A negative or zero
- * value passed for this argument may be used for polling
- * and will always return immediately.
- *
- * Return value will be one of:
- *
- * Pipe_None = No more data will be available from the child process,
- * ( == 0) or no process has been executed. WaitForExit should
- * be called to wait for the process to terminate.
- * Pipe_STDOUT = Data have been read from the child's stdout pipe.
- * Pipe_STDERR = Data have been read from the child's stderr pipe.
- * Pipe_Timeout = No data available within timeout specified for the
- * call. Time elapsed has been subtracted from timeout
- * argument.
- */
-kwsysEXPORT int kwsysProcess_WaitForData(kwsysProcess* cp, char** data,
- int* length, double* timeout);
-enum kwsysProcess_Pipes_e
-{
- kwsysProcess_Pipe_None,
- kwsysProcess_Pipe_STDIN,
- kwsysProcess_Pipe_STDOUT,
- kwsysProcess_Pipe_STDERR,
- kwsysProcess_Pipe_Timeout=255
-};
-
-/**
- * Block until the child process terminates or the given timeout
- * expires. If no process is running, returns immediatly. The
- * argument is:
- *
- * timeout = Specifies the maximum time this call may block. Upon
- * returning due to child termination, the elapsed time
- * is subtracted from the given value. A NULL pointer
- * passed for this argument indicates no timeout for the
- * call.
- *
- * Return value will be one of:
- *
- * 0 = Child did not terminate within timeout specified for
- * the call. Time elapsed has been subtracted from timeout
- * argument.
- * 1 = Child has terminated or was not running.
- */
-kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout);
-
-/**
- * Interrupt the process group for the child process that is currently
- * running by sending it the appropriate operating-system specific signal.
- * The caller should call WaitForExit after this returns to wait for the
- * child to terminate.
- *
- * WARNING: If you didn't specify kwsysProcess_Option_CreateProcessGroup,
- * you will interrupt your own process group.
- */
-kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp);
-
-/**
- * Forcefully terminate the child process that is currently running.
- * The caller should call WaitForExit after this returns to wait for
- * the child to terminate.
- */
-kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsys .c or .cxx file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_NAMESPACE)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysProcess
-# undef kwsysProcess_s
-# undef kwsysProcess_New
-# undef kwsysProcess_Delete
-# undef kwsysProcess_SetCommand
-# undef kwsysProcess_AddCommand
-# undef kwsysProcess_SetTimeout
-# undef kwsysProcess_SetWorkingDirectory
-# undef kwsysProcess_SetPipeFile
-# undef kwsysProcess_SetPipeNative
-# undef kwsysProcess_SetPipeShared
-# undef kwsysProcess_Option_Detach
-# undef kwsysProcess_Option_HideWindow
-# undef kwsysProcess_Option_MergeOutput
-# undef kwsysProcess_Option_Verbatim
-# undef kwsysProcess_Option_CreateProcessGroup
-# undef kwsysProcess_GetOption
-# undef kwsysProcess_SetOption
-# undef kwsysProcess_Option_e
-# undef kwsysProcess_State_Starting
-# undef kwsysProcess_State_Error
-# undef kwsysProcess_State_Exception
-# undef kwsysProcess_State_Executing
-# undef kwsysProcess_State_Exited
-# undef kwsysProcess_State_Expired
-# undef kwsysProcess_State_Killed
-# undef kwsysProcess_State_Disowned
-# undef kwsysProcess_GetState
-# undef kwsysProcess_State_e
-# undef kwsysProcess_Exception_None
-# undef kwsysProcess_Exception_Fault
-# undef kwsysProcess_Exception_Illegal
-# undef kwsysProcess_Exception_Interrupt
-# undef kwsysProcess_Exception_Numerical
-# undef kwsysProcess_Exception_Other
-# undef kwsysProcess_GetExitException
-# undef kwsysProcess_Exception_e
-# undef kwsysProcess_GetExitCode
-# undef kwsysProcess_GetExitValue
-# undef kwsysProcess_GetErrorString
-# undef kwsysProcess_GetExceptionString
-# undef kwsysProcess_Execute
-# undef kwsysProcess_Disown
-# undef kwsysProcess_WaitForData
-# undef kwsysProcess_Pipes_e
-# undef kwsysProcess_Pipe_None
-# undef kwsysProcess_Pipe_STDIN
-# undef kwsysProcess_Pipe_STDOUT
-# undef kwsysProcess_Pipe_STDERR
-# undef kwsysProcess_Pipe_Timeout
-# undef kwsysProcess_Pipe_Handle
-# undef kwsysProcess_WaitForExit
-# undef kwsysProcess_Interrupt
-# undef kwsysProcess_Kill
-# endif
-#endif
-
-#endif
diff --git a/src/kwsys/ProcessUNIX.c b/src/kwsys/ProcessUNIX.c
deleted file mode 100644
index 6d9b109..0000000
--- a/src/kwsys/ProcessUNIX.c
+++ /dev/null
@@ -1,3058 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(System.h)
-
-/* Work-around CMake dependency scanning limitation. This must
- duplicate the above list of headers. */
-#if 0
-# include "Process.h.in"
-# include "System.h.in"
-#endif
-
-/*
-
-Implementation for UNIX
-
-On UNIX, a child process is forked to exec the program. Three output
-pipes are read by the parent process using a select call to block
-until data are ready. Two of the pipes are stdout and stderr for the
-child. The third is a special pipe populated by a signal handler to
-indicate that a child has terminated. This is used in conjunction
-with the timeout on the select call to implement a timeout for program
-even when it closes stdout and stderr and at the same time avoiding
-races.
-
-*/
-
-
-/*
-
-TODO:
-
-We cannot create the pipeline of processes in suspended states. How
-do we cleanup processes already started when one fails to load? Right
-now we are just killing them, which is probably not the right thing to
-do.
-
-*/
-
-#if defined(__CYGWIN__)
-/* Increase the file descriptor limit for select() before including
- related system headers. (Default: 64) */
-# define FD_SETSIZE 16384
-#endif
-
-#include <stddef.h> /* ptrdiff_t */
-#include <stdio.h> /* snprintf */
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* strdup, strerror, memset */
-#include <sys/time.h> /* struct timeval */
-#include <sys/types.h> /* pid_t, fd_set */
-#include <sys/wait.h> /* waitpid */
-#include <sys/stat.h> /* open mode */
-#include <unistd.h> /* pipe, close, fork, execvp, select, _exit */
-#include <fcntl.h> /* fcntl */
-#include <errno.h> /* errno */
-#include <time.h> /* gettimeofday */
-#include <signal.h> /* sigaction */
-#include <dirent.h> /* DIR, dirent */
-#include <ctype.h> /* isspace */
-#include <assert.h> /* assert */
-
-#if defined(__VMS)
-# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
-#else
-# define KWSYSPE_VMS_NONBLOCK
-#endif
-
-#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
-typedef ptrdiff_t kwsysProcess_ptrdiff_t;
-#else
-typedef int kwsysProcess_ptrdiff_t;
-#endif
-
-#if defined(KWSYS_C_HAS_SSIZE_T) && KWSYS_C_HAS_SSIZE_T
-typedef ssize_t kwsysProcess_ssize_t;
-#else
-typedef int kwsysProcess_ssize_t;
-#endif
-
-#if defined(__BEOS__) && !defined(__ZETA__)
-/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
-# include <be/kernel/OS.h>
-static inline void kwsysProcess_usleep(unsigned int msec)
-{
- snooze(msec);
-}
-#else
-# define kwsysProcess_usleep usleep
-#endif
-
-/*
- * BeOS's select() works like WinSock: it's for networking only, and
- * doesn't work with Unix file handles...socket and file handles are
- * different namespaces (the same descriptor means different things in
- * each context!)
- *
- * So on Unix-like systems where select() is flakey, we'll set the
- * pipes' file handles to be non-blocking and just poll them directly
- * without select().
- */
-#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__)
-# define KWSYSPE_USE_SELECT 1
-#endif
-
-/* Some platforms do not have siginfo on their signal handlers. */
-#if defined(SA_SIGINFO) && !defined(__BEOS__)
-# define KWSYSPE_USE_SIGINFO 1
-#endif
-
-/* The number of pipes for the child's output. The standard stdout
- and stderr pipes are the first two. One more pipe is used to
- detect when the child process has terminated. The third pipe is
- not given to the child process, so it cannot close it until it
- terminates. */
-#define KWSYSPE_PIPE_COUNT 3
-#define KWSYSPE_PIPE_STDOUT 0
-#define KWSYSPE_PIPE_STDERR 1
-#define KWSYSPE_PIPE_SIGNAL 2
-
-/* The maximum amount to read from a pipe at a time. */
-#define KWSYSPE_PIPE_BUFFER_SIZE 1024
-
-/* Keep track of times using a signed representation. Switch to the
- native (possibly unsigned) representation only when calling native
- functions. */
-typedef struct timeval kwsysProcessTimeNative;
-typedef struct kwsysProcessTime_s kwsysProcessTime;
-struct kwsysProcessTime_s
-{
- long tv_sec;
- long tv_usec;
-};
-
-typedef struct kwsysProcessCreateInformation_s
-{
- int StdIn;
- int StdOut;
- int StdErr;
- int ErrorPipe[2];
-} kwsysProcessCreateInformation;
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessVolatileFree(volatile void* p);
-static int kwsysProcessInitialize(kwsysProcess* cp);
-static void kwsysProcessCleanup(kwsysProcess* cp, int error);
-static void kwsysProcessCleanupDescriptor(int* pfd);
-static void kwsysProcessClosePipes(kwsysProcess* cp);
-static int kwsysProcessSetNonBlocking(int fd);
-static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
- kwsysProcessCreateInformation* si);
-static void kwsysProcessDestroy(kwsysProcess* cp);
-static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
-static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
- kwsysProcessTime* timeoutTime);
-static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
- kwsysProcessTimeNative* timeoutLength,
- int zeroIsExpired);
-static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
-static double kwsysProcessTimeToDouble(kwsysProcessTime t);
-static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
-static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
-static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
-static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
-static void kwsysProcessSetExitException(kwsysProcess* cp, int sig);
-static void kwsysProcessChildErrorExit(int errorPipe);
-static void kwsysProcessRestoreDefaultSignalHandlers(void);
-static pid_t kwsysProcessFork(kwsysProcess* cp,
- kwsysProcessCreateInformation* si);
-static void kwsysProcessKill(pid_t process_id);
-#if defined(__VMS)
-static int kwsysProcessSetVMSFeature(const char* name, int value);
-#endif
-static int kwsysProcessesAdd(kwsysProcess* cp);
-static void kwsysProcessesRemove(kwsysProcess* cp);
-#if KWSYSPE_USE_SIGINFO
-static void kwsysProcessesSignalHandler(int signum, siginfo_t* info,
- void* ucontext);
-#else
-static void kwsysProcessesSignalHandler(int signum);
-#endif
-
-/*--------------------------------------------------------------------------*/
-/* Structure containing data used to implement the child's execution. */
-struct kwsysProcess_s
-{
- /* The command lines to execute. */
- char*** Commands;
- volatile int NumberOfCommands;
-
- /* Descriptors for the read ends of the child's output pipes and
- the signal pipe. */
- int PipeReadEnds[KWSYSPE_PIPE_COUNT];
-
- /* Descriptors for the child's ends of the pipes.
- Used temporarily during process creation. */
- int PipeChildStd[3];
-
- /* Write descriptor for child termination signal pipe. */
- int SignalPipe;
-
- /* Buffer for pipe data. */
- char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
-
- /* Process IDs returned by the calls to fork. Everything is volatile
- because the signal handler accesses them. You must be very careful
- when reaping PIDs or modifying this array to avoid race conditions. */
- volatile pid_t* volatile ForkPIDs;
-
- /* Flag for whether the children were terminated by a faild select. */
- int SelectError;
-
- /* The timeout length. */
- double Timeout;
-
- /* The working directory for the process. */
- char* WorkingDirectory;
-
- /* Whether to create the child as a detached process. */
- int OptionDetach;
-
- /* Whether the child was created as a detached process. */
- int Detached;
-
- /* Whether to treat command lines as verbatim. */
- int Verbatim;
-
- /* Whether to merge stdout/stderr of the child. */
- int MergeOutput;
-
- /* Whether to create the process in a new process group. */
- volatile sig_atomic_t CreateProcessGroup;
-
- /* Time at which the child started. Negative for no timeout. */
- kwsysProcessTime StartTime;
-
- /* Time at which the child will timeout. Negative for no timeout. */
- kwsysProcessTime TimeoutTime;
-
- /* Flag for whether the timeout expired. */
- int TimeoutExpired;
-
- /* The number of pipes left open during execution. */
- int PipesLeft;
-
-#if KWSYSPE_USE_SELECT
- /* File descriptor set for call to select. */
- fd_set PipeSet;
-#endif
-
- /* The number of children still executing. */
- int CommandsLeft;
-
- /* The current status of the child process. Must be atomic because
- the signal handler checks this to avoid a race. */
- volatile sig_atomic_t State;
-
- /* The exceptional behavior that terminated the child process, if
- * any. */
- int ExitException;
-
- /* The exit code of the child process. */
- int ExitCode;
-
- /* The exit value of the child process, if any. */
- int ExitValue;
-
- /* Whether the process was killed. */
- volatile sig_atomic_t Killed;
-
- /* Buffer for error message in case of failure. */
- char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
-
- /* Description for the ExitException. */
- char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
-
- /* The exit codes of each child process in the pipeline. */
- int* CommandExitCodes;
-
- /* Name of files to which stdin and stdout pipes are attached. */
- char* PipeFileSTDIN;
- char* PipeFileSTDOUT;
- char* PipeFileSTDERR;
-
- /* Whether each pipe is shared with the parent process. */
- int PipeSharedSTDIN;
- int PipeSharedSTDOUT;
- int PipeSharedSTDERR;
-
- /* Native pipes provided by the user. */
- int PipeNativeSTDIN[2];
- int PipeNativeSTDOUT[2];
- int PipeNativeSTDERR[2];
-
- /* The real working directory of this process. */
- int RealWorkingDirectoryLength;
- char* RealWorkingDirectory;
-};
-
-/*--------------------------------------------------------------------------*/
-kwsysProcess* kwsysProcess_New(void)
-{
- /* Allocate a process control structure. */
- kwsysProcess* cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
- if(!cp)
- {
- return 0;
- }
- memset(cp, 0, sizeof(kwsysProcess));
-
- /* Share stdin with the parent process by default. */
- cp->PipeSharedSTDIN = 1;
-
- /* No native pipes by default. */
- cp->PipeNativeSTDIN[0] = -1;
- cp->PipeNativeSTDIN[1] = -1;
- cp->PipeNativeSTDOUT[0] = -1;
- cp->PipeNativeSTDOUT[1] = -1;
- cp->PipeNativeSTDERR[0] = -1;
- cp->PipeNativeSTDERR[1] = -1;
-
- /* Set initial status. */
- cp->State = kwsysProcess_State_Starting;
-
- return cp;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Delete(kwsysProcess* cp)
-{
- /* Make sure we have an instance. */
- if(!cp)
- {
- return;
- }
-
- /* If the process is executing, wait for it to finish. */
- if(cp->State == kwsysProcess_State_Executing)
- {
- if(cp->Detached)
- {
- kwsysProcess_Disown(cp);
- }
- else
- {
- kwsysProcess_WaitForExit(cp, 0);
- }
- }
-
- /* Free memory. */
- kwsysProcess_SetCommand(cp, 0);
- kwsysProcess_SetWorkingDirectory(cp, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if(cp->CommandExitCodes)
- {
- free(cp->CommandExitCodes);
- }
- free(cp);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
-{
- int i;
- if(!cp)
- {
- return 0;
- }
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- char** c = cp->Commands[i];
- while(*c)
- {
- free(*c++);
- }
- free(cp->Commands[i]);
- }
- cp->NumberOfCommands = 0;
- if(cp->Commands)
- {
- free(cp->Commands);
- cp->Commands = 0;
- }
- if(command)
- {
- return kwsysProcess_AddCommand(cp, command);
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
-{
- int newNumberOfCommands;
- char*** newCommands;
-
- /* Make sure we have a command to add. */
- if(!cp || !command || !*command)
- {
- return 0;
- }
-
- /* Allocate a new array for command pointers. */
- newNumberOfCommands = cp->NumberOfCommands + 1;
- if(!(newCommands =
- (char***)malloc(sizeof(char**) *(size_t)(newNumberOfCommands))))
- {
- /* Out of memory. */
- return 0;
- }
-
- /* Copy any existing commands into the new array. */
- {
- int i;
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- newCommands[i] = cp->Commands[i];
- }
- }
-
- /* Add the new command. */
- if(cp->Verbatim)
- {
- /* In order to run the given command line verbatim we need to
- parse it. */
- newCommands[cp->NumberOfCommands] =
- kwsysSystem_Parse_CommandForUnix(*command, 0);
- if(!newCommands[cp->NumberOfCommands] ||
- !newCommands[cp->NumberOfCommands][0])
- {
- /* Out of memory or no command parsed. */
- free(newCommands);
- return 0;
- }
- }
- else
- {
- /* Copy each argument string individually. */
- char const* const* c = command;
- kwsysProcess_ptrdiff_t n = 0;
- kwsysProcess_ptrdiff_t i = 0;
- while(*c++);
- n = c - command - 1;
- newCommands[cp->NumberOfCommands] =
- (char**)malloc((size_t)(n+1)*sizeof(char*));
- if(!newCommands[cp->NumberOfCommands])
- {
- /* Out of memory. */
- free(newCommands);
- return 0;
- }
- for(i=0; i < n; ++i)
- {
- assert(command[i]); /* Quiet Clang scan-build. */
- newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
- if(!newCommands[cp->NumberOfCommands][i])
- {
- break;
- }
- }
- if(i < n)
- {
- /* Out of memory. */
- for(;i > 0; --i)
- {
- free(newCommands[cp->NumberOfCommands][i-1]);
- }
- free(newCommands);
- return 0;
- }
- newCommands[cp->NumberOfCommands][n] = 0;
- }
-
- /* Successfully allocated new command array. Free the old array. */
- free(cp->Commands);
- cp->Commands = newCommands;
- cp->NumberOfCommands = newNumberOfCommands;
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
-{
- if(!cp)
- {
- return;
- }
- cp->Timeout = timeout;
- if(cp->Timeout < 0)
- {
- cp->Timeout = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
-{
- if(!cp)
- {
- return 0;
- }
- if(cp->WorkingDirectory == dir)
- {
- return 1;
- }
- if(cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0)
- {
- return 1;
- }
- if(cp->WorkingDirectory)
- {
- free(cp->WorkingDirectory);
- cp->WorkingDirectory = 0;
- }
- if(dir)
- {
- cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
- if(!cp->WorkingDirectory)
- {
- return 0;
- }
- strcpy(cp->WorkingDirectory, dir);
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
-{
- char** pfile;
- if(!cp)
- {
- return 0;
- }
- switch(prPipe)
- {
- case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
- case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
- case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
- default: return 0;
- }
- if(*pfile)
- {
- free(*pfile);
- *pfile = 0;
- }
- if(file)
- {
- *pfile = (char*)malloc(strlen(file)+1);
- if(!*pfile)
- {
- return 0;
- }
- strcpy(*pfile, file);
- }
-
- /* If we are redirecting the pipe, do not share it or use a native
- pipe. */
- if(*pfile)
- {
- kwsysProcess_SetPipeNative(cp, prPipe, 0);
- kwsysProcess_SetPipeShared(cp, prPipe, 0);
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared)
-{
- if(!cp)
- {
- return;
- }
-
- switch(prPipe)
- {
- case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
- case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
- case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
- default: return;
- }
-
- /* If we are sharing the pipe, do not redirect it to a file or use a
- native pipe. */
- if(shared)
- {
- kwsysProcess_SetPipeFile(cp, prPipe, 0);
- kwsysProcess_SetPipeNative(cp, prPipe, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
-{
- int* pPipeNative = 0;
-
- if(!cp)
- {
- return;
- }
-
- switch(prPipe)
- {
- case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
- case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
- case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
- default: return;
- }
-
- /* Copy the native pipe descriptors provided. */
- if(p)
- {
- pPipeNative[0] = p[0];
- pPipeNative[1] = p[1];
- }
- else
- {
- pPipeNative[0] = -1;
- pPipeNative[1] = -1;
- }
-
- /* If we are using a native pipe, do not share it or redirect it to
- a file. */
- if(p)
- {
- kwsysProcess_SetPipeFile(cp, prPipe, 0);
- kwsysProcess_SetPipeShared(cp, prPipe, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
-{
- if(!cp)
- {
- return 0;
- }
-
- switch(optionId)
- {
- case kwsysProcess_Option_Detach: return cp->OptionDetach;
- case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
- case kwsysProcess_Option_Verbatim: return cp->Verbatim;
- case kwsysProcess_Option_CreateProcessGroup:
- return cp->CreateProcessGroup;
- default: return 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
-{
- if(!cp)
- {
- return;
- }
-
- switch(optionId)
- {
- case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
- case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
- case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
- case kwsysProcess_Option_CreateProcessGroup:
- cp->CreateProcessGroup = value; break;
- default: break;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetState(kwsysProcess* cp)
-{
- return cp? cp->State : kwsysProcess_State_Error;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitException(kwsysProcess* cp)
-{
- return cp? cp->ExitException : kwsysProcess_Exception_Other;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitCode(kwsysProcess* cp)
-{
- return cp? cp->ExitCode : 0;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitValue(kwsysProcess* cp)
-{
- return cp? cp->ExitValue : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
-{
- if(!cp)
- {
- return "Process management structure could not be allocated";
- }
- else if(cp->State == kwsysProcess_State_Error)
- {
- return cp->ErrorMessage;
- }
- return "Success";
-}
-
-/*--------------------------------------------------------------------------*/
-const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
-{
- if(!cp)
- {
- return "GetExceptionString called with NULL process management structure";
- }
- else if(cp->State == kwsysProcess_State_Exception)
- {
- return cp->ExitExceptionString;
- }
- return "No exception";
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Execute(kwsysProcess* cp)
-{
- int i;
-
- /* Do not execute a second copy simultaneously. */
- if(!cp || cp->State == kwsysProcess_State_Executing)
- {
- return;
- }
-
- /* Make sure we have something to run. */
- if(cp->NumberOfCommands < 1)
- {
- strcpy(cp->ErrorMessage, "No command");
- cp->State = kwsysProcess_State_Error;
- return;
- }
-
- /* Initialize the control structure for a new process. */
- if(!kwsysProcessInitialize(cp))
- {
- strcpy(cp->ErrorMessage, "Out of memory");
- cp->State = kwsysProcess_State_Error;
- return;
- }
-
-#if defined(__VMS)
- /* Make sure pipes behave like streams on VMS. */
- if(!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-#endif
-
- /* Save the real working directory of this process and change to
- the working directory for the child processes. This is needed
- to make pipe file paths evaluate correctly. */
- if(cp->WorkingDirectory)
- {
- int r;
- if(!getcwd(cp->RealWorkingDirectory,
- (size_t)(cp->RealWorkingDirectoryLength)))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Some platforms specify that the chdir call may be
- interrupted. Repeat the call until it finishes. */
- while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
- if(r < 0)
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- /* If not running a detached child, add this object to the global
- set of process objects that wish to be notified when a child
- exits. */
- if(!cp->OptionDetach)
- {
- if(!kwsysProcessesAdd(cp))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- /* Setup the stdin pipe for the first process. */
- if(cp->PipeFileSTDIN)
- {
- /* Open a file for the child's stdin to read. */
- cp->PipeChildStd[0] = open(cp->PipeFileSTDIN, O_RDONLY);
- if(cp->PipeChildStd[0] < 0)
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Set close-on-exec flag on the pipe's end. */
- if(fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0)
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
- else if(cp->PipeSharedSTDIN)
- {
- cp->PipeChildStd[0] = 0;
- }
- else if(cp->PipeNativeSTDIN[0] >= 0)
- {
- cp->PipeChildStd[0] = cp->PipeNativeSTDIN[0];
-
- /* Set close-on-exec flag on the pipe's ends. The read end will
- be dup2-ed into the stdin descriptor after the fork but before
- the exec. */
- if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
- else
- {
- cp->PipeChildStd[0] = -1;
- }
-
- /* Create the output pipe for the last process.
- We always create this so the pipe can be passed to select even if
- it will report closed immediately. */
- {
- /* Create the pipe. */
- int p[2];
- if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Store the pipe. */
- cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0];
- cp->PipeChildStd[1] = p[1];
-
- /* Set close-on-exec flag on the pipe's ends. */
- if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Set to non-blocking in case select lies, or for the polling
- implementation. */
- if(!kwsysProcessSetNonBlocking(p[0]))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- if (cp->PipeFileSTDOUT)
- {
- /* Use a file for stdout. */
- if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
- cp->PipeFileSTDOUT))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
- else if (cp->PipeSharedSTDOUT)
- {
- /* Use the parent stdout. */
- kwsysProcessCleanupDescriptor(&cp->PipeChildStd[1]);
- cp->PipeChildStd[1] = 1;
- }
- else if (cp->PipeNativeSTDOUT[1] >= 0)
- {
- /* Use the given descriptor for stdout. */
- if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1],
- cp->PipeNativeSTDOUT))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- /* Create stderr pipe to be shared by all processes in the pipeline.
- We always create this so the pipe can be passed to select even if
- it will report closed immediately. */
- {
- /* Create the pipe. */
- int p[2];
- if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Store the pipe. */
- cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
- cp->PipeChildStd[2] = p[1];
-
- /* Set close-on-exec flag on the pipe's ends. */
- if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Set to non-blocking in case select lies, or for the polling
- implementation. */
- if(!kwsysProcessSetNonBlocking(p[0]))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- if (cp->PipeFileSTDERR)
- {
- /* Use a file for stderr. */
- if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
- cp->PipeFileSTDERR))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
- else if (cp->PipeSharedSTDERR)
- {
- /* Use the parent stderr. */
- kwsysProcessCleanupDescriptor(&cp->PipeChildStd[2]);
- cp->PipeChildStd[2] = 2;
- }
- else if (cp->PipeNativeSTDERR[1] >= 0)
- {
- /* Use the given handle for stderr. */
- if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2],
- cp->PipeNativeSTDERR))
- {
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
-
- /* The timeout period starts now. */
- cp->StartTime = kwsysProcessTimeGetCurrent();
- cp->TimeoutTime.tv_sec = -1;
- cp->TimeoutTime.tv_usec = -1;
-
- /* Create the pipeline of processes. */
- {
- kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
- int nextStdIn = cp->PipeChildStd[0];
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- /* Setup the process's pipes. */
- si.StdIn = nextStdIn;
- if (i == cp->NumberOfCommands-1)
- {
- nextStdIn = -1;
- si.StdOut = cp->PipeChildStd[1];
- }
- else
- {
- /* Create a pipe to sit between the children. */
- int p[2] = {-1,-1};
- if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
- {
- if (nextStdIn != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupDescriptor(&nextStdIn);
- }
- kwsysProcessCleanup(cp, 1);
- return;
- }
-
- /* Set close-on-exec flag on the pipe's ends. */
- if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- close(p[0]);
- close(p[1]);
- if (nextStdIn != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupDescriptor(&nextStdIn);
- }
- kwsysProcessCleanup(cp, 1);
- return;
- }
- nextStdIn = p[0];
- si.StdOut = p[1];
- }
- si.StdErr = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
-
- {
- int res = kwsysProcessCreate(cp, i, &si);
-
- /* Close our copies of pipes used between children. */
- if (si.StdIn != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupDescriptor(&si.StdIn);
- }
- if (si.StdOut != cp->PipeChildStd[1])
- {
- kwsysProcessCleanupDescriptor(&si.StdOut);
- }
- if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput)
- {
- kwsysProcessCleanupDescriptor(&si.StdErr);
- }
-
- if(!res)
- {
- kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
- if (nextStdIn != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupDescriptor(&nextStdIn);
- }
- kwsysProcessCleanup(cp, 1);
- return;
- }
- }
- }
- }
-
- /* The parent process does not need the child's pipe ends. */
- for (i=0; i < 3; ++i)
- {
- kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
- }
-
- /* Restore the working directory. */
- if(cp->RealWorkingDirectory)
- {
- /* Some platforms specify that the chdir call may be
- interrupted. Repeat the call until it finishes. */
- while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
- free(cp->RealWorkingDirectory);
- cp->RealWorkingDirectory = 0;
- }
-
- /* All the pipes are now open. */
- cp->PipesLeft = KWSYSPE_PIPE_COUNT;
-
- /* The process has now started. */
- cp->State = kwsysProcess_State_Executing;
- cp->Detached = cp->OptionDetach;
-}
-
-/*--------------------------------------------------------------------------*/
-kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp)
-{
- /* Make sure a detached child process is running. */
- if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
- cp->TimeoutExpired || cp->Killed)
- {
- return;
- }
-
- /* Close all the pipes safely. */
- kwsysProcessClosePipes(cp);
-
- /* We will not wait for exit, so cleanup now. */
- kwsysProcessCleanup(cp, 0);
-
- /* The process has been disowned. */
- cp->State = kwsysProcess_State_Disowned;
-}
-
-/*--------------------------------------------------------------------------*/
-typedef struct kwsysProcessWaitData_s
-{
- int Expired;
- int PipeId;
- int User;
- double* UserTimeout;
- kwsysProcessTime TimeoutTime;
-} kwsysProcessWaitData;
-static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
- kwsysProcessWaitData* wd);
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
- double* userTimeout)
-{
- kwsysProcessTime userStartTime = {0, 0};
- kwsysProcessWaitData wd =
- {
- 0,
- kwsysProcess_Pipe_None,
- 0,
- 0,
- {0, 0}
- };
- wd.UserTimeout = userTimeout;
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
- cp->TimeoutExpired)
- {
- return kwsysProcess_Pipe_None;
- }
-
- /* Record the time at which user timeout period starts. */
- if(userTimeout)
- {
- userStartTime = kwsysProcessTimeGetCurrent();
- }
-
- /* Calculate the time at which a timeout will expire, and whether it
- is the user or process timeout. */
- wd.User = kwsysProcessGetTimeoutTime(cp, userTimeout,
- &wd.TimeoutTime);
-
- /* Data can only be available when pipes are open. If the process
- is not running, cp->PipesLeft will be 0. */
- while(cp->PipesLeft > 0 &&
- !kwsysProcessWaitForPipe(cp, data, length, &wd)) {}
-
- /* Update the user timeout. */
- if(userTimeout)
- {
- kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
- userStartTime);
- double d = kwsysProcessTimeToDouble(difference);
- *userTimeout -= d;
- if(*userTimeout < 0)
- {
- *userTimeout = 0;
- }
- }
-
- /* Check what happened. */
- if(wd.PipeId)
- {
- /* Data are ready on a pipe. */
- return wd.PipeId;
- }
- else if(wd.Expired)
- {
- /* A timeout has expired. */
- if(wd.User)
- {
- /* The user timeout has expired. It has no time left. */
- return kwsysProcess_Pipe_Timeout;
- }
- else
- {
- /* The process timeout has expired. Kill the children now. */
- kwsysProcess_Kill(cp);
- cp->Killed = 0;
- cp->TimeoutExpired = 1;
- return kwsysProcess_Pipe_None;
- }
- }
- else
- {
- /* No pipes are left open. */
- return kwsysProcess_Pipe_None;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
- kwsysProcessWaitData* wd)
-{
- int i;
- kwsysProcessTimeNative timeoutLength;
-
-#if KWSYSPE_USE_SELECT
- int numReady = 0;
- int max = -1;
- kwsysProcessTimeNative* timeout = 0;
-
- /* Check for any open pipes with data reported ready by the last
- call to select. According to "man select_tut" we must deal
- with all descriptors reported by a call to select before
- passing them to another select call. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- if(cp->PipeReadEnds[i] >= 0 &&
- FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
- {
- kwsysProcess_ssize_t n;
-
- /* We are handling this pipe now. Remove it from the set. */
- FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
-
- /* The pipe is ready to read without blocking. Keep trying to
- read until the operation is not interrupted. */
- while(((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
- KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && (errno == EINTR));
- if(n > 0)
- {
- /* We have data on this pipe. */
- if(i == KWSYSPE_PIPE_SIGNAL)
- {
- /* A child process has terminated. */
- kwsysProcessDestroy(cp);
- }
- else if(data && length)
- {
- /* Report this data. */
- *data = cp->PipeBuffer;
- *length = (int)(n);
- switch(i)
- {
- case KWSYSPE_PIPE_STDOUT:
- wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
- case KWSYSPE_PIPE_STDERR:
- wd->PipeId = kwsysProcess_Pipe_STDERR; break;
- };
- return 1;
- }
- }
- else if(n < 0 && errno == EAGAIN)
- {
- /* No data are really ready. The select call lied. See the
- "man select" page on Linux for cases when this occurs. */
- }
- else
- {
- /* We are done reading from this pipe. */
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
- --cp->PipesLeft;
- }
- }
- }
-
- /* If we have data, break early. */
- if(wd->PipeId)
- {
- return 1;
- }
-
- /* Make sure the set is empty (it should always be empty here
- anyway). */
- FD_ZERO(&cp->PipeSet);
-
- /* Setup a timeout if required. */
- if(wd->TimeoutTime.tv_sec < 0)
- {
- timeout = 0;
- }
- else
- {
- timeout = &timeoutLength;
- }
- if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime,
- wd->User?wd->UserTimeout:0,
- &timeoutLength, 0))
- {
- /* Timeout has already expired. */
- wd->Expired = 1;
- return 1;
- }
-
- /* Add the pipe reading ends that are still open. */
- max = -1;
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- if(cp->PipeReadEnds[i] >= 0)
- {
- FD_SET(cp->PipeReadEnds[i], &cp->PipeSet);
- if(cp->PipeReadEnds[i] > max)
- {
- max = cp->PipeReadEnds[i];
- }
- }
- }
-
- /* Make sure we have a non-empty set. */
- if(max < 0)
- {
- /* All pipes have closed. Child has terminated. */
- return 1;
- }
-
- /* Run select to block until data are available. Repeat call
- until it is not interrupted. */
- while(((numReady = select(max+1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
- (errno == EINTR));
-
- /* Check result of select. */
- if(numReady == 0)
- {
- /* Select's timeout expired. */
- wd->Expired = 1;
- return 1;
- }
- else if(numReady < 0)
- {
- /* Select returned an error. Leave the error description in the
- pipe buffer. */
- strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
-
- /* Kill the children now. */
- kwsysProcess_Kill(cp);
- cp->Killed = 0;
- cp->SelectError = 1;
- }
-
- return 0;
-#else
- /* Poll pipes for data since we do not have select. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- if(cp->PipeReadEnds[i] >= 0)
- {
- const int fd = cp->PipeReadEnds[i];
- int n = read(fd, cp->PipeBuffer, KWSYSPE_PIPE_BUFFER_SIZE);
- if(n > 0)
- {
- /* We have data on this pipe. */
- if(i == KWSYSPE_PIPE_SIGNAL)
- {
- /* A child process has terminated. */
- kwsysProcessDestroy(cp);
- }
- else if(data && length)
- {
- /* Report this data. */
- *data = cp->PipeBuffer;
- *length = n;
- switch(i)
- {
- case KWSYSPE_PIPE_STDOUT:
- wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
- case KWSYSPE_PIPE_STDERR:
- wd->PipeId = kwsysProcess_Pipe_STDERR; break;
- };
- }
- return 1;
- }
- else if (n == 0) /* EOF */
- {
- /* We are done reading from this pipe. */
-#if defined(__VMS)
- if(!cp->CommandsLeft)
-#endif
- {
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
- --cp->PipesLeft;
- }
- }
- else if (n < 0) /* error */
- {
-#if defined(__VMS)
- if(!cp->CommandsLeft)
- {
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
- --cp->PipesLeft;
- }
- else
-#endif
- if((errno != EINTR) && (errno != EAGAIN))
- {
- strncpy(cp->ErrorMessage,strerror(errno),
- KWSYSPE_PIPE_BUFFER_SIZE);
- /* Kill the children now. */
- kwsysProcess_Kill(cp);
- cp->Killed = 0;
- cp->SelectError = 1;
- return 1;
- }
- }
- }
- }
-
- /* If we have data, break early. */
- if(wd->PipeId)
- {
- return 1;
- }
-
- if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime, wd->User?wd->UserTimeout:0,
- &timeoutLength, 1))
- {
- /* Timeout has already expired. */
- wd->Expired = 1;
- return 1;
- }
-
- /* Sleep a little, try again. */
- {
- unsigned int msec = ((timeoutLength.tv_sec * 1000) +
- (timeoutLength.tv_usec / 1000));
- if (msec > 100000)
- {
- msec = 100000; /* do not sleep more than 100 milliseconds at a time */
- }
- kwsysProcess_usleep(msec);
- }
- return 0;
-#endif
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
-{
- int status = 0;
- int prPipe = 0;
-
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing)
- {
- return 1;
- }
-
- /* Wait for all the pipes to close. Ignore all data. */
- while((prPipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
- {
- if(prPipe == kwsysProcess_Pipe_Timeout)
- {
- return 0;
- }
- }
-
- /* Check if there was an error in one of the waitpid calls. */
- if(cp->State == kwsysProcess_State_Error)
- {
- /* The error message is already in its buffer. Tell
- kwsysProcessCleanup to not create it. */
- kwsysProcessCleanup(cp, 0);
- return 1;
- }
-
- /* Check whether the child reported an error invoking the process. */
- if(cp->SelectError)
- {
- /* The error message is already in its buffer. Tell
- kwsysProcessCleanup to not create it. */
- kwsysProcessCleanup(cp, 0);
- cp->State = kwsysProcess_State_Error;
- return 1;
- }
-
- /* Use the status of the last process in the pipeline. */
- status = cp->CommandExitCodes[cp->NumberOfCommands-1];
-
- /* Determine the outcome. */
- if(cp->Killed)
- {
- /* We killed the child. */
- cp->State = kwsysProcess_State_Killed;
- }
- else if(cp->TimeoutExpired)
- {
- /* The timeout expired. */
- cp->State = kwsysProcess_State_Expired;
- }
- else if(WIFEXITED(status))
- {
- /* The child exited normally. */
- cp->State = kwsysProcess_State_Exited;
- cp->ExitException = kwsysProcess_Exception_None;
- cp->ExitCode = status;
- cp->ExitValue = (int)WEXITSTATUS(status);
- }
- else if(WIFSIGNALED(status))
- {
- /* The child received an unhandled signal. */
- cp->State = kwsysProcess_State_Exception;
- cp->ExitCode = status;
- kwsysProcessSetExitException(cp, (int)WTERMSIG(status));
- }
- else
- {
- /* Error getting the child return code. */
- strcpy(cp->ErrorMessage, "Error getting child return code.");
- cp->State = kwsysProcess_State_Error;
- }
-
- /* Normal cleanup. */
- kwsysProcessCleanup(cp, 0);
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Interrupt(kwsysProcess* cp)
-{
- int i;
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
- cp->Killed)
- {
- return;
- }
-
- /* Interrupt the children. */
- if (cp->CreateProcessGroup)
- {
- if(cp->ForkPIDs)
- {
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- /* Make sure the PID is still valid. */
- if(cp->ForkPIDs[i])
- {
- /* The user created a process group for this process. The group ID
- is the process ID for the original process in the group. */
- kill(-cp->ForkPIDs[i], SIGINT);
- }
- }
- }
- }
- else
- {
- /* No process group was created. Kill our own process group.
- NOTE: While one could argue that we could call kill(cp->ForkPIDs[i],
- SIGINT) as a way to still interrupt the process even though it's not in
- a special group, this is not an option on Windows. Therefore, we kill
- the current process group for consistency with Windows. */
- kill(0, SIGINT);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Kill(kwsysProcess* cp)
-{
- int i;
-
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing)
- {
- return;
- }
-
- /* First close the child exit report pipe write end to avoid causing a
- SIGPIPE when the child terminates and our signal handler tries to
- report it after we have already closed the read end. */
- kwsysProcessCleanupDescriptor(&cp->SignalPipe);
-
-#if !defined(__APPLE__)
- /* Close all the pipe read ends. Do this before killing the
- children because Cygwin has problems killing processes that are
- blocking to wait for writing to their output pipes. */
- kwsysProcessClosePipes(cp);
-#endif
-
- /* Kill the children. */
- cp->Killed = 1;
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- int status;
- if(cp->ForkPIDs[i])
- {
- /* Kill the child. */
- kwsysProcessKill(cp->ForkPIDs[i]);
-
- /* Reap the child. Keep trying until the call is not
- interrupted. */
- while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR));
- }
- }
-
-#if defined(__APPLE__)
- /* Close all the pipe read ends. Do this after killing the
- children because OS X has problems closing pipe read ends whose
- pipes are full and still have an open write end. */
- kwsysProcessClosePipes(cp);
-#endif
-
- cp->CommandsLeft = 0;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Call the free() function with a pointer to volatile without causing
- compiler warnings. */
-static void kwsysProcessVolatileFree(volatile void* p)
-{
- /* clang has made it impossible to free memory that points to volatile
- without first using special pragmas to disable a warning... */
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wcast-qual"
-#endif
- free((void*)p); /* The cast will silence most compilers, but not clang. */
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
-}
-
-/*--------------------------------------------------------------------------*/
-/* Initialize a process control structure for kwsysProcess_Execute. */
-static int kwsysProcessInitialize(kwsysProcess* cp)
-{
- int i;
- volatile pid_t* oldForkPIDs;
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- cp->PipeReadEnds[i] = -1;
- }
- for(i=0; i < 3; ++i)
- {
- cp->PipeChildStd[i] = -1;
- }
- cp->SignalPipe = -1;
- cp->SelectError = 0;
- cp->StartTime.tv_sec = -1;
- cp->StartTime.tv_usec = -1;
- cp->TimeoutTime.tv_sec = -1;
- cp->TimeoutTime.tv_usec = -1;
- cp->TimeoutExpired = 0;
- cp->PipesLeft = 0;
- cp->CommandsLeft = 0;
-#if KWSYSPE_USE_SELECT
- FD_ZERO(&cp->PipeSet);
-#endif
- cp->State = kwsysProcess_State_Starting;
- cp->Killed = 0;
- cp->ExitException = kwsysProcess_Exception_None;
- cp->ExitCode = 1;
- cp->ExitValue = 1;
- cp->ErrorMessage[0] = 0;
- strcpy(cp->ExitExceptionString, "No exception");
-
- oldForkPIDs = cp->ForkPIDs;
- cp->ForkPIDs = (volatile pid_t*)malloc(
- sizeof(volatile pid_t)*(size_t)(cp->NumberOfCommands));
- if(oldForkPIDs)
- {
- kwsysProcessVolatileFree(oldForkPIDs);
- }
- if(!cp->ForkPIDs)
- {
- return 0;
- }
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
- }
-
- if(cp->CommandExitCodes)
- {
- free(cp->CommandExitCodes);
- }
- cp->CommandExitCodes = (int*)malloc(sizeof(int)*
- (size_t)(cp->NumberOfCommands));
- if(!cp->CommandExitCodes)
- {
- return 0;
- }
- memset(cp->CommandExitCodes, 0, sizeof(int)*(size_t)(cp->NumberOfCommands));
-
- /* Allocate memory to save the real working directory. */
- if ( cp->WorkingDirectory )
- {
-#if defined(MAXPATHLEN)
- cp->RealWorkingDirectoryLength = MAXPATHLEN;
-#elif defined(PATH_MAX)
- cp->RealWorkingDirectoryLength = PATH_MAX;
-#else
- cp->RealWorkingDirectoryLength = 4096;
-#endif
- cp->RealWorkingDirectory =
- (char*)malloc((size_t)(cp->RealWorkingDirectoryLength));
- if(!cp->RealWorkingDirectory)
- {
- return 0;
- }
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Free all resources used by the given kwsysProcess instance that were
- allocated by kwsysProcess_Execute. */
-static void kwsysProcessCleanup(kwsysProcess* cp, int error)
-{
- int i;
-
- if(error)
- {
- /* We are cleaning up due to an error. Report the error message
- if one has not been provided already. */
- if(cp->ErrorMessage[0] == 0)
- {
- strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
- }
-
- /* Set the error state. */
- cp->State = kwsysProcess_State_Error;
-
- /* Kill any children already started. */
- if(cp->ForkPIDs)
- {
- int status;
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- if(cp->ForkPIDs[i])
- {
- /* Kill the child. */
- kwsysProcessKill(cp->ForkPIDs[i]);
-
- /* Reap the child. Keep trying until the call is not
- interrupted. */
- while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
- (errno == EINTR));
- }
- }
- }
-
- /* Restore the working directory. */
- if(cp->RealWorkingDirectory)
- {
- while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
- }
- }
-
- /* If not creating a detached child, remove this object from the
- global set of process objects that wish to be notified when a
- child exits. */
- if(!cp->OptionDetach)
- {
- kwsysProcessesRemove(cp);
- }
-
- /* Free memory. */
- if(cp->ForkPIDs)
- {
- kwsysProcessVolatileFree(cp->ForkPIDs);
- cp->ForkPIDs = 0;
- }
- if(cp->RealWorkingDirectory)
- {
- free(cp->RealWorkingDirectory);
- cp->RealWorkingDirectory = 0;
- }
-
- /* Close pipe handles. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
- }
- for(i=0; i < 3; ++i)
- {
- kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-/* Close the given file descriptor if it is open. Reset its value to -1. */
-static void kwsysProcessCleanupDescriptor(int* pfd)
-{
- if(pfd && *pfd > 2)
- {
- /* Keep trying to close until it is not interrupted by a
- * signal. */
- while((close(*pfd) < 0) && (errno == EINTR));
- *pfd = -1;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessClosePipes(kwsysProcess* cp)
-{
- int i;
-
- /* Close any pipes that are still open. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- if(cp->PipeReadEnds[i] >= 0)
- {
-#if KWSYSPE_USE_SELECT
- /* If the pipe was reported by the last call to select, we must
- read from it. This is needed to satisfy the suggestions from
- "man select_tut" and is not needed for the polling
- implementation. Ignore the data. */
- if(FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
- {
- /* We are handling this pipe now. Remove it from the set. */
- FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
-
- /* The pipe is ready to read without blocking. Keep trying to
- read until the operation is not interrupted. */
- while((read(cp->PipeReadEnds[i], cp->PipeBuffer,
- KWSYSPE_PIPE_BUFFER_SIZE) < 0) && (errno == EINTR));
- }
-#endif
-
- /* We are done reading from this pipe. */
- kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
- --cp->PipesLeft;
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessSetNonBlocking(int fd)
-{
- int flags = fcntl(fd, F_GETFL);
- if(flags >= 0)
- {
- flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- }
- return flags >= 0;
-}
-
-/*--------------------------------------------------------------------------*/
-#if defined(__VMS)
-int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
-#endif
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
- kwsysProcessCreateInformation* si)
-{
- sigset_t mask, old_mask;
- int pgidPipe[2];
- char tmp;
- ssize_t readRes;
-
- /* Create the error reporting pipe. */
- if(pipe(si->ErrorPipe) < 0)
- {
- return 0;
- }
-
- /* Create a pipe for detecting that the child process has created a process
- group and session. */
- if(pipe(pgidPipe) < 0)
- {
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
- return 0;
- }
-
- /* Set close-on-exec flag on the pipe's write end. */
- if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
- fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0)
- {
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
- kwsysProcessCleanupDescriptor(&pgidPipe[0]);
- kwsysProcessCleanupDescriptor(&pgidPipe[1]);
- return 0;
- }
-
- /* Block SIGINT / SIGTERM while we start. The purpose is so that our signal
- handler doesn't get called from the child process after the fork and
- before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */
- sigemptyset(&mask);
- sigaddset(&mask, SIGINT);
- sigaddset(&mask, SIGTERM);
- if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
- {
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
- kwsysProcessCleanupDescriptor(&pgidPipe[0]);
- kwsysProcessCleanupDescriptor(&pgidPipe[1]);
- return 0;
- }
-
- /* Fork off a child process. */
-#if defined(__VMS)
- /* VMS needs vfork and execvp to be in the same function because
- they use setjmp/longjmp to run the child startup code in the
- parent! TODO: OptionDetach. Also
- TODO: CreateProcessGroup. */
- cp->ForkPIDs[prIndex] = vfork();
-#else
- cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
-#endif
- if(cp->ForkPIDs[prIndex] < 0)
- {
- sigprocmask(SIG_SETMASK, &old_mask, 0);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
- kwsysProcessCleanupDescriptor(&pgidPipe[0]);
- kwsysProcessCleanupDescriptor(&pgidPipe[1]);
- return 0;
- }
-
- if(cp->ForkPIDs[prIndex] == 0)
- {
-#if defined(__VMS)
- /* Specify standard pipes for child process. */
- decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
-#else
- /* Close the read end of the error reporting / process group
- setup pipe. */
- close(si->ErrorPipe[0]);
- close(pgidPipe[0]);
-
- /* Setup the stdin, stdout, and stderr pipes. */
- if(si->StdIn > 0)
- {
- dup2(si->StdIn, 0);
- }
- else if(si->StdIn < 0)
- {
- close(0);
- }
- if(si->StdOut != 1)
- {
- dup2(si->StdOut, 1);
- }
- if(si->StdErr != 2)
- {
- dup2(si->StdErr, 2);
- }
-
- /* Clear the close-on-exec flag for stdin, stdout, and stderr.
- All other pipe handles will be closed when exec succeeds. */
- fcntl(0, F_SETFD, 0);
- fcntl(1, F_SETFD, 0);
- fcntl(2, F_SETFD, 0);
-
- /* Restore all default signal handlers. */
- kwsysProcessRestoreDefaultSignalHandlers();
-
- /* Now that we have restored default signal handling and created the
- process group, restore mask. */
- sigprocmask(SIG_SETMASK, &old_mask, 0);
-
- /* Create new process group. We use setsid instead of setpgid to avoid
- the child getting hung up on signals like SIGTTOU. (In the real world,
- this has been observed where "git svn" ends up calling the "resize"
- program which opens /dev/tty. */
- if(cp->CreateProcessGroup && setsid() < 0)
- {
- kwsysProcessChildErrorExit(si->ErrorPipe[1]);
- }
-#endif
-
- /* Execute the real process. If successful, this does not return. */
- execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]);
- /* TODO: What does VMS do if the child fails to start? */
- /* TODO: On VMS, how do we put the process in a new group? */
-
- /* Failure. Report error to parent and terminate. */
- kwsysProcessChildErrorExit(si->ErrorPipe[1]);
- }
-
-#if defined(__VMS)
- /* Restore the standard pipes of this process. */
- decc$set_child_standard_streams(0, 1, 2);
-#endif
-
- /* We are done with the error reporting pipe and process group setup pipe
- write end. */
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
- kwsysProcessCleanupDescriptor(&pgidPipe[1]);
-
- /* Make sure the child is in the process group before we proceed. This
- avoids race conditions with calls to the kill function that we make for
- signalling process groups. */
- while((readRes = read(pgidPipe[0], &tmp, 1)) > 0);
- if(readRes < 0)
- {
- sigprocmask(SIG_SETMASK, &old_mask, 0);
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- kwsysProcessCleanupDescriptor(&pgidPipe[0]);
- return 0;
- }
- kwsysProcessCleanupDescriptor(&pgidPipe[0]);
-
- /* Unmask signals. */
- if(sigprocmask(SIG_SETMASK, &old_mask, 0) < 0)
- {
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
- return 0;
- }
-
- /* A child has been created. */
- ++cp->CommandsLeft;
-
- /* Block until the child's exec call succeeds and closes the error
- pipe or writes data to the pipe to report an error. */
- {
- kwsysProcess_ssize_t total = 0;
- kwsysProcess_ssize_t n = 1;
- /* Read the entire error message up to the length of our buffer. */
- while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
- {
- /* Keep trying to read until the operation is not interrupted. */
- while(((n = read(si->ErrorPipe[0], cp->ErrorMessage+total,
- (size_t)(KWSYSPE_PIPE_BUFFER_SIZE-total))) < 0) &&
- (errno == EINTR));
- if(n > 0)
- {
- total += n;
- }
- }
-
- /* We are done with the error reporting pipe read end. */
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
-
- if(total > 0)
- {
- /* The child failed to execute the process. */
- return 0;
- }
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessDestroy(kwsysProcess* cp)
-{
- /* A child process has terminated. Reap it if it is one handled by
- this object. */
- int i;
- /* Temporarily disable signals that access ForkPIDs. We don't want them to
- read a reaped PID, and writes to ForkPIDs are not atomic. */
- sigset_t mask, old_mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGINT);
- sigaddset(&mask, SIGTERM);
- if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
- {
- return;
- }
-
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- if(cp->ForkPIDs[i])
- {
- int result;
- while(((result = waitpid(cp->ForkPIDs[i],
- &cp->CommandExitCodes[i], WNOHANG)) < 0) &&
- (errno == EINTR));
- if(result > 0)
- {
- /* This child has termianted. */
- cp->ForkPIDs[i] = 0;
- if(--cp->CommandsLeft == 0)
- {
- /* All children have terminated. Close the signal pipe
- write end so that no more notifications are sent to this
- object. */
- kwsysProcessCleanupDescriptor(&cp->SignalPipe);
-
- /* TODO: Once the children have terminated, switch
- WaitForData to use a non-blocking read to get the
- rest of the data from the pipe. This is needed when
- grandchildren keep the output pipes open. */
- }
- }
- else if(result < 0 && cp->State != kwsysProcess_State_Error)
- {
- /* Unexpected error. Report the first time this happens. */
- strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
- cp->State = kwsysProcess_State_Error;
- }
- }
- }
-
- /* Re-enable signals. */
- sigprocmask(SIG_SETMASK, &old_mask, 0);
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
-{
- int fout;
- if(!name)
- {
- return 1;
- }
-
- /* Close the existing descriptor. */
- kwsysProcessCleanupDescriptor(p);
-
- /* Open a file for the pipe to write. */
- if((fout = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
- {
- return 0;
- }
-
- /* Set close-on-exec flag on the pipe's end. */
- if(fcntl(fout, F_SETFD, FD_CLOEXEC) < 0)
- {
- return 0;
- }
-
- /* Assign the replacement descriptor. */
- *p = fout;
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessSetupOutputPipeNative(int* p, int des[2])
-{
- /* Close the existing descriptor. */
- kwsysProcessCleanupDescriptor(p);
-
- /* Set close-on-exec flag on the pipe's ends. The proper end will
- be dup2-ed into the standard descriptor number after fork but
- before exec. */
- if((fcntl(des[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(des[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- return 0;
- }
-
- /* Assign the replacement descriptor. */
- *p = des[1];
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Get the time at which either the process or user timeout will
- expire. Returns 1 if the user timeout is first, and 0 otherwise. */
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
- kwsysProcessTime* timeoutTime)
-{
- /* The first time this is called, we need to calculate the time at
- which the child will timeout. */
- if(cp->Timeout > 0 && cp->TimeoutTime.tv_sec < 0)
- {
- kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
- cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
- }
-
- /* Start with process timeout. */
- *timeoutTime = cp->TimeoutTime;
-
- /* Check if the user timeout is earlier. */
- if(userTimeout)
- {
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
- kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
- userTimeoutLength);
- if(timeoutTime->tv_sec < 0 ||
- kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
- {
- *timeoutTime = userTimeoutTime;
- return 1;
- }
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Get the length of time before the given timeout time arrives.
- Returns 1 if the time has already arrived, and 0 otherwise. */
-static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
- kwsysProcessTimeNative* timeoutLength,
- int zeroIsExpired)
-{
- if(timeoutTime->tv_sec < 0)
- {
- /* No timeout time has been requested. */
- return 0;
- }
- else
- {
- /* Calculate the remaining time. */
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime timeLeft = kwsysProcessTimeSubtract(*timeoutTime,
- currentTime);
- if(timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0)
- {
- /* Caller has explicitly requested a zero timeout. */
- timeLeft.tv_sec = 0;
- timeLeft.tv_usec = 0;
- }
-
- if(timeLeft.tv_sec < 0 ||
- (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired))
- {
- /* Timeout has already expired. */
- return 1;
- }
- else
- {
- /* There is some time left. */
- timeoutLength->tv_sec = timeLeft.tv_sec;
- timeoutLength->tv_usec = timeLeft.tv_usec;
- return 0;
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
-{
- kwsysProcessTime current;
- kwsysProcessTimeNative current_native;
- gettimeofday(&current_native, 0);
- current.tv_sec = (long)current_native.tv_sec;
- current.tv_usec = (long)current_native.tv_usec;
- return current;
-}
-
-/*--------------------------------------------------------------------------*/
-static double kwsysProcessTimeToDouble(kwsysProcessTime t)
-{
- return (double)t.tv_sec + (double)(t.tv_usec)*0.000001;
-}
-
-/*--------------------------------------------------------------------------*/
-static kwsysProcessTime kwsysProcessTimeFromDouble(double d)
-{
- kwsysProcessTime t;
- t.tv_sec = (long)d;
- t.tv_usec = (long)((d-(double)(t.tv_sec))*1000000);
- return t;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- return ((in1.tv_sec < in2.tv_sec) ||
- ((in1.tv_sec == in2.tv_sec) && (in1.tv_usec < in2.tv_usec)));
-}
-
-/*--------------------------------------------------------------------------*/
-static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- kwsysProcessTime out;
- out.tv_sec = in1.tv_sec + in2.tv_sec;
- out.tv_usec = in1.tv_usec + in2.tv_usec;
- if(out.tv_usec > 1000000)
- {
- out.tv_usec -= 1000000;
- out.tv_sec += 1;
- }
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- kwsysProcessTime out;
- out.tv_sec = in1.tv_sec - in2.tv_sec;
- out.tv_usec = in1.tv_usec - in2.tv_usec;
- if(out.tv_usec < 0)
- {
- out.tv_usec += 1000000;
- out.tv_sec -= 1;
- }
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-#define KWSYSPE_CASE(type, str) \
- cp->ExitException = kwsysProcess_Exception_##type; \
- strcpy(cp->ExitExceptionString, str)
-static void kwsysProcessSetExitException(kwsysProcess* cp, int sig)
-{
- switch (sig)
- {
-#ifdef SIGSEGV
- case SIGSEGV: KWSYSPE_CASE(Fault, "Segmentation fault"); break;
-#endif
-#ifdef SIGBUS
-# if !defined(SIGSEGV) || SIGBUS != SIGSEGV
- case SIGBUS: KWSYSPE_CASE(Fault, "Bus error"); break;
-# endif
-#endif
-#ifdef SIGFPE
- case SIGFPE: KWSYSPE_CASE(Numerical, "Floating-point exception"); break;
-#endif
-#ifdef SIGILL
- case SIGILL: KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
-#endif
-#ifdef SIGINT
- case SIGINT: KWSYSPE_CASE(Interrupt, "User interrupt"); break;
-#endif
-#ifdef SIGABRT
- case SIGABRT: KWSYSPE_CASE(Other, "Child aborted"); break;
-#endif
-#ifdef SIGKILL
- case SIGKILL: KWSYSPE_CASE(Other, "Child killed"); break;
-#endif
-#ifdef SIGTERM
- case SIGTERM: KWSYSPE_CASE(Other, "Child terminated"); break;
-#endif
-#ifdef SIGHUP
- case SIGHUP: KWSYSPE_CASE(Other, "SIGHUP"); break;
-#endif
-#ifdef SIGQUIT
- case SIGQUIT: KWSYSPE_CASE(Other, "SIGQUIT"); break;
-#endif
-#ifdef SIGTRAP
- case SIGTRAP: KWSYSPE_CASE(Other, "SIGTRAP"); break;
-#endif
-#ifdef SIGIOT
-# if !defined(SIGABRT) || SIGIOT != SIGABRT
- case SIGIOT: KWSYSPE_CASE(Other, "SIGIOT"); break;
-# endif
-#endif
-#ifdef SIGUSR1
- case SIGUSR1: KWSYSPE_CASE(Other, "SIGUSR1"); break;
-#endif
-#ifdef SIGUSR2
- case SIGUSR2: KWSYSPE_CASE(Other, "SIGUSR2"); break;
-#endif
-#ifdef SIGPIPE
- case SIGPIPE: KWSYSPE_CASE(Other, "SIGPIPE"); break;
-#endif
-#ifdef SIGALRM
- case SIGALRM: KWSYSPE_CASE(Other, "SIGALRM"); break;
-#endif
-#ifdef SIGSTKFLT
- case SIGSTKFLT: KWSYSPE_CASE(Other, "SIGSTKFLT"); break;
-#endif
-#ifdef SIGCHLD
- case SIGCHLD: KWSYSPE_CASE(Other, "SIGCHLD"); break;
-#elif defined(SIGCLD)
- case SIGCLD: KWSYSPE_CASE(Other, "SIGCLD"); break;
-#endif
-#ifdef SIGCONT
- case SIGCONT: KWSYSPE_CASE(Other, "SIGCONT"); break;
-#endif
-#ifdef SIGSTOP
- case SIGSTOP: KWSYSPE_CASE(Other, "SIGSTOP"); break;
-#endif
-#ifdef SIGTSTP
- case SIGTSTP: KWSYSPE_CASE(Other, "SIGTSTP"); break;
-#endif
-#ifdef SIGTTIN
- case SIGTTIN: KWSYSPE_CASE(Other, "SIGTTIN"); break;
-#endif
-#ifdef SIGTTOU
- case SIGTTOU: KWSYSPE_CASE(Other, "SIGTTOU"); break;
-#endif
-#ifdef SIGURG
- case SIGURG: KWSYSPE_CASE(Other, "SIGURG"); break;
-#endif
-#ifdef SIGXCPU
- case SIGXCPU: KWSYSPE_CASE(Other, "SIGXCPU"); break;
-#endif
-#ifdef SIGXFSZ
- case SIGXFSZ: KWSYSPE_CASE(Other, "SIGXFSZ"); break;
-#endif
-#ifdef SIGVTALRM
- case SIGVTALRM: KWSYSPE_CASE(Other, "SIGVTALRM"); break;
-#endif
-#ifdef SIGPROF
- case SIGPROF: KWSYSPE_CASE(Other, "SIGPROF"); break;
-#endif
-#ifdef SIGWINCH
- case SIGWINCH: KWSYSPE_CASE(Other, "SIGWINCH"); break;
-#endif
-#ifdef SIGPOLL
- case SIGPOLL: KWSYSPE_CASE(Other, "SIGPOLL"); break;
-#endif
-#ifdef SIGIO
-# if !defined(SIGPOLL) || SIGIO != SIGPOLL
- case SIGIO: KWSYSPE_CASE(Other, "SIGIO"); break;
-# endif
-#endif
-#ifdef SIGPWR
- case SIGPWR: KWSYSPE_CASE(Other, "SIGPWR"); break;
-#endif
-#ifdef SIGSYS
- case SIGSYS: KWSYSPE_CASE(Other, "SIGSYS"); break;
-#endif
-#ifdef SIGUNUSED
-# if !defined(SIGSYS) || SIGUNUSED != SIGSYS
- case SIGUNUSED: KWSYSPE_CASE(Other, "SIGUNUSED"); break;
-# endif
-#endif
- default:
- cp->ExitException = kwsysProcess_Exception_Other;
- sprintf(cp->ExitExceptionString, "Signal %d", sig);
- break;
- }
-}
-#undef KWSYSPE_CASE
-
-/*--------------------------------------------------------------------------*/
-/* When the child process encounters an error before its program is
- invoked, this is called to report the error to the parent and
- exit. */
-static void kwsysProcessChildErrorExit(int errorPipe)
-{
- /* Construct the error message. */
- char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
- kwsysProcess_ssize_t result;
- strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
-
- /* Report the error to the parent through the special pipe. */
- result=write(errorPipe, buffer, strlen(buffer));
- (void)result;
-
- /* Terminate without cleanup. */
- _exit(1);
-}
-
-/*--------------------------------------------------------------------------*/
-/* Restores all signal handlers to their default values. */
-static void kwsysProcessRestoreDefaultSignalHandlers(void)
-{
- struct sigaction act;
- memset(&act, 0, sizeof(struct sigaction));
- act.sa_handler = SIG_DFL;
-#ifdef SIGHUP
- sigaction(SIGHUP, &act, 0);
-#endif
-#ifdef SIGINT
- sigaction(SIGINT, &act, 0);
-#endif
-#ifdef SIGQUIT
- sigaction(SIGQUIT, &act, 0);
-#endif
-#ifdef SIGILL
- sigaction(SIGILL, &act, 0);
-#endif
-#ifdef SIGTRAP
- sigaction(SIGTRAP, &act, 0);
-#endif
-#ifdef SIGABRT
- sigaction(SIGABRT, &act, 0);
-#endif
-#ifdef SIGIOT
- sigaction(SIGIOT, &act, 0);
-#endif
-#ifdef SIGBUS
- sigaction(SIGBUS, &act, 0);
-#endif
-#ifdef SIGFPE
- sigaction(SIGFPE, &act, 0);
-#endif
-#ifdef SIGUSR1
- sigaction(SIGUSR1, &act, 0);
-#endif
-#ifdef SIGSEGV
- sigaction(SIGSEGV, &act, 0);
-#endif
-#ifdef SIGUSR2
- sigaction(SIGUSR2, &act, 0);
-#endif
-#ifdef SIGPIPE
- sigaction(SIGPIPE, &act, 0);
-#endif
-#ifdef SIGALRM
- sigaction(SIGALRM, &act, 0);
-#endif
-#ifdef SIGTERM
- sigaction(SIGTERM, &act, 0);
-#endif
-#ifdef SIGSTKFLT
- sigaction(SIGSTKFLT, &act, 0);
-#endif
-#ifdef SIGCLD
- sigaction(SIGCLD, &act, 0);
-#endif
-#ifdef SIGCHLD
- sigaction(SIGCHLD, &act, 0);
-#endif
-#ifdef SIGCONT
- sigaction(SIGCONT, &act, 0);
-#endif
-#ifdef SIGTSTP
- sigaction(SIGTSTP, &act, 0);
-#endif
-#ifdef SIGTTIN
- sigaction(SIGTTIN, &act, 0);
-#endif
-#ifdef SIGTTOU
- sigaction(SIGTTOU, &act, 0);
-#endif
-#ifdef SIGURG
- sigaction(SIGURG, &act, 0);
-#endif
-#ifdef SIGXCPU
- sigaction(SIGXCPU, &act, 0);
-#endif
-#ifdef SIGXFSZ
- sigaction(SIGXFSZ, &act, 0);
-#endif
-#ifdef SIGVTALRM
- sigaction(SIGVTALRM, &act, 0);
-#endif
-#ifdef SIGPROF
- sigaction(SIGPROF, &act, 0);
-#endif
-#ifdef SIGWINCH
- sigaction(SIGWINCH, &act, 0);
-#endif
-#ifdef SIGPOLL
- sigaction(SIGPOLL, &act, 0);
-#endif
-#ifdef SIGIO
- sigaction(SIGIO, &act, 0);
-#endif
-#ifdef SIGPWR
- sigaction(SIGPWR, &act, 0);
-#endif
-#ifdef SIGSYS
- sigaction(SIGSYS, &act, 0);
-#endif
-#ifdef SIGUNUSED
- sigaction(SIGUNUSED, &act, 0);
-#endif
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessExit(void)
-{
- _exit(0);
-}
-
-/*--------------------------------------------------------------------------*/
-#if !defined(__VMS)
-static pid_t kwsysProcessFork(kwsysProcess* cp,
- kwsysProcessCreateInformation* si)
-{
- /* Create a detached process if requested. */
- if(cp->OptionDetach)
- {
- /* Create an intermediate process. */
- pid_t middle_pid = fork();
- if(middle_pid < 0)
- {
- /* Fork failed. Return as if we were not detaching. */
- return middle_pid;
- }
- else if(middle_pid == 0)
- {
- /* This is the intermediate process. Create the real child. */
- pid_t child_pid = fork();
- if(child_pid == 0)
- {
- /* This is the real child process. There is nothing to do here. */
- return 0;
- }
- else
- {
- /* Use the error pipe to report the pid to the real parent. */
- while((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR));
-
- /* Exit without cleanup. The parent holds all resources. */
- kwsysProcessExit();
- return 0; /* Never reached, but avoids SunCC warning. */
- }
- }
- else
- {
- /* This is the original parent process. The intermediate
- process will use the error pipe to report the pid of the
- detached child. */
- pid_t child_pid;
- int status;
- while((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR));
-
- /* Wait for the intermediate process to exit and clean it up. */
- while((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR));
- return child_pid;
- }
- }
- else
- {
- /* Not creating a detached process. Use normal fork. */
- return fork();
- }
-}
-#endif
-
-/*--------------------------------------------------------------------------*/
-/* We try to obtain process information by invoking the ps command.
- Here we define the command to call on each platform and the
- corresponding parsing format string. The parsing format should
- have two integers to store: the pid and then the ppid. */
-#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) \
- || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__)
-# define KWSYSPE_PS_COMMAND "ps axo pid,ppid"
-# define KWSYSPE_PS_FORMAT "%d %d\n"
-#elif defined(__sun) && (defined(__SVR4) || defined(__svr4__)) /* Solaris */
-# define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid"
-# define KWSYSPE_PS_FORMAT "%d %d\n"
-#elif defined(__hpux) || defined(__sun__) || defined(__sgi) || defined(_AIX) \
- || defined(__sparc)
-# define KWSYSPE_PS_COMMAND "ps -ef"
-# define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n"
-#elif defined(__QNX__)
-# define KWSYSPE_PS_COMMAND "ps -Af"
-# define KWSYSPE_PS_FORMAT "%*d %d %d %*[^\n]\n"
-#elif defined(__CYGWIN__)
-# define KWSYSPE_PS_COMMAND "ps aux"
-# define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n"
-#endif
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessKill(pid_t process_id)
-{
-#if defined(__linux__) || defined(__CYGWIN__)
- DIR* procdir;
-#endif
-
- /* Suspend the process to be sure it will not create more children. */
- kill(process_id, SIGSTOP);
-
-#if defined(__CYGWIN__)
- /* Some Cygwin versions seem to need help here. Give up our time slice
- so that the child can process SIGSTOP before we send SIGKILL. */
- usleep(1);
-#endif
-
- /* Kill all children if we can find them. */
-#if defined(__linux__) || defined(__CYGWIN__)
- /* First try using the /proc filesystem. */
- if((procdir = opendir("/proc")) != NULL)
- {
-#if defined(MAXPATHLEN)
- char fname[MAXPATHLEN];
-#elif defined(PATH_MAX)
- char fname[PATH_MAX];
-#else
- char fname[4096];
-#endif
- char buffer[KWSYSPE_PIPE_BUFFER_SIZE+1];
- struct dirent* d;
-
- /* Each process has a directory in /proc whose name is the pid.
- Within this directory is a file called stat that has the
- following format:
-
- pid (command line) status ppid ...
-
- We want to get the ppid for all processes. Those that have
- process_id as their parent should be recursively killed. */
- for(d = readdir(procdir); d; d = readdir(procdir))
- {
- int pid;
- if(sscanf(d->d_name, "%d", &pid) == 1 && pid != 0)
- {
- struct stat finfo;
- sprintf(fname, "/proc/%d/stat", pid);
- if(stat(fname, &finfo) == 0)
- {
- FILE* f = fopen(fname, "r");
- if(f)
- {
- size_t nread = fread(buffer, 1, KWSYSPE_PIPE_BUFFER_SIZE, f);
- fclose(f);
- buffer[nread] = '\0';
- if(nread > 0)
- {
- const char* rparen = strrchr(buffer, ')');
- int ppid;
- if(rparen && (sscanf(rparen+1, "%*s %d", &ppid) == 1))
- {
- if(ppid == process_id)
- {
- /* Recursively kill this child and its children. */
- kwsysProcessKill(pid);
- }
- }
- }
- }
- }
- }
- }
- closedir(procdir);
- }
- else
-#endif
- {
-#if defined(KWSYSPE_PS_COMMAND)
- /* Try running "ps" to get the process information. */
- FILE* ps = popen(KWSYSPE_PS_COMMAND, "r");
-
- /* Make sure the process started and provided a valid header. */
- if(ps && fscanf(ps, "%*[^\n]\n") != EOF)
- {
- /* Look for processes whose parent is the process being killed. */
- int pid, ppid;
- while(fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2)
- {
- if(ppid == process_id)
- {
- /* Recursively kill this child and its children. */
- kwsysProcessKill(pid);
- }
- }
- }
-
- /* We are done with the ps process. */
- if(ps)
- {
- pclose(ps);
- }
-#endif
- }
-
- /* Kill the process. */
- kill(process_id, SIGKILL);
-
-#if defined(__APPLE__)
- /* On OS X 10.3 the above SIGSTOP occasionally prevents the SIGKILL
- from working. Just in case, we resume the child and kill it
- again. There is a small race condition in this obscure case. If
- the child manages to fork again between these two signals, we
- will not catch its children. */
- kill(process_id, SIGCONT);
- kill(process_id, SIGKILL);
-#endif
-}
-
-/*--------------------------------------------------------------------------*/
-#if defined(__VMS)
-int decc$feature_get_index(const char* name);
-int decc$feature_set_value(int index, int mode, int value);
-static int kwsysProcessSetVMSFeature(const char* name, int value)
-{
- int i;
- errno = 0;
- i = decc$feature_get_index(name);
- return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0);
-}
-#endif
-
-/*--------------------------------------------------------------------------*/
-/* Global set of executing processes for use by the signal handler.
- This global instance will be zero-initialized by the compiler. */
-typedef struct kwsysProcessInstances_s
-{
- int Count;
- int Size;
- kwsysProcess** Processes;
-} kwsysProcessInstances;
-static kwsysProcessInstances kwsysProcesses;
-
-/* The old SIGCHLD / SIGINT / SIGTERM handlers. */
-static struct sigaction kwsysProcessesOldSigChldAction;
-static struct sigaction kwsysProcessesOldSigIntAction;
-static struct sigaction kwsysProcessesOldSigTermAction;
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
-{
- /* Block signals while we update the set of pipes to check.
- TODO: sigprocmask is undefined for threaded apps. See
- pthread_sigmask. */
- sigset_t newset;
- sigset_t oldset;
- sigemptyset(&newset);
- sigaddset(&newset, SIGCHLD);
- sigaddset(&newset, SIGINT);
- sigaddset(&newset, SIGTERM);
- sigprocmask(SIG_BLOCK, &newset, &oldset);
-
- /* Store the new set in that seen by the signal handler. */
- kwsysProcesses = *newProcesses;
-
- /* Restore the signal mask to the previous setting. */
- sigprocmask(SIG_SETMASK, &oldset, 0);
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcessesAdd(kwsysProcess* cp)
-{
- /* Create a pipe through which the signal handler can notify the
- given process object that a child has exited. */
- {
- /* Create the pipe. */
- int p[2];
- if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
- {
- return 0;
- }
-
- /* Store the pipes now to be sure they are cleaned up later. */
- cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0];
- cp->SignalPipe = p[1];
-
- /* Switch the pipe to non-blocking mode so that reading a byte can
- be an atomic test-and-set. */
- if(!kwsysProcessSetNonBlocking(p[0]) ||
- !kwsysProcessSetNonBlocking(p[1]))
- {
- return 0;
- }
-
- /* The children do not need this pipe. Set close-on-exec flag on
- the pipe's ends. */
- if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- return 0;
- }
- }
-
- /* Attempt to add the given signal pipe to the signal handler set. */
- {
-
- /* Make sure there is enough space for the new signal pipe. */
- kwsysProcessInstances oldProcesses = kwsysProcesses;
- kwsysProcessInstances newProcesses = oldProcesses;
- if(oldProcesses.Count == oldProcesses.Size)
- {
- /* Start with enough space for a small number of process instances
- and double the size each time more is needed. */
- newProcesses.Size = oldProcesses.Size? oldProcesses.Size*2 : 4;
-
- /* Try allocating the new block of memory. */
- if((newProcesses.Processes = ((kwsysProcess**)
- malloc((size_t)(newProcesses.Size)*
- sizeof(kwsysProcess*)))))
- {
- /* Copy the old pipe set to the new memory. */
- if(oldProcesses.Count > 0)
- {
- memcpy(newProcesses.Processes, oldProcesses.Processes,
- ((size_t)(oldProcesses.Count) * sizeof(kwsysProcess*)));
- }
- }
- else
- {
- /* Failed to allocate memory for the new signal pipe set. */
- return 0;
- }
- }
-
- /* Append the new signal pipe to the set. */
- newProcesses.Processes[newProcesses.Count++] = cp;
-
- /* Store the new set in that seen by the signal handler. */
- kwsysProcessesUpdate(&newProcesses);
-
- /* Free the original pipes if new ones were allocated. */
- if(newProcesses.Processes != oldProcesses.Processes)
- {
- free(oldProcesses.Processes);
- }
-
- /* If this is the first process, enable the signal handler. */
- if(newProcesses.Count == 1)
- {
- /* Install our handler for SIGCHLD. Repeat call until it is not
- interrupted. */
- struct sigaction newSigAction;
- memset(&newSigAction, 0, sizeof(struct sigaction));
-#if KWSYSPE_USE_SIGINFO
- newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
- newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
-# ifdef SA_RESTART
- newSigAction.sa_flags |= SA_RESTART;
-# endif
-#else
- newSigAction.sa_handler = kwsysProcessesSignalHandler;
- newSigAction.sa_flags = SA_NOCLDSTOP;
-#endif
- sigemptyset(&newSigAction.sa_mask);
- while((sigaction(SIGCHLD, &newSigAction,
- &kwsysProcessesOldSigChldAction) < 0) &&
- (errno == EINTR));
-
- /* Install our handler for SIGINT / SIGTERM. Repeat call until
- it is not interrupted. */
- sigemptyset(&newSigAction.sa_mask);
- sigaddset(&newSigAction.sa_mask, SIGTERM);
- while((sigaction(SIGINT, &newSigAction,
- &kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR));
-
- sigemptyset(&newSigAction.sa_mask);
- sigaddset(&newSigAction.sa_mask, SIGINT);
- while((sigaction(SIGTERM, &newSigAction,
- &kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR));
- }
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessesRemove(kwsysProcess* cp)
-{
- /* Attempt to remove the given signal pipe from the signal handler set. */
- {
- /* Find the given process in the set. */
- kwsysProcessInstances newProcesses = kwsysProcesses;
- int i;
- for(i=0; i < newProcesses.Count; ++i)
- {
- if(newProcesses.Processes[i] == cp)
- {
- break;
- }
- }
- if(i < newProcesses.Count)
- {
- /* Remove the process from the set. */
- --newProcesses.Count;
- for(; i < newProcesses.Count; ++i)
- {
- newProcesses.Processes[i] = newProcesses.Processes[i+1];
- }
-
- /* If this was the last process, disable the signal handler. */
- if(newProcesses.Count == 0)
- {
- /* Restore the signal handlers. Repeat call until it is not
- interrupted. */
- while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
- (errno == EINTR));
- while((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
- (errno == EINTR));
- while((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
- (errno == EINTR));
-
- /* Free the table of process pointers since it is now empty.
- This is safe because the signal handler has been removed. */
- newProcesses.Size = 0;
- free(newProcesses.Processes);
- newProcesses.Processes = 0;
- }
-
- /* Store the new set in that seen by the signal handler. */
- kwsysProcessesUpdate(&newProcesses);
- }
- }
-
- /* Close the pipe through which the signal handler may have notified
- the given process object that a child has exited. */
- kwsysProcessCleanupDescriptor(&cp->SignalPipe);
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessesSignalHandler(int signum
-#if KWSYSPE_USE_SIGINFO
- , siginfo_t* info, void* ucontext
-#endif
- )
-{
- int i, j, procStatus, old_errno = errno;
-#if KWSYSPE_USE_SIGINFO
- (void)info;
- (void)ucontext;
-#endif
-
- /* Signal all process objects that a child has terminated. */
- switch(signum)
- {
- case SIGCHLD:
- for(i=0; i < kwsysProcesses.Count; ++i)
- {
- /* Set the pipe in a signalled state. */
- char buf = 1;
- kwsysProcess* cp = kwsysProcesses.Processes[i];
- kwsysProcess_ssize_t pipeStatus=
- read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
- (void)pipeStatus;
- pipeStatus=write(cp->SignalPipe, &buf, 1);
- (void)pipeStatus;
- }
- break;
- case SIGINT:
- case SIGTERM:
- /* Signal child processes that are running in new process groups. */
- for(i=0; i < kwsysProcesses.Count; ++i)
- {
- kwsysProcess* cp = kwsysProcesses.Processes[i];
- /* Check Killed to avoid data race condition when killing.
- Check State to avoid data race condition in kwsysProcessCleanup
- when there is an error (it leaves a reaped PID). */
- if(cp->CreateProcessGroup && !cp->Killed &&
- cp->State != kwsysProcess_State_Error && cp->ForkPIDs)
- {
- for(j=0; j < cp->NumberOfCommands; ++j)
- {
- /* Make sure the PID is still valid. */
- if(cp->ForkPIDs[j])
- {
- /* The user created a process group for this process. The group ID
- is the process ID for the original process in the group. */
- kill(-cp->ForkPIDs[j], SIGINT);
- }
- }
- }
- }
-
- /* Wait for all processes to terminate. */
- while(wait(&procStatus) >= 0 || errno != ECHILD)
- {
- }
-
- /* Terminate the process, which is now in an inconsistent state
- because we reaped all the PIDs that it may have been reaping
- or may have reaped in the future. Reraise the signal so that
- the proper exit code is returned. */
- {
- /* Install default signal handler. */
- struct sigaction defSigAction;
- sigset_t unblockSet;
- memset(&defSigAction, 0, sizeof(defSigAction));
- defSigAction.sa_handler = SIG_DFL;
- sigemptyset(&defSigAction.sa_mask);
- while((sigaction(signum, &defSigAction, 0) < 0) &&
- (errno == EINTR));
- /* Unmask the signal. */
- sigemptyset(&unblockSet);
- sigaddset(&unblockSet, signum);
- sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
- /* Raise the signal again. */
- raise(signum);
- /* We shouldn't get here... but if we do... */
- _exit(1);
- }
- /* break omitted to silence unreachable code clang compiler warning. */
- }
-
-#if !KWSYSPE_USE_SIGINFO
- /* Re-Install our handler. Repeat call until it is not interrupted. */
- {
- struct sigaction newSigAction;
- struct sigaction &oldSigAction;
- memset(&newSigAction, 0, sizeof(struct sigaction));
- newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
- newSigChldAction.sa_flags = SA_NOCLDSTOP;
- sigemptyset(&newSigAction.sa_mask);
- switch(signum)
- {
- case SIGCHLD: oldSigAction = &kwsysProcessesOldSigChldAction; break;
- case SIGINT:
- sigaddset(&newSigAction.sa_mask, SIGTERM);
- oldSigAction = &kwsysProcessesOldSigIntAction; break;
- case SIGTERM:
- sigaddset(&newSigAction.sa_mask, SIGINT);
- oldSigAction = &kwsysProcessesOldSigTermAction; break;
- default: return 0;
- }
- while((sigaction(signum, &newSigAction,
- oldSigAction) < 0) &&
- (errno == EINTR));
- }
-#endif
-
- errno = old_errno;
-}
diff --git a/src/kwsys/ProcessWin32.c b/src/kwsys/ProcessWin32.c
deleted file mode 100644
index 1f8749f..0000000
--- a/src/kwsys/ProcessWin32.c
+++ /dev/null
@@ -1,3017 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(Encoding.h)
-
-/* Work-around CMake dependency scanning limitation. This must
- duplicate the above list of headers. */
-#if 0
-# include "Process.h.in"
-# include "Encoding_c.h.in"
-#endif
-
-/*
-
-Implementation for Windows
-
-On windows, a thread is created to wait for data on each pipe. The
-threads are synchronized with the main thread to simulate the use of
-a UNIX-style select system call.
-
-*/
-
-#ifdef _MSC_VER
-#pragma warning (push, 1)
-#endif
-#include <windows.h> /* Windows API */
-#if defined(_MSC_VER) && _MSC_VER >= 1800
-# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
-#endif
-#include <string.h> /* strlen, strdup */
-#include <stdio.h> /* sprintf */
-#include <io.h> /* _unlink */
-#ifdef __WATCOMC__
-#define _unlink unlink
-#endif
-
-#ifndef _MAX_FNAME
-#define _MAX_FNAME 4096
-#endif
-#ifndef _MAX_PATH
-#define _MAX_PATH 4096
-#endif
-
-#ifdef _MSC_VER
-#pragma warning (pop)
-#pragma warning (disable: 4514)
-#pragma warning (disable: 4706)
-#endif
-
-#if defined(__BORLANDC__)
-# pragma warn -8004 /* assigned a value that is never used */
-# pragma warn -8060 /* Assignment inside if() condition. */
-#endif
-
-/* There are pipes for the process pipeline's stdout and stderr. */
-#define KWSYSPE_PIPE_COUNT 2
-#define KWSYSPE_PIPE_STDOUT 0
-#define KWSYSPE_PIPE_STDERR 1
-
-/* The maximum amount to read from a pipe at a time. */
-#define KWSYSPE_PIPE_BUFFER_SIZE 1024
-
-/* Debug output macro. */
-#if 0
-# define KWSYSPE_DEBUG(x) \
-( \
- (void*)cp == (void*)0x00226DE0? \
- ( \
- fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, __LINE__), \
- fprintf x, \
- fflush(stderr), \
- 1 \
- ) : (1) \
-)
-#else
-# define KWSYSPE_DEBUG(x) (void)1
-#endif
-
-typedef LARGE_INTEGER kwsysProcessTime;
-
-typedef struct kwsysProcessCreateInformation_s
-{
- /* Windows child startup control data. */
- STARTUPINFOW StartupInfo;
-
- /* Original handles before making inherited duplicates. */
- HANDLE hStdInput;
- HANDLE hStdOutput;
- HANDLE hStdError;
-} kwsysProcessCreateInformation;
-
-
-/*--------------------------------------------------------------------------*/
-typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
-static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
-static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp,
- kwsysProcessPipeData* td);
-static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
-static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
- kwsysProcessPipeData* td);
-static int kwsysProcessInitialize(kwsysProcess* cp);
-static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si);
-static void kwsysProcessDestroy(kwsysProcess* cp, int event);
-static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle,
- const char* name);
-static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
-static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
-static void kwsysProcessCleanupHandle(PHANDLE h);
-static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error);
-static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
- kwsysProcessTime* timeoutTime);
-static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
- kwsysProcessTime* timeoutLength);
-static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
-static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
-static double kwsysProcessTimeToDouble(kwsysProcessTime t);
-static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
-static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
-static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
-static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
-static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
-static void kwsysProcessKillTree(int pid);
-static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
-static int kwsysProcessesInitialize(void);
-static int kwsysTryEnterCreateProcessSection(void);
-static void kwsysLeaveCreateProcessSection(void);
-static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId,
- int newProcessGroup);
-static void kwsysProcessesRemove(HANDLE hProcess);
-static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType);
-
-/*--------------------------------------------------------------------------*/
-/* A structure containing synchronization data for each thread. */
-typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync;
-struct kwsysProcessPipeSync_s
-{
- /* Handle to the thread. */
- HANDLE Thread;
-
- /* Semaphore indicating to the thread that a process has started. */
- HANDLE Ready;
-
- /* Semaphore indicating to the thread that it should begin work. */
- HANDLE Go;
-
- /* Semaphore indicating thread has reset for another process. */
- HANDLE Reset;
-};
-
-/*--------------------------------------------------------------------------*/
-/* A structure containing data for each pipe's threads. */
-struct kwsysProcessPipeData_s
-{
- /* ------------- Data managed per instance of kwsysProcess ------------- */
-
- /* Synchronization data for reading thread. */
- kwsysProcessPipeSync Reader;
-
- /* Synchronization data for waking thread. */
- kwsysProcessPipeSync Waker;
-
- /* Index of this pipe. */
- int Index;
-
- /* The kwsysProcess instance owning this pipe. */
- kwsysProcess* Process;
-
- /* ------------- Data managed per call to Execute ------------- */
-
- /* Buffer for data read in this pipe's thread. */
- char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
-
- /* The length of the data stored in the buffer. */
- DWORD DataLength;
-
- /* Whether the pipe has been closed. */
- int Closed;
-
- /* Handle for the read end of this pipe. */
- HANDLE Read;
-
- /* Handle for the write end of this pipe. */
- HANDLE Write;
-};
-
-/*--------------------------------------------------------------------------*/
-/* Structure containing data used to implement the child's execution. */
-struct kwsysProcess_s
-{
- /* ------------- Data managed per instance of kwsysProcess ------------- */
-
- /* The status of the process structure. */
- int State;
-
- /* The command lines to execute. */
- wchar_t** Commands;
- int NumberOfCommands;
-
- /* The exit code of each command. */
- DWORD* CommandExitCodes;
-
- /* The working directory for the child process. */
- wchar_t* WorkingDirectory;
-
- /* Whether to create the child as a detached process. */
- int OptionDetach;
-
- /* Whether the child was created as a detached process. */
- int Detached;
-
- /* Whether to hide the child process's window. */
- int HideWindow;
-
- /* Whether to treat command lines as verbatim. */
- int Verbatim;
-
- /* Whether to merge stdout/stderr of the child. */
- int MergeOutput;
-
- /* Whether to create the process in a new process group. */
- int CreateProcessGroup;
-
- /* Mutex to protect the shared index used by threads to report data. */
- HANDLE SharedIndexMutex;
-
- /* Semaphore used by threads to signal data ready. */
- HANDLE Full;
-
- /* Whether we are currently deleting this kwsysProcess instance. */
- int Deleting;
-
- /* Data specific to each pipe and its thread. */
- kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];
-
- /* Name of files to which stdin and stdout pipes are attached. */
- char* PipeFileSTDIN;
- char* PipeFileSTDOUT;
- char* PipeFileSTDERR;
-
- /* Whether each pipe is shared with the parent process. */
- int PipeSharedSTDIN;
- int PipeSharedSTDOUT;
- int PipeSharedSTDERR;
-
- /* Native pipes provided by the user. */
- HANDLE PipeNativeSTDIN[2];
- HANDLE PipeNativeSTDOUT[2];
- HANDLE PipeNativeSTDERR[2];
-
- /* ------------- Data managed per call to Execute ------------- */
-
- /* The exceptional behavior that terminated the process, if any. */
- int ExitException;
-
- /* The process exit code. */
- DWORD ExitCode;
-
- /* The process return code, if any. */
- int ExitValue;
-
- /* Index of last pipe to report data, if any. */
- int CurrentIndex;
-
- /* Index shared by threads to report data. */
- int SharedIndex;
-
- /* The timeout length. */
- double Timeout;
-
- /* Time at which the child started. */
- kwsysProcessTime StartTime;
-
- /* Time at which the child will timeout. Negative for no timeout. */
- kwsysProcessTime TimeoutTime;
-
- /* Flag for whether the process was killed. */
- int Killed;
-
- /* Flag for whether the timeout expired. */
- int TimeoutExpired;
-
- /* Flag for whether the process has terminated. */
- int Terminated;
-
- /* The number of pipes still open during execution and while waiting
- for pipes to close after process termination. */
- int PipesLeft;
-
- /* Buffer for error messages. */
- char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
-
- /* Description for the ExitException. */
- char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
-
- /* Windows process information data. */
- PROCESS_INFORMATION* ProcessInformation;
-
- /* Data and process termination events for which to wait. */
- PHANDLE ProcessEvents;
- int ProcessEventsLength;
-
- /* Real working directory of our own process. */
- DWORD RealWorkingDirectoryLength;
- wchar_t* RealWorkingDirectory;
-
- /* Own handles for the child's ends of the pipes in the parent process.
- Used temporarily during process creation. */
- HANDLE PipeChildStd[3];
-};
-
-/*--------------------------------------------------------------------------*/
-kwsysProcess* kwsysProcess_New(void)
-{
- int i;
-
- /* Process control structure. */
- kwsysProcess* cp;
-
- /* Windows version number data. */
- OSVERSIONINFO osv;
-
- /* Initialize list of processes before we get any farther. It's especially
- important that the console Ctrl handler be added BEFORE starting the
- first process. This prevents the risk of an orphaned process being
- started by the main thread while the default Ctrl handler is in
- progress. */
- if(!kwsysProcessesInitialize())
- {
- return 0;
- }
-
- /* Allocate a process control structure. */
- cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
- if(!cp)
- {
- /* Could not allocate memory for the control structure. */
- return 0;
- }
- ZeroMemory(cp, sizeof(*cp));
-
- /* Share stdin with the parent process by default. */
- cp->PipeSharedSTDIN = 1;
-
- /* Set initial status. */
- cp->State = kwsysProcess_State_Starting;
-
- /* Choose a method of running the child based on version of
- windows. */
- ZeroMemory(&osv, sizeof(osv));
- osv.dwOSVersionInfoSize = sizeof(osv);
-#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
-# pragma warning (push)
-# ifdef __INTEL_COMPILER
-# pragma warning (disable:1478)
-# else
-# pragma warning (disable:4996)
-# endif
-#endif
- GetVersionEx(&osv);
-#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
-# pragma warning (pop)
-#endif
- if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
- {
- /* Win9x no longer supported. */
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* Initially no thread owns the mutex. Initialize semaphore to 1. */
- if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* Initially no data are available. Initialize semaphore to 0. */
- if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* Create the thread to read each pipe. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- DWORD dummy=0;
-
- /* Assign the thread its index. */
- cp->Pipe[i].Index = i;
-
- /* Give the thread a pointer back to the kwsysProcess instance. */
- cp->Pipe[i].Process = cp;
-
- /* No process is yet running. Initialize semaphore to 0. */
- if(!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* The pipe is not yet reset. Initialize semaphore to 0. */
- if(!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* The thread's buffer is initially empty. Initialize semaphore to 1. */
- if(!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* Create the reading thread. It will block immediately. The
- thread will not make deeply nested calls, so we need only a
- small stack. */
- if(!(cp->Pipe[i].Reader.Thread = CreateThread(0, 1024,
- kwsysProcessPipeThreadRead,
- &cp->Pipe[i], 0, &dummy)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* No process is yet running. Initialize semaphore to 0. */
- if(!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* The pipe is not yet reset. Initialize semaphore to 0. */
- if(!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* The waker should not wake immediately. Initialize semaphore to 0. */
- if(!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
-
- /* Create the waking thread. It will block immediately. The
- thread will not make deeply nested calls, so we need only a
- small stack. */
- if(!(cp->Pipe[i].Waker.Thread = CreateThread(0, 1024,
- kwsysProcessPipeThreadWake,
- &cp->Pipe[i], 0, &dummy)))
- {
- kwsysProcess_Delete(cp);
- return 0;
- }
- }
- for(i=0; i < 3; ++i)
- {
- cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
- }
-
- return cp;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Delete(kwsysProcess* cp)
-{
- int i;
-
- /* Make sure we have an instance. */
- if(!cp)
- {
- return;
- }
-
- /* If the process is executing, wait for it to finish. */
- if(cp->State == kwsysProcess_State_Executing)
- {
- if(cp->Detached)
- {
- kwsysProcess_Disown(cp);
- }
- else
- {
- kwsysProcess_WaitForExit(cp, 0);
- }
- }
-
- /* We are deleting the kwsysProcess instance. */
- cp->Deleting = 1;
-
- /* Terminate each of the threads. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- /* Terminate this reading thread. */
- if(cp->Pipe[i].Reader.Thread)
- {
- /* Signal the thread we are ready for it. It will terminate
- immediately since Deleting is set. */
- ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
-
- /* Wait for the thread to exit. */
- WaitForSingleObject(cp->Pipe[i].Reader.Thread, INFINITE);
-
- /* Close the handle to the thread. */
- kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread);
- }
-
- /* Terminate this waking thread. */
- if(cp->Pipe[i].Waker.Thread)
- {
- /* Signal the thread we are ready for it. It will terminate
- immediately since Deleting is set. */
- ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
-
- /* Wait for the thread to exit. */
- WaitForSingleObject(cp->Pipe[i].Waker.Thread, INFINITE);
-
- /* Close the handle to the thread. */
- kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread);
- }
-
- /* Cleanup the pipe's semaphores. */
- kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Go);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Reset);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset);
- }
-
- /* Close the shared semaphores. */
- kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
- kwsysProcessCleanupHandle(&cp->Full);
-
- /* Free memory. */
- kwsysProcess_SetCommand(cp, 0);
- kwsysProcess_SetWorkingDirectory(cp, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
- kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if(cp->CommandExitCodes)
- {
- free(cp->CommandExitCodes);
- }
- free(cp);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
-{
- int i;
- if(!cp)
- {
- return 0;
- }
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- free(cp->Commands[i]);
- }
- cp->NumberOfCommands = 0;
- if(cp->Commands)
- {
- free(cp->Commands);
- cp->Commands = 0;
- }
- if(command)
- {
- return kwsysProcess_AddCommand(cp, command);
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
-{
- int newNumberOfCommands;
- wchar_t** newCommands;
-
- /* Make sure we have a command to add. */
- if(!cp || !command || !*command)
- {
- return 0;
- }
-
-
- /* Allocate a new array for command pointers. */
- newNumberOfCommands = cp->NumberOfCommands + 1;
- if(!(newCommands = (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands)))
- {
- /* Out of memory. */
- return 0;
- }
-
- /* Copy any existing commands into the new array. */
- {
- int i;
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- newCommands[i] = cp->Commands[i];
- }
- }
-
- if (cp->Verbatim)
- {
- /* Copy the verbatim command line into the buffer. */
- newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
- }
- else
- {
- /* Encode the arguments so CommandLineToArgvW can decode
- them from the command line string in the child. */
- char buffer[32768]; /* CreateProcess max command-line length. */
- char* end = buffer + sizeof(buffer);
- char* out = buffer;
- char const* const* a;
- for (a = command; *a; ++a)
- {
- int quote = !**a; /* Quote the empty string. */
- int slashes = 0;
- char const* c;
- if (a != command && out != end) { *out++ = ' '; }
- for (c = *a; !quote && *c; ++c)
- { quote = (*c == ' ' || *c == '\t'); }
- if (quote && out != end) { *out++ = '"'; }
- for (c = *a; *c; ++c)
- {
- if (*c == '\\')
- {
- ++slashes;
- }
- else
- {
- if (*c == '"')
- {
- // Add n+1 backslashes to total 2n+1 before internal '"'.
- while(slashes-- >= 0 && out != end) { *out++ = '\\'; }
- }
- slashes = 0;
- }
- if (out != end) { *out++ = *c; }
- }
- if (quote)
- {
- // Add n backslashes to total 2n before ending '"'.
- while (slashes-- > 0 && out != end) { *out++ = '\\'; }
- if (out != end) { *out++ = '"'; }
- }
- }
- if(out != end)
- {
- *out = '\0';
- newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
- }
- else
- {
- newCommands[cp->NumberOfCommands] = 0;
- }
- }
- if (!newCommands[cp->NumberOfCommands])
- {
- /* Out of memory or command line too long. */
- free(newCommands);
- return 0;
- }
-
- /* Save the new array of commands. */
- free(cp->Commands);
- cp->Commands = newCommands;
- cp->NumberOfCommands = newNumberOfCommands;
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
-{
- if(!cp)
- {
- return;
- }
- cp->Timeout = timeout;
- if(cp->Timeout < 0)
- {
- cp->Timeout = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
-{
- if(!cp)
- {
- return 0;
- }
- if(cp->WorkingDirectory)
- {
- free(cp->WorkingDirectory);
- cp->WorkingDirectory = 0;
- }
- if(dir && dir[0])
- {
- wchar_t* wdir = kwsysEncoding_DupToWide(dir);
- /* We must convert the working directory to a full path. */
- DWORD length = GetFullPathNameW(wdir, 0, 0, 0);
- if(length > 0)
- {
- wchar_t* work_dir = malloc(length*sizeof(wchar_t));
- if(!work_dir)
- {
- free(wdir);
- return 0;
- }
- if(!GetFullPathNameW(wdir, length, work_dir, 0))
- {
- free(work_dir);
- free(wdir);
- return 0;
- }
- cp->WorkingDirectory = work_dir;
- }
- free(wdir);
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
-{
- char** pfile;
- if(!cp)
- {
- return 0;
- }
- switch(pipe)
- {
- case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
- case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
- case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
- default: return 0;
- }
- if(*pfile)
- {
- free(*pfile);
- *pfile = 0;
- }
- if(file)
- {
- *pfile = (char*)malloc(strlen(file)+1);
- if(!*pfile)
- {
- return 0;
- }
- strcpy(*pfile, file);
- }
-
- /* If we are redirecting the pipe, do not share it or use a native
- pipe. */
- if(*pfile)
- {
- kwsysProcess_SetPipeNative(cp, pipe, 0);
- kwsysProcess_SetPipeShared(cp, pipe, 0);
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
-{
- if(!cp)
- {
- return;
- }
-
- switch(pipe)
- {
- case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
- case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
- case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
- default: return;
- }
-
- /* If we are sharing the pipe, do not redirect it to a file or use a
- native pipe. */
- if(shared)
- {
- kwsysProcess_SetPipeFile(cp, pipe, 0);
- kwsysProcess_SetPipeNative(cp, pipe, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
-{
- HANDLE* pPipeNative = 0;
-
- if(!cp)
- {
- return;
- }
-
- switch(pipe)
- {
- case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
- case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
- case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
- default: return;
- }
-
- /* Copy the native pipe handles provided. */
- if(p)
- {
- pPipeNative[0] = p[0];
- pPipeNative[1] = p[1];
- }
- else
- {
- pPipeNative[0] = 0;
- pPipeNative[1] = 0;
- }
-
- /* If we are using a native pipe, do not share it or redirect it to
- a file. */
- if(p)
- {
- kwsysProcess_SetPipeFile(cp, pipe, 0);
- kwsysProcess_SetPipeShared(cp, pipe, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
-{
- if(!cp)
- {
- return 0;
- }
-
- switch(optionId)
- {
- case kwsysProcess_Option_Detach: return cp->OptionDetach;
- case kwsysProcess_Option_HideWindow: return cp->HideWindow;
- case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
- case kwsysProcess_Option_Verbatim: return cp->Verbatim;
- case kwsysProcess_Option_CreateProcessGroup:
- return cp->CreateProcessGroup;
- default: return 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
-{
- if(!cp)
- {
- return;
- }
-
- switch(optionId)
- {
- case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
- case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
- case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
- case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
- case kwsysProcess_Option_CreateProcessGroup:
- cp->CreateProcessGroup = value; break;
- default: break;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetState(kwsysProcess* cp)
-{
- return cp? cp->State : kwsysProcess_State_Error;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitException(kwsysProcess* cp)
-{
- return cp? cp->ExitException : kwsysProcess_Exception_Other;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitValue(kwsysProcess* cp)
-{
- return cp? cp->ExitValue : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_GetExitCode(kwsysProcess* cp)
-{
- return cp? cp->ExitCode : 0;
-}
-
-/*--------------------------------------------------------------------------*/
-const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
-{
- if(!cp)
- {
- return "Process management structure could not be allocated";
- }
- else if(cp->State == kwsysProcess_State_Error)
- {
- return cp->ErrorMessage;
- }
- return "Success";
-}
-
-/*--------------------------------------------------------------------------*/
-const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
-{
- if(!cp)
- {
- return "GetExceptionString called with NULL process management structure";
- }
- else if(cp->State == kwsysProcess_State_Exception)
- {
- return cp->ExitExceptionString;
- }
- return "No exception";
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Execute(kwsysProcess* cp)
-{
- int i;
-
- /* Do not execute a second time. */
- if(!cp || cp->State == kwsysProcess_State_Executing)
- {
- return;
- }
-
- /* Make sure we have something to run. */
- if(cp->NumberOfCommands < 1)
- {
- strcpy(cp->ErrorMessage, "No command");
- cp->State = kwsysProcess_State_Error;
- return;
- }
-
- /* Initialize the control structure for a new process. */
- if(!kwsysProcessInitialize(cp))
- {
- strcpy(cp->ErrorMessage, "Out of memory");
- cp->State = kwsysProcess_State_Error;
- return;
- }
-
- /* Save the real working directory of this process and change to
- the working directory for the child processes. This is needed
- to make pipe file paths evaluate correctly. */
- if(cp->WorkingDirectory)
- {
- if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
- cp->RealWorkingDirectory))
- {
- kwsysProcessCleanup(cp, GetLastError());
- return;
- }
- SetCurrentDirectoryW(cp->WorkingDirectory);
- }
-
-
- /* Setup the stdin pipe for the first process. */
- if(cp->PipeFileSTDIN)
- {
- /* Create a handle to read a file for stdin. */
- wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
- DWORD error;
- cp->PipeChildStd[0] =
- CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, 0, 0);
- error = GetLastError(); /* Check now in case free changes this. */
- free(wstdin);
- if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
- {
- kwsysProcessCleanup(cp, error);
- return;
- }
- }
- else if(cp->PipeSharedSTDIN)
- {
- /* Share this process's stdin with the child. */
- kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]);
- }
- else if(cp->PipeNativeSTDIN[0])
- {
- /* Use the provided native pipe. */
- kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]);
- }
- else
- {
- /* Explicitly give the child no stdin. */
- cp->PipeChildStd[0] = INVALID_HANDLE_VALUE;
- }
-
- /* Create the output pipe for the last process.
- We always create this so the pipe thread can run even if we
- do not end up giving the write end to the child below. */
- if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
- &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0))
- {
- kwsysProcessCleanup(cp, GetLastError());
- return;
- }
-
- if(cp->PipeFileSTDOUT)
- {
- /* Use a file for stdout. */
- DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
- cp->PipeFileSTDOUT);
- if(error)
- {
- kwsysProcessCleanup(cp, error);
- return;
- }
- }
- else if(cp->PipeSharedSTDOUT)
- {
- /* Use the parent stdout. */
- kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]);
- }
- else if(cp->PipeNativeSTDOUT[1])
- {
- /* Use the given handle for stdout. */
- kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]);
- }
- else
- {
- /* Use our pipe for stdout. Duplicate the handle since our waker
- thread will use the original. Do not make it inherited yet. */
- if(!DuplicateHandle(GetCurrentProcess(),
- cp->Pipe[KWSYSPE_PIPE_STDOUT].Write,
- GetCurrentProcess(), &cp->PipeChildStd[1],
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- kwsysProcessCleanup(cp, GetLastError());
- return;
- }
- }
-
- /* Create stderr pipe to be shared by all processes in the pipeline.
- We always create this so the pipe thread can run even if we do not
- end up giving the write end to the child below. */
- if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
- &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
- {
- kwsysProcessCleanup(cp, GetLastError());
- return;
- }
-
- if(cp->PipeFileSTDERR)
- {
- /* Use a file for stderr. */
- DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
- cp->PipeFileSTDERR);
- if(error)
- {
- kwsysProcessCleanup(cp, error);
- return;
- }
- }
- else if(cp->PipeSharedSTDERR)
- {
- /* Use the parent stderr. */
- kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]);
- }
- else if(cp->PipeNativeSTDERR[1])
- {
- /* Use the given handle for stderr. */
- kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]);
- }
- else
- {
- /* Use our pipe for stderr. Duplicate the handle since our waker
- thread will use the original. Do not make it inherited yet. */
- if(!DuplicateHandle(GetCurrentProcess(),
- cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
- GetCurrentProcess(), &cp->PipeChildStd[2],
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- kwsysProcessCleanup(cp, GetLastError());
- return;
- }
- }
-
- /* Create the pipeline of processes. */
- {
- /* Child startup control data. */
- kwsysProcessCreateInformation si;
- HANDLE nextStdInput = cp->PipeChildStd[0];
-
- /* Initialize startup info data. */
- ZeroMemory(&si, sizeof(si));
- si.StartupInfo.cb = sizeof(si.StartupInfo);
-
- /* Decide whether a child window should be shown. */
- si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
- si.StartupInfo.wShowWindow =
- (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
-
- /* Connect the child's output pipes to the threads. */
- si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
-
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- /* Setup the process's pipes. */
- si.hStdInput = nextStdInput;
- if (i == cp->NumberOfCommands-1)
- {
- /* The last child gets the overall stdout. */
- nextStdInput = INVALID_HANDLE_VALUE;
- si.hStdOutput = cp->PipeChildStd[1];
- }
- else
- {
- /* Create a pipe to sit between the children. */
- HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
- if (!CreatePipe(&p[0], &p[1], 0, 0))
- {
- DWORD error = GetLastError();
- if (nextStdInput != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupHandle(&nextStdInput);
- }
- kwsysProcessCleanup(cp, error);
- return;
- }
- nextStdInput = p[0];
- si.hStdOutput = p[1];
- }
- si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
-
- {
- DWORD error = kwsysProcessCreate(cp, i, &si);
-
- /* Close our copies of pipes used between children. */
- if (si.hStdInput != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupHandle(&si.hStdInput);
- }
- if (si.hStdOutput != cp->PipeChildStd[1])
- {
- kwsysProcessCleanupHandle(&si.hStdOutput);
- }
- if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput)
- {
- kwsysProcessCleanupHandle(&si.hStdError);
- }
- if (!error)
- {
- cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
- }
- else
- {
- if (nextStdInput != cp->PipeChildStd[0])
- {
- kwsysProcessCleanupHandle(&nextStdInput);
- }
- kwsysProcessCleanup(cp, error);
- return;
- }
- }
- }
- }
-
- /* The parent process does not need the child's pipe ends. */
- for (i=0; i < 3; ++i)
- {
- kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
- }
-
- /* Restore the working directory. */
- if(cp->RealWorkingDirectory)
- {
- SetCurrentDirectoryW(cp->RealWorkingDirectory);
- free(cp->RealWorkingDirectory);
- cp->RealWorkingDirectory = 0;
- }
-
- /* The timeout period starts now. */
- cp->StartTime = kwsysProcessTimeGetCurrent();
- cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
-
- /* All processes in the pipeline have been started in suspended
- mode. Resume them all now. */
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- ResumeThread(cp->ProcessInformation[i].hThread);
- }
-
- /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
- /* Tell the pipe threads that a process has started. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
- ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
- }
-
- /* We don't care about the children's main threads. */
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
- }
-
- /* No pipe has reported data. */
- cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
- cp->PipesLeft = KWSYSPE_PIPE_COUNT;
-
- /* The process has now started. */
- cp->State = kwsysProcess_State_Executing;
- cp->Detached = cp->OptionDetach;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Disown(kwsysProcess* cp)
-{
- int i;
-
- /* Make sure we are executing a detached process. */
- if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
- cp->TimeoutExpired || cp->Killed || cp->Terminated)
- {
- return;
- }
-
- /* Disable the reading threads. */
- kwsysProcessDisablePipeThreads(cp);
-
- /* Wait for all pipe threads to reset. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
- WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
- }
-
- /* We will not wait for exit, so cleanup now. */
- kwsysProcessCleanup(cp, 0);
-
- /* The process has been disowned. */
- cp->State = kwsysProcess_State_Disowned;
-}
-
-/*--------------------------------------------------------------------------*/
-
-int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
- double* userTimeout)
-{
- kwsysProcessTime userStartTime;
- kwsysProcessTime timeoutLength;
- kwsysProcessTime timeoutTime;
- DWORD timeout;
- int user;
- int done = 0;
- int expired = 0;
- int pipeId = kwsysProcess_Pipe_None;
- DWORD w;
-
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
- cp->TimeoutExpired)
- {
- return kwsysProcess_Pipe_None;
- }
-
- /* Record the time at which user timeout period starts. */
- userStartTime = kwsysProcessTimeGetCurrent();
-
- /* Calculate the time at which a timeout will expire, and whether it
- is the user or process timeout. */
- user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
-
- /* Loop until we have a reason to return. */
- while(!done && cp->PipesLeft > 0)
- {
- /* If we previously got data from a thread, let it know we are
- done with the data. */
- if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
- {
- KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
- ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
- cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
- }
-
- /* Setup a timeout if required. */
- if(kwsysProcessGetTimeoutLeft(&timeoutTime, user?userTimeout:0,
- &timeoutLength))
- {
- /* Timeout has already expired. */
- expired = 1;
- break;
- }
- if(timeoutTime.QuadPart < 0)
- {
- timeout = INFINITE;
- }
- else
- {
- timeout = kwsysProcessTimeToDWORD(timeoutLength);
- }
-
- /* Wait for a pipe's thread to signal or a process to terminate. */
- w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents,
- 0, timeout);
- if(w == WAIT_TIMEOUT)
- {
- /* Timeout has expired. */
- expired = 1;
- done = 1;
- }
- else if(w == WAIT_OBJECT_0)
- {
- /* Save the index of the reporting thread and release the mutex.
- The thread will block until we signal its Empty mutex. */
- cp->CurrentIndex = cp->SharedIndex;
- ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
-
- /* Data are available or a pipe closed. */
- if(cp->Pipe[cp->CurrentIndex].Closed)
- {
- /* The pipe closed at the write end. Close the read end and
- inform the wakeup thread it is done with this process. */
- kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
- ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0);
- KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex));
- --cp->PipesLeft;
- }
- else if(data && length)
- {
- /* Report this data. */
- *data = cp->Pipe[cp->CurrentIndex].DataBuffer;
- *length = cp->Pipe[cp->CurrentIndex].DataLength;
- switch(cp->CurrentIndex)
- {
- case KWSYSPE_PIPE_STDOUT:
- pipeId = kwsysProcess_Pipe_STDOUT; break;
- case KWSYSPE_PIPE_STDERR:
- pipeId = kwsysProcess_Pipe_STDERR; break;
- }
- done = 1;
- }
- }
- else
- {
- /* A process has terminated. */
- kwsysProcessDestroy(cp, w-WAIT_OBJECT_0);
- }
- }
-
- /* Update the user timeout. */
- if(userTimeout)
- {
- kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
- userStartTime);
- double d = kwsysProcessTimeToDouble(difference);
- *userTimeout -= d;
- if(*userTimeout < 0)
- {
- *userTimeout = 0;
- }
- }
-
- /* Check what happened. */
- if(pipeId)
- {
- /* Data are ready on a pipe. */
- return pipeId;
- }
- else if(expired)
- {
- /* A timeout has expired. */
- if(user)
- {
- /* The user timeout has expired. It has no time left. */
- return kwsysProcess_Pipe_Timeout;
- }
- else
- {
- /* The process timeout has expired. Kill the child now. */
- KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n"));
- kwsysProcess_Kill(cp);
- cp->TimeoutExpired = 1;
- cp->Killed = 0;
- return kwsysProcess_Pipe_None;
- }
- }
- else
- {
- /* The children have terminated and no more data are available. */
- return kwsysProcess_Pipe_None;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
-{
- int i;
- int pipe;
-
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing)
- {
- return 1;
- }
-
- /* Wait for the process to terminate. Ignore all data. */
- while((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
- {
- if(pipe == kwsysProcess_Pipe_Timeout)
- {
- /* The user timeout has expired. */
- return 0;
- }
- }
-
- KWSYSPE_DEBUG((stderr, "no more data\n"));
-
- /* When the last pipe closes in WaitForData, the loop terminates
- without releasing the pipe's thread. Release it now. */
- if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
- {
- KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
- ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
- cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
- }
-
- /* Wait for all pipe threads to reset. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i));
- WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
- KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i));
- WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
- }
-
- /* ---- It is now safe again to call kwsysProcessCleanup. ----- */
- /* Close all the pipes. */
- kwsysProcessCleanup(cp, 0);
-
- /* Determine the outcome. */
- if(cp->Killed)
- {
- /* We killed the child. */
- cp->State = kwsysProcess_State_Killed;
- }
- else if(cp->TimeoutExpired)
- {
- /* The timeout expired. */
- cp->State = kwsysProcess_State_Expired;
- }
- else
- {
- /* The children exited. Report the outcome of the last process. */
- cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands-1];
- if((cp->ExitCode & 0xF0000000) == 0xC0000000)
- {
- /* Child terminated due to exceptional behavior. */
- cp->State = kwsysProcess_State_Exception;
- cp->ExitValue = 1;
- kwsysProcessSetExitException(cp, cp->ExitCode);
- }
- else
- {
- /* Child exited without exception. */
- cp->State = kwsysProcess_State_Exited;
- cp->ExitException = kwsysProcess_Exception_None;
- cp->ExitValue = cp->ExitCode;
- }
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Interrupt(kwsysProcess* cp)
-{
- int i;
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
- cp->Killed)
- {
- KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
- return;
- }
-
- /* Skip actually interrupting the child if it has already terminated. */
- if(cp->Terminated)
- {
- KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
- return;
- }
-
- /* Interrupt the children. */
- if (cp->CreateProcessGroup)
- {
- if(cp->ProcessInformation)
- {
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- /* Make sure the process handle isn't closed (e.g. from disowning). */
- if(cp->ProcessInformation[i].hProcess)
- {
- /* The user created a process group for this process. The group ID
- is the process ID for the original process in the group. Note
- that we have to use Ctrl+Break: Ctrl+C is not allowed for process
- groups. */
- GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
- cp->ProcessInformation[i].dwProcessId);
- }
- }
- }
- }
- else
- {
- /* No process group was created. Kill our own process group... */
- GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcess_Kill(kwsysProcess* cp)
-{
- int i;
- /* Make sure we are executing a process. */
- if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
- cp->Killed)
- {
- KWSYSPE_DEBUG((stderr, "kill: child not executing\n"));
- return;
- }
-
- /* Disable the reading threads. */
- KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n"));
- kwsysProcessDisablePipeThreads(cp);
-
- /* Skip actually killing the child if it has already terminated. */
- if(cp->Terminated)
- {
- KWSYSPE_DEBUG((stderr, "kill: child already terminated\n"));
- return;
- }
-
- /* Kill the children. */
- cp->Killed = 1;
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
- /* Remove from global list of processes and close handles. */
- kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
- kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
- kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
- }
-
- /* We are killing the children and ignoring all data. Do not wait
- for them to exit. */
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*
- Function executed for each pipe's thread. Argument is a pointer to
- the kwsysProcessPipeData instance for this thread.
-*/
-DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd)
-{
- kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
- kwsysProcess* cp = td->Process;
-
- /* Wait for a process to be ready. */
- while((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting))
- {
- /* Read output from the process for this thread's pipe. */
- kwsysProcessPipeThreadReadPipe(cp, td);
-
- /* Signal the main thread we have reset for a new process. */
- ReleaseSemaphore(td->Reader.Reset, 1, 0);
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*
- Function called in each pipe's thread to handle data for one
- execution of a subprocess.
-*/
-void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
-{
- /* Wait for space in the thread's buffer. */
- while((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)),
- WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed))
- {
- KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index));
-
- /* Read data from the pipe. This may block until data are available. */
- if(!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
- &td->DataLength, 0))
- {
- if(GetLastError() != ERROR_BROKEN_PIPE)
- {
- /* UNEXPECTED failure to read the pipe. */
- }
-
- /* The pipe closed. There are no more data to read. */
- td->Closed = 1;
- KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index));
- }
-
- KWSYSPE_DEBUG((stderr, "read %d\n", td->Index));
-
- /* Wait for our turn to be handled by the main thread. */
- WaitForSingleObject(cp->SharedIndexMutex, INFINITE);
-
- KWSYSPE_DEBUG((stderr, "reporting read %d\n", td->Index));
-
- /* Tell the main thread we have something to report. */
- cp->SharedIndex = td->Index;
- ReleaseSemaphore(cp->Full, 1, 0);
- }
-
- /* We were signalled to exit with our buffer empty. Reset the
- mutex for a new process. */
- KWSYSPE_DEBUG((stderr, "self releasing reader %d\n", td->Index));
- ReleaseSemaphore(td->Reader.Go, 1, 0);
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*
- Function executed for each pipe's thread. Argument is a pointer to
- the kwsysProcessPipeData instance for this thread.
-*/
-DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd)
-{
- kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
- kwsysProcess* cp = td->Process;
-
- /* Wait for a process to be ready. */
- while((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting))
- {
- /* Wait for a possible wakeup. */
- kwsysProcessPipeThreadWakePipe(cp, td);
-
- /* Signal the main thread we have reset for a new process. */
- ReleaseSemaphore(td->Waker.Reset, 1, 0);
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*
- Function called in each pipe's thread to handle reading thread
- wakeup for one execution of a subprocess.
-*/
-void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td)
-{
- (void)cp;
-
- /* Wait for a possible wake command. */
- KWSYSPE_DEBUG((stderr, "wait for wake %d\n", td->Index));
- WaitForSingleObject(td->Waker.Go, INFINITE);
- KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index));
-
- /* If the pipe is not closed, we need to wake up the reading thread. */
- if(!td->Closed)
- {
- DWORD dummy;
- KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index));
- WriteFile(td->Write, "", 1, &dummy, 0);
- KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index));
- }
-}
-
-/*--------------------------------------------------------------------------*/
-/* Initialize a process control structure for kwsysProcess_Execute. */
-int kwsysProcessInitialize(kwsysProcess* cp)
-{
- /* Reset internal status flags. */
- cp->TimeoutExpired = 0;
- cp->Terminated = 0;
- cp->Killed = 0;
- cp->ExitException = kwsysProcess_Exception_None;
- cp->ExitCode = 1;
- cp->ExitValue = 1;
-
- /* Reset error data. */
- cp->ErrorMessage[0] = 0;
- strcpy(cp->ExitExceptionString, "No exception");
-
- /* Allocate process information for each process. */
- cp->ProcessInformation =
- (PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) *
- cp->NumberOfCommands);
- if(!cp->ProcessInformation)
- {
- return 0;
- }
- ZeroMemory(cp->ProcessInformation,
- sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
- if(cp->CommandExitCodes)
- {
- free(cp->CommandExitCodes);
- }
- cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD)*cp->NumberOfCommands);
- if(!cp->CommandExitCodes)
- {
- return 0;
- }
- ZeroMemory(cp->CommandExitCodes, sizeof(DWORD)*cp->NumberOfCommands);
-
- /* Allocate event wait array. The first event is cp->Full, the rest
- are the process termination events. */
- cp->ProcessEvents = (PHANDLE)malloc(sizeof(HANDLE)*(cp->NumberOfCommands+1));
- if(!cp->ProcessEvents)
- {
- return 0;
- }
- ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands+1));
- cp->ProcessEvents[0] = cp->Full;
- cp->ProcessEventsLength = cp->NumberOfCommands+1;
-
- /* Allocate space to save the real working directory of this process. */
- if(cp->WorkingDirectory)
- {
- cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0);
- if(cp->RealWorkingDirectoryLength > 0)
- {
- cp->RealWorkingDirectory = malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t));
- if(!cp->RealWorkingDirectory)
- {
- return 0;
- }
- }
- }
- {
- int i;
- for (i=0; i < 3; ++i)
- {
- cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
- }
- }
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
-{
- DWORD flags;
-
- /* Check whether the handle is valid for this process. */
- if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags))
- {
- /* Use the handle as-is if it is already inherited. */
- if (flags & HANDLE_FLAG_INHERIT)
- {
- *out = in;
- return ERROR_SUCCESS;
- }
-
- /* Create an inherited copy of this handle. */
- if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out,
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- {
- return ERROR_SUCCESS;
- }
- else
- {
- return GetLastError();
- }
- }
- else
- {
- /* The given handle is not valid for this process. Some child
- processes may break if they do not have a valid standard handle,
- so open NUL to give to the child. */
- SECURITY_ATTRIBUTES sa;
- ZeroMemory(&sa, sizeof(sa));
- sa.nLength = (DWORD)sizeof(sa);
- sa.bInheritHandle = 1;
- *out = CreateFileW(L"NUL",
- (isStdIn ? GENERIC_READ :
- (GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- &sa, OPEN_EXISTING, 0, 0);
- return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
- }
-}
-
-/*--------------------------------------------------------------------------*/
-DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si)
-{
- DWORD creationFlags;
- DWORD error = ERROR_SUCCESS;
-
- /* Check if we are currently exiting. */
- if (!kwsysTryEnterCreateProcessSection())
- {
- /* The Ctrl handler is currently working on exiting our process. Rather
- than return an error code, which could cause incorrect conclusions to be
- reached by the caller, we simply hang. (For example, a CMake try_run
- configure step might cause the project to configure wrong.) */
- Sleep(INFINITE);
- }
-
- /* Create the child in a suspended state so we can wait until all
- children have been created before running any one. */
- creationFlags = CREATE_SUSPENDED;
- if (cp->CreateProcessGroup)
- {
- creationFlags |= CREATE_NEW_PROCESS_GROUP;
- }
-
- /* Create inherited copies of the handles. */
- (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
- si->hStdInput, 1)) ||
- (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
- si->hStdOutput, 0)) ||
- (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
- si->hStdError, 0)) ||
- /* Create the process. */
- (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0,
- 0, &si->StartupInfo, &cp->ProcessInformation[index]) &&
- (error = GetLastError()));
-
- /* Close the inherited copies of the handles. */
- if (si->StartupInfo.hStdInput != si->hStdInput)
- {
- kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
- }
- if (si->StartupInfo.hStdOutput != si->hStdOutput)
- {
- kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
- }
- if (si->StartupInfo.hStdError != si->hStdError)
- {
- kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
- }
-
- /* Add the process to the global list of processes. */
- if (!error &&
- !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
- cp->ProcessInformation[index].dwProcessId, cp->CreateProcessGroup))
- {
- /* This failed for some reason. Kill the suspended process. */
- TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
- /* And clean up... */
- kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
- kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
- strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
- error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason. */
- }
-
- /* If the console Ctrl handler is waiting for us, this will release it... */
- kwsysLeaveCreateProcessSection();
- return error;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessDestroy(kwsysProcess* cp, int event)
-{
- int i;
- int index;
-
- /* Find the process index for the termination event. */
- for(index=0; index < cp->NumberOfCommands; ++index)
- {
- if(cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event])
- {
- break;
- }
- }
-
- /* Check the exit code of the process. */
- GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
- &cp->CommandExitCodes[index]);
-
- /* Remove from global list of processes. */
- kwsysProcessesRemove(cp->ProcessInformation[index].hProcess);
-
- /* Close the process handle for the terminated process. */
- kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
-
- /* Remove the process from the available events. */
- cp->ProcessEventsLength -= 1;
- for(i=event; i < cp->ProcessEventsLength; ++i)
- {
- cp->ProcessEvents[i] = cp->ProcessEvents[i+1];
- }
-
- /* Check if all processes have terminated. */
- if(cp->ProcessEventsLength == 1)
- {
- cp->Terminated = 1;
-
- /* Close our copies of the pipe write handles so the pipe threads
- can detect end-of-data. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- /* TODO: If the child created its own child (our grandchild)
- which inherited a copy of the pipe write-end then the pipe
- may not close and we will still need the waker write pipe.
- However we still want to be able to detect end-of-data in the
- normal case. The reader thread will have to switch to using
- PeekNamedPipe to read the last bit of data from the pipe
- without blocking. This is equivalent to using a non-blocking
- read on posix. */
- KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i));
- kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
-{
- HANDLE fout;
- wchar_t* wname;
- DWORD error;
- if(!name)
- {
- return ERROR_INVALID_PARAMETER;
- }
-
- /* Close the existing handle. */
- kwsysProcessCleanupHandle(phandle);
-
- /* Create a handle to write a file for the pipe. */
- wname = kwsysEncoding_DupToWide(name);
- fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0,
- CREATE_ALWAYS, 0, 0);
- error = GetLastError();
- free(wname);
- if(fout == INVALID_HANDLE_VALUE)
- {
- return error;
- }
-
- /* Assign the replacement handle. */
- *phandle = fout;
- return ERROR_SUCCESS;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
-{
- /* Close the existing handle. */
- kwsysProcessCleanupHandle(handle);
- /* Store the new standard handle. */
- *handle = GetStdHandle(nStdHandle);
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle)
-{
- /* Close the existing handle. */
- kwsysProcessCleanupHandle(handle);
- /* Store the new given handle. */
- *handle = native;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* Close the given handle if it is open. Reset its value to 0. */
-void kwsysProcessCleanupHandle(PHANDLE h)
-{
- if(h && *h && *h != INVALID_HANDLE_VALUE &&
- *h != GetStdHandle(STD_INPUT_HANDLE) &&
- *h != GetStdHandle(STD_OUTPUT_HANDLE) &&
- *h != GetStdHandle(STD_ERROR_HANDLE))
- {
- CloseHandle(*h);
- *h = INVALID_HANDLE_VALUE;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* Close all handles created by kwsysProcess_Execute. */
-void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
-{
- int i;
- /* If this is an error case, report the error. */
- if(error)
- {
- /* Construct an error message if one has not been provided already. */
- if(cp->ErrorMessage[0] == 0)
- {
- /* Format the error message. */
- wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
- DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0);
- if(length < 1)
- {
- /* FormatMessage failed. Use a default message. */
- _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
- "Process execution failed with error 0x%X. "
- "FormatMessage failed with error 0x%X",
- error, GetLastError());
- }
- if(!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
- KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL))
- {
- /* WideCharToMultiByte failed. Use a default message. */
- _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
- "Process execution failed with error 0x%X. "
- "WideCharToMultiByte failed with error 0x%X",
- error, GetLastError());
- }
- }
-
- /* Remove trailing period and newline, if any. */
- kwsysProcessCleanErrorMessage(cp);
-
- /* Set the error state. */
- cp->State = kwsysProcess_State_Error;
-
- /* Cleanup any processes already started in a suspended state. */
- if(cp->ProcessInformation)
- {
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- if(cp->ProcessInformation[i].hProcess)
- {
- TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
- WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
- }
- }
- for(i=0; i < cp->NumberOfCommands; ++i)
- {
- /* Remove from global list of processes and close handles. */
- kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
- kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
- kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
- }
- }
-
- /* Restore the working directory. */
- if(cp->RealWorkingDirectory)
- {
- SetCurrentDirectoryW(cp->RealWorkingDirectory);
- }
- }
-
- /* Free memory. */
- if(cp->ProcessInformation)
- {
- free(cp->ProcessInformation);
- cp->ProcessInformation = 0;
- }
- if(cp->ProcessEvents)
- {
- free(cp->ProcessEvents);
- cp->ProcessEvents = 0;
- }
- if(cp->RealWorkingDirectory)
- {
- free(cp->RealWorkingDirectory);
- cp->RealWorkingDirectory = 0;
- }
-
- /* Close each pipe. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
- kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
- cp->Pipe[i].Closed = 0;
- }
- for(i=0; i < 3; ++i)
- {
- kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
-{
- /* Remove trailing period and newline, if any. */
- size_t length = strlen(cp->ErrorMessage);
- if(cp->ErrorMessage[length-1] == '\n')
- {
- cp->ErrorMessage[length-1] = 0;
- --length;
- if(length > 0 && cp->ErrorMessage[length-1] == '\r')
- {
- cp->ErrorMessage[length-1] = 0;
- --length;
- }
- }
- if(length > 0 && cp->ErrorMessage[length-1] == '.')
- {
- cp->ErrorMessage[length-1] = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-/* Get the time at which either the process or user timeout will
- expire. Returns 1 if the user timeout is first, and 0 otherwise. */
-int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
- kwsysProcessTime* timeoutTime)
-{
- /* The first time this is called, we need to calculate the time at
- which the child will timeout. */
- if(cp->Timeout && cp->TimeoutTime.QuadPart < 0)
- {
- kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
- cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
- }
-
- /* Start with process timeout. */
- *timeoutTime = cp->TimeoutTime;
-
- /* Check if the user timeout is earlier. */
- if(userTimeout)
- {
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
- kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
- userTimeoutLength);
- if(timeoutTime->QuadPart < 0 ||
- kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
- {
- *timeoutTime = userTimeoutTime;
- return 1;
- }
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Get the length of time before the given timeout time arrives.
- Returns 1 if the time has already arrived, and 0 otherwise. */
-int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
- kwsysProcessTime* timeoutLength)
-{
- if(timeoutTime->QuadPart < 0)
- {
- /* No timeout time has been requested. */
- return 0;
- }
- else
- {
- /* Calculate the remaining time. */
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- *timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime);
-
- if(timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0)
- {
- /* Caller has explicitly requested a zero timeout. */
- timeoutLength->QuadPart = 0;
- }
-
- if(timeoutLength->QuadPart < 0)
- {
- /* Timeout has already expired. */
- return 1;
- }
- else
- {
- /* There is some time left. */
- return 0;
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-kwsysProcessTime kwsysProcessTimeGetCurrent()
-{
- kwsysProcessTime current;
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- current.LowPart = ft.dwLowDateTime;
- current.HighPart = ft.dwHighDateTime;
- return current;
-}
-
-/*--------------------------------------------------------------------------*/
-DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t)
-{
- return (DWORD)(t.QuadPart * 0.0001);
-}
-
-/*--------------------------------------------------------------------------*/
-double kwsysProcessTimeToDouble(kwsysProcessTime t)
-{
- return t.QuadPart * 0.0000001;
-}
-
-/*--------------------------------------------------------------------------*/
-kwsysProcessTime kwsysProcessTimeFromDouble(double d)
-{
- kwsysProcessTime t;
- t.QuadPart = (LONGLONG)(d*10000000);
- return t;
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- return in1.QuadPart < in2.QuadPart;
-}
-
-/*--------------------------------------------------------------------------*/
-kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- kwsysProcessTime out;
- out.QuadPart = in1.QuadPart + in2.QuadPart;
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
-{
- kwsysProcessTime out;
- out.QuadPart = in1.QuadPart - in2.QuadPart;
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-#define KWSYSPE_CASE(type, str) \
- cp->ExitException = kwsysProcess_Exception_##type; \
- strcpy(cp->ExitExceptionString, str)
-static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
-{
- switch (code)
- {
- case STATUS_CONTROL_C_EXIT:
- KWSYSPE_CASE(Interrupt, "User interrupt"); break;
-
- case STATUS_FLOAT_DENORMAL_OPERAND:
- KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)"); break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- KWSYSPE_CASE(Numerical, "Divide-by-zero"); break;
- case STATUS_FLOAT_INEXACT_RESULT:
- KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)"); break;
- case STATUS_FLOAT_INVALID_OPERATION:
- KWSYSPE_CASE(Numerical, "Invalid floating-point operation"); break;
- case STATUS_FLOAT_OVERFLOW:
- KWSYSPE_CASE(Numerical, "Floating-point overflow"); break;
- case STATUS_FLOAT_STACK_CHECK:
- KWSYSPE_CASE(Numerical, "Floating-point stack check failed"); break;
- case STATUS_FLOAT_UNDERFLOW:
- KWSYSPE_CASE(Numerical, "Floating-point underflow"); break;
-#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
- case STATUS_FLOAT_MULTIPLE_FAULTS:
- KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)"); break;
-#endif
-#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
- case STATUS_FLOAT_MULTIPLE_TRAPS:
- KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)"); break;
-#endif
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- KWSYSPE_CASE(Numerical, "Integer divide-by-zero"); break;
- case STATUS_INTEGER_OVERFLOW:
- KWSYSPE_CASE(Numerical, "Integer overflow"); break;
-
- case STATUS_DATATYPE_MISALIGNMENT:
- KWSYSPE_CASE(Fault, "Datatype misalignment"); break;
- case STATUS_ACCESS_VIOLATION:
- KWSYSPE_CASE(Fault, "Access violation"); break;
- case STATUS_IN_PAGE_ERROR:
- KWSYSPE_CASE(Fault, "In-page error"); break;
- case STATUS_INVALID_HANDLE:
- KWSYSPE_CASE(Fault, "Invalid hanlde"); break;
- case STATUS_NONCONTINUABLE_EXCEPTION:
- KWSYSPE_CASE(Fault, "Noncontinuable exception"); break;
- case STATUS_INVALID_DISPOSITION:
- KWSYSPE_CASE(Fault, "Invalid disposition"); break;
- case STATUS_ARRAY_BOUNDS_EXCEEDED:
- KWSYSPE_CASE(Fault, "Array bounds exceeded"); break;
- case STATUS_STACK_OVERFLOW:
- KWSYSPE_CASE(Fault, "Stack overflow"); break;
-
- case STATUS_ILLEGAL_INSTRUCTION:
- KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
- case STATUS_PRIVILEGED_INSTRUCTION:
- KWSYSPE_CASE(Illegal, "Privileged instruction"); break;
-
- case STATUS_NO_MEMORY:
- default:
- cp->ExitException = kwsysProcess_Exception_Other;
- _snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code);
- break;
- }
-}
-#undef KWSYSPE_CASE
-
-typedef struct kwsysProcess_List_s kwsysProcess_List;
-static kwsysProcess_List* kwsysProcess_List_New(void);
-static void kwsysProcess_List_Delete(kwsysProcess_List* self);
-static int kwsysProcess_List_Update(kwsysProcess_List* self);
-static int kwsysProcess_List_NextProcess(kwsysProcess_List* self);
-static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self);
-static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self);
-
-/*--------------------------------------------------------------------------*/
-/* Windows NT 4 API definitions. */
-#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
-typedef LONG NTSTATUS;
-typedef LONG KPRIORITY;
-typedef struct _UNICODE_STRING UNICODE_STRING;
-struct _UNICODE_STRING
-{
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-};
-
-/* The process information structure. Declare only enough to get
- process identifiers. The rest may be ignored because we use the
- NextEntryDelta to move through an array of instances. */
-typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
-typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
-struct _SYSTEM_PROCESS_INFORMATION
-{
- ULONG NextEntryDelta;
- ULONG ThreadCount;
- ULONG Reserved1[6];
- LARGE_INTEGER CreateTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER KernelTime;
- UNICODE_STRING ProcessName;
- KPRIORITY BasePriority;
- ULONG ProcessId;
- ULONG InheritedFromProcessId;
-};
-
-/*--------------------------------------------------------------------------*/
-/* Toolhelp32 API definitions. */
-#define TH32CS_SNAPPROCESS 0x00000002
-#if defined(_WIN64)
-typedef unsigned __int64 ProcessULONG_PTR;
-#else
-typedef unsigned long ProcessULONG_PTR;
-#endif
-typedef struct tagPROCESSENTRY32 PROCESSENTRY32;
-typedef PROCESSENTRY32* LPPROCESSENTRY32;
-struct tagPROCESSENTRY32
-{
- DWORD dwSize;
- DWORD cntUsage;
- DWORD th32ProcessID;
- ProcessULONG_PTR th32DefaultHeapID;
- DWORD th32ModuleID;
- DWORD cntThreads;
- DWORD th32ParentProcessID;
- LONG pcPriClassBase;
- DWORD dwFlags;
- char szExeFile[MAX_PATH];
-};
-
-/*--------------------------------------------------------------------------*/
-/* Windows API function types. */
-typedef HANDLE (WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
-typedef BOOL (WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
-typedef BOOL (WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
-typedef NTSTATUS (WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID,
- ULONG, PULONG);
-
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
-static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self);
-static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self);
-static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self);
-static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self);
-static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self);
-static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self);
-static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self);
-static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self);
-static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self);
-static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self);
-static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self);
-
-struct kwsysProcess_List_s
-{
- /* Implementation switches at runtime based on version of Windows. */
- int NT4;
-
- /* Implementation functions and data for NT 4. */
- ZwQuerySystemInformationType P_ZwQuerySystemInformation;
- char* Buffer;
- int BufferSize;
- PSYSTEM_PROCESS_INFORMATION CurrentInfo;
-
- /* Implementation functions and data for other Windows versions. */
- CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot;
- Process32FirstType P_Process32First;
- Process32NextType P_Process32Next;
- HANDLE Snapshot;
- PROCESSENTRY32 CurrentEntry;
-};
-
-/*--------------------------------------------------------------------------*/
-static kwsysProcess_List* kwsysProcess_List_New(void)
-{
- OSVERSIONINFO osv;
- kwsysProcess_List* self;
-
- /* Allocate and initialize the list object. */
- if(!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List))))
- {
- return 0;
- }
- memset(self, 0, sizeof(*self));
-
- /* Select an implementation. */
- ZeroMemory(&osv, sizeof(osv));
- osv.dwOSVersionInfoSize = sizeof(osv);
-#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
-# pragma warning (push)
-# ifdef __INTEL_COMPILER
-# pragma warning (disable:1478)
-# else
-# pragma warning (disable:4996)
-# endif
-#endif
- GetVersionEx(&osv);
-#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
-# pragma warning (pop)
-#endif
- self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
- osv.dwMajorVersion < 5)? 1:0;
-
- /* Initialize the selected implementation. */
- if(!(self->NT4?
- kwsysProcess_List__New_NT4(self) :
- kwsysProcess_List__New_Snapshot(self)))
- {
- kwsysProcess_List_Delete(self);
- return 0;
- }
-
- /* Update to the current set of processes. */
- if(!kwsysProcess_List_Update(self))
- {
- kwsysProcess_List_Delete(self);
- return 0;
- }
- return self;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcess_List_Delete(kwsysProcess_List* self)
-{
- if(self)
- {
- if(self->NT4)
- {
- kwsysProcess_List__Delete_NT4(self);
- }
- else
- {
- kwsysProcess_List__Delete_Snapshot(self);
- }
- free(self);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List_Update(kwsysProcess_List* self)
-{
- return self? (self->NT4?
- kwsysProcess_List__Update_NT4(self) :
- kwsysProcess_List__Update_Snapshot(self)) : 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
-{
- return self? (self->NT4?
- kwsysProcess_List__GetProcessId_NT4(self) :
- kwsysProcess_List__GetProcessId_Snapshot(self)) : -1;
-
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
-{
- return self? (self->NT4?
- kwsysProcess_List__GetParentId_NT4(self) :
- kwsysProcess_List__GetParentId_Snapshot(self)) : -1;
-
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
-{
- return (self? (self->NT4?
- kwsysProcess_List__Next_NT4(self) :
- kwsysProcess_List__Next_Snapshot(self)) : 0);
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
-{
- /* Get a handle to the NT runtime module that should already be
- loaded in this program. This does not actually increment the
- reference count to the module so we do not need to close the
- handle. */
- HMODULE hNT = GetModuleHandleW(L"ntdll.dll");
- if(hNT)
- {
- /* Get pointers to the needed API functions. */
- self->P_ZwQuerySystemInformation =
- ((ZwQuerySystemInformationType)
- GetProcAddress(hNT, "ZwQuerySystemInformation"));
- }
- if(!self->P_ZwQuerySystemInformation)
- {
- return 0;
- }
-
- /* Allocate an initial process information buffer. */
- self->BufferSize = 32768;
- self->Buffer = (char*)malloc(self->BufferSize);
- return self->Buffer? 1:0;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
-{
- /* Free the process information buffer. */
- if(self->Buffer)
- {
- free(self->Buffer);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
-{
- self->CurrentInfo = 0;
- for(;;)
- {
- /* Query number 5 is for system process list. */
- NTSTATUS status =
- self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
- if(status == STATUS_INFO_LENGTH_MISMATCH)
- {
- /* The query requires a bigger buffer. */
- int newBufferSize = self->BufferSize * 2;
- char* newBuffer = (char*)malloc(newBufferSize);
- if(newBuffer)
- {
- free(self->Buffer);
- self->Buffer = newBuffer;
- self->BufferSize = newBufferSize;
- }
- else
- {
- return 0;
- }
- }
- else if(status >= 0)
- {
- /* The query succeeded. Initialize traversal of the process list. */
- self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
- return 1;
- }
- else
- {
- /* The query failed. */
- return 0;
- }
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
-{
- if(self->CurrentInfo)
- {
- if(self->CurrentInfo->NextEntryDelta > 0)
- {
- self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)
- ((char*)self->CurrentInfo +
- self->CurrentInfo->NextEntryDelta));
- return 1;
- }
- self->CurrentInfo = 0;
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
-{
- return self->CurrentInfo? self->CurrentInfo->ProcessId : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
-{
- return self->CurrentInfo? self->CurrentInfo->InheritedFromProcessId : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
-{
- /* Get a handle to the Windows runtime module that should already be
- loaded in this program. This does not actually increment the
- reference count to the module so we do not need to close the
- handle. */
- HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
- if(hKernel)
- {
- self->P_CreateToolhelp32Snapshot =
- ((CreateToolhelp32SnapshotType)
- GetProcAddress(hKernel, "CreateToolhelp32Snapshot"));
- self->P_Process32First =
- ((Process32FirstType)
- GetProcAddress(hKernel, "Process32First"));
- self->P_Process32Next =
- ((Process32NextType)
- GetProcAddress(hKernel, "Process32Next"));
- }
- return (self->P_CreateToolhelp32Snapshot &&
- self->P_Process32First &&
- self->P_Process32Next)? 1:0;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
-{
- if(self->Snapshot)
- {
- CloseHandle(self->Snapshot);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
-{
- if(self->Snapshot)
- {
- CloseHandle(self->Snapshot);
- }
- if(!(self->Snapshot =
- self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)))
- {
- return 0;
- }
- ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
- self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
- if(!self->P_Process32First(self->Snapshot, &self->CurrentEntry))
- {
- CloseHandle(self->Snapshot);
- self->Snapshot = 0;
- return 0;
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
-{
- if(self->Snapshot)
- {
- if(self->P_Process32Next(self->Snapshot, &self->CurrentEntry))
- {
- return 1;
- }
- CloseHandle(self->Snapshot);
- self->Snapshot = 0;
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
-{
- return self->Snapshot? self->CurrentEntry.th32ProcessID : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
-{
- return self->Snapshot? self->CurrentEntry.th32ParentProcessID : -1;
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessKill(DWORD pid)
-{
- HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
- if(h)
- {
- TerminateProcess(h, 255);
- WaitForSingleObject(h, INFINITE);
- CloseHandle(h);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessKillTree(int pid)
-{
- kwsysProcess_List* plist = kwsysProcess_List_New();
- kwsysProcessKill(pid);
- if(plist)
- {
- do
- {
- if(kwsysProcess_List_GetCurrentParentId(plist) == pid)
- {
- int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
- kwsysProcessKillTree(ppid);
- }
- } while(kwsysProcess_List_NextProcess(plist));
- kwsysProcess_List_Delete(plist);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
-{
- int i;
-
- /* If data were just reported data, release the pipe's thread. */
- if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
- {
- KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
- ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
- cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
- }
-
- /* Wakeup all reading threads that are not on closed pipes. */
- for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
- {
- /* The wakeup threads will write one byte to the pipe write ends.
- If there are no data in the pipe then this is enough to wakeup
- the reading threads. If there are already data in the pipe
- this may block. We cannot use PeekNamedPipe to check whether
- there are data because an outside process might still be
- writing data if we are disowning it. Also, PeekNamedPipe will
- block if checking a pipe on which the reading thread is
- currently calling ReadPipe. Therefore we need a separate
- thread to call WriteFile. If it blocks, that is okay because
- it will unblock when we close the read end and break the pipe
- below. */
- if(cp->Pipe[i].Read)
- {
- KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i));
- ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0);
- }
- }
-
- /* Tell pipe threads to reset until we run another process. */
- while(cp->PipesLeft > 0)
- {
- /* The waking threads will cause all reading threads to report.
- Wait for the next one and save its index. */
- KWSYSPE_DEBUG((stderr, "waiting for reader\n"));
- WaitForSingleObject(cp->Full, INFINITE);
- cp->CurrentIndex = cp->SharedIndex;
- ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
- KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex));
-
- /* We are done reading this pipe. Close its read handle. */
- cp->Pipe[cp->CurrentIndex].Closed = 1;
- kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
- --cp->PipesLeft;
-
- /* Tell the reading thread we are done with the data. It will
- reset immediately because the pipe is closed. */
- ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-/* Global set of executing processes for use by the Ctrl handler.
- This global instance will be zero-initialized by the compiler.
-
- Note that the console Ctrl handler runs on a background thread and so
- everything it does must be thread safe. Here, we track the hProcess
- HANDLEs directly instead of kwsysProcess instances, so that we don't have
- to make kwsysProcess thread safe. */
-typedef struct kwsysProcessInstance_s
-{
- HANDLE hProcess;
- DWORD dwProcessId;
- int NewProcessGroup; /* Whether the process was created in a new group. */
-} kwsysProcessInstance;
-
-typedef struct kwsysProcessInstances_s
-{
- /* Whether we have initialized key fields below, like critical sections. */
- int Initialized;
-
- /* Ctrl handler runs on a different thread, so we must sync access. */
- CRITICAL_SECTION Lock;
-
- int Exiting;
- size_t Count;
- size_t Size;
- kwsysProcessInstance* Processes;
-} kwsysProcessInstances;
-static kwsysProcessInstances kwsysProcesses;
-
-/*--------------------------------------------------------------------------*/
-/* Initialize critial section and set up console Ctrl handler. You MUST call
- this before using any other kwsysProcesses* functions below. */
-static int kwsysProcessesInitialize(void)
-{
- /* Initialize everything if not done already. */
- if(!kwsysProcesses.Initialized)
- {
- InitializeCriticalSection(&kwsysProcesses.Lock);
-
- /* Set up console ctrl handler. */
- if(!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE))
- {
- return 0;
- }
-
- kwsysProcesses.Initialized = 1;
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-/* The Ctrl handler waits on the global list of processes. To prevent an
- orphaned process, do not create a new process if the Ctrl handler is
- already running. Do so by using this function to check if it is ok to
- create a process. */
-static int kwsysTryEnterCreateProcessSection(void)
-{
- /* Enter main critical section; this means creating a process and the Ctrl
- handler are mutually exclusive. */
- EnterCriticalSection(&kwsysProcesses.Lock);
- /* Indicate to the caller if they can create a process. */
- if(kwsysProcesses.Exiting)
- {
- LeaveCriticalSection(&kwsysProcesses.Lock);
- return 0;
- }
- else
- {
- return 1;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-/* Matching function on successful kwsysTryEnterCreateProcessSection return.
- Make sure you called kwsysProcessesAdd if applicable before calling this.*/
-static void kwsysLeaveCreateProcessSection(void)
-{
- LeaveCriticalSection(&kwsysProcesses.Lock);
-}
-
-/*--------------------------------------------------------------------------*/
-/* Add new process to global process list. The Ctrl handler will wait for
- the process to exit before it returns. Do not close the process handle
- until after calling kwsysProcessesRemove. The newProcessGroup parameter
- must be set if the process was created with CREATE_NEW_PROCESS_GROUP. */
-static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
- int newProcessGroup)
-{
- if(!kwsysProcessesInitialize() || !hProcess ||
- hProcess == INVALID_HANDLE_VALUE)
- {
- return 0;
- }
-
- /* Enter the critical section. */
- EnterCriticalSection(&kwsysProcesses.Lock);
-
- /* Make sure there is enough space for the new process handle. */
- if(kwsysProcesses.Count == kwsysProcesses.Size)
- {
- size_t newSize;
- kwsysProcessInstance *newArray;
- /* Start with enough space for a small number of process handles
- and double the size each time more is needed. */
- newSize = kwsysProcesses.Size? kwsysProcesses.Size*2 : 4;
-
- /* Try allocating the new block of memory. */
- if(newArray = (kwsysProcessInstance*)malloc(
- newSize*sizeof(kwsysProcessInstance)))
- {
- /* Copy the old process handles to the new memory. */
- if(kwsysProcesses.Count > 0)
- {
- memcpy(newArray, kwsysProcesses.Processes,
- kwsysProcesses.Count * sizeof(kwsysProcessInstance));
- }
- }
- else
- {
- /* Failed to allocate memory for the new process handle set. */
- LeaveCriticalSection(&kwsysProcesses.Lock);
- return 0;
- }
-
- /* Free original array. */
- free(kwsysProcesses.Processes);
-
- /* Update original structure with new allocation. */
- kwsysProcesses.Size = newSize;
- kwsysProcesses.Processes = newArray;
- }
-
- /* Append the new process information to the set. */
- kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
- kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid;
- kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup =
- newProcessGroup;
-
- /* Leave critical section and return success. */
- LeaveCriticalSection(&kwsysProcesses.Lock);
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Removes process to global process list. */
-static void kwsysProcessesRemove(HANDLE hProcess)
-{
- size_t i;
-
- if (!hProcess || hProcess == INVALID_HANDLE_VALUE)
- {
- return;
- }
-
- EnterCriticalSection(&kwsysProcesses.Lock);
-
- /* Find the given process in the set. */
- for(i=0; i < kwsysProcesses.Count; ++i)
- {
- if(kwsysProcesses.Processes[i].hProcess == hProcess)
- {
- break;
- }
- }
- if(i < kwsysProcesses.Count)
- {
- /* Found it! Remove the process from the set. */
- --kwsysProcesses.Count;
- for(; i < kwsysProcesses.Count; ++i)
- {
- kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i+1];
- }
-
- /* If this was the last process, free the array. */
- if(kwsysProcesses.Count == 0)
- {
- kwsysProcesses.Size = 0;
- free(kwsysProcesses.Processes);
- kwsysProcesses.Processes = 0;
- }
- }
-
- LeaveCriticalSection(&kwsysProcesses.Lock);
-}
-
-/*--------------------------------------------------------------------------*/
-static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
-{
- size_t i;
- (void)dwCtrlType;
- /* Enter critical section. */
- EnterCriticalSection(&kwsysProcesses.Lock);
-
- /* Set flag indicating that we are exiting. */
- kwsysProcesses.Exiting = 1;
-
- /* If some of our processes were created in a new process group, we must
- manually interrupt them. They won't otherwise receive a Ctrl+C/Break. */
- for(i=0; i < kwsysProcesses.Count; ++i)
- {
- if(kwsysProcesses.Processes[i].NewProcessGroup)
- {
- DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
- if(groupId)
- {
- GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
- }
- }
- }
-
- /* Wait for each child process to exit. This is the key step that prevents
- us from leaving several orphaned children processes running in the
- background when the user presses Ctrl+C. */
- for(i=0; i < kwsysProcesses.Count; ++i)
- {
- WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
- }
-
- /* Leave critical section. */
- LeaveCriticalSection(&kwsysProcesses.Lock);
-
- /* Continue on to default Ctrl handler (which calls ExitProcess). */
- return FALSE;
-}
diff --git a/src/kwsys/README.txt b/src/kwsys/README.txt
deleted file mode 100644
index b8191f7..0000000
--- a/src/kwsys/README.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-KWSys provides a platform-independent API to many common system
-features that are implemented differently on every platform. This
-library is intended to be shared among many projects, so it has a
-configurable namespace. Each project should configure KWSys to use a
-namespace unique to itself. See comments in CMakeLists.txt for
-details.
-
-You are probably reading this file in the source tree of a surrounding
-project. In that case, see "../README.kwsys" for details of using
-KWSys in your project.
-
-See CONTRIBUTING.rst for instructions to contribute KWSys changes.
diff --git a/src/kwsys/System.c b/src/kwsys/System.c
deleted file mode 100644
index ccc7e81..0000000
--- a/src/kwsys/System.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(System.h)
-
-/* Work-around CMake dependency scanning limitation. This must
- duplicate the above list of headers. */
-#if 0
-# include "System.h.in"
-#endif
-
-#include <stddef.h> /* ptrdiff_t */
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* memcpy */
-#include <ctype.h> /* isspace */
-
-#include <stdio.h>
-
-#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
-typedef ptrdiff_t kwsysSystem_ptrdiff_t;
-#else
-typedef int kwsysSystem_ptrdiff_t;
-#endif
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem__AppendByte(char* local,
- char** begin, char** end,
- int* size, char c)
-{
- /* Allocate space for the character. */
- if((*end - *begin) >= *size)
- {
- kwsysSystem_ptrdiff_t length = *end - *begin;
- char* newBuffer = (char*)malloc((size_t)(*size*2));
- if(!newBuffer)
- {
- return 0;
- }
- memcpy(newBuffer, *begin, (size_t)(length)*sizeof(char));
- if(*begin != local)
- {
- free(*begin);
- }
- *begin = newBuffer;
- *end = *begin + length;
- *size *= 2;
- }
-
- /* Store the character. */
- *(*end)++ = c;
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem__AppendArgument(char** local,
- char*** begin, char*** end,
- int* size,
- char* arg_local,
- char** arg_begin, char** arg_end,
- int* arg_size)
-{
- /* Append a null-terminator to the argument string. */
- if(!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size, '\0'))
- {
- return 0;
- }
-
- /* Allocate space for the argument pointer. */
- if((*end - *begin) >= *size)
- {
- kwsysSystem_ptrdiff_t length = *end - *begin;
- char** newPointers = (char**)malloc((size_t)(*size)*2*sizeof(char*));
- if(!newPointers)
- {
- return 0;
- }
- memcpy(newPointers, *begin, (size_t)(length)*sizeof(char*));
- if(*begin != local)
- {
- free(*begin);
- }
- *begin = newPointers;
- *end = *begin + length;
- *size *= 2;
- }
-
- /* Allocate space for the argument string. */
- **end = (char*)malloc((size_t)(*arg_end - *arg_begin));
- if(!**end)
- {
- return 0;
- }
-
- /* Store the argument in the command array. */
- memcpy(**end, *arg_begin,(size_t)(*arg_end - *arg_begin));
- ++(*end);
-
- /* Reset the argument to be empty. */
- *arg_end = *arg_begin;
-
- return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-#define KWSYSPE_LOCAL_BYTE_COUNT 1024
-#define KWSYSPE_LOCAL_ARGS_COUNT 32
-static char** kwsysSystem__ParseUnixCommand(const char* command, int flags)
-{
- /* Create a buffer for argument pointers during parsing. */
- char* local_pointers[KWSYSPE_LOCAL_ARGS_COUNT];
- int pointers_size = KWSYSPE_LOCAL_ARGS_COUNT;
- char** pointer_begin = local_pointers;
- char** pointer_end = pointer_begin;
-
- /* Create a buffer for argument strings during parsing. */
- char local_buffer[KWSYSPE_LOCAL_BYTE_COUNT];
- int buffer_size = KWSYSPE_LOCAL_BYTE_COUNT;
- char* buffer_begin = local_buffer;
- char* buffer_end = buffer_begin;
-
- /* Parse the command string. Try to behave like a UNIX shell. */
- char** newCommand = 0;
- const char* c = command;
- int in_argument = 0;
- int in_escape = 0;
- int in_single = 0;
- int in_double = 0;
- int failed = 0;
- for(;*c; ++c)
- {
- if(in_escape)
- {
- /* This character is escaped so do no special handling. */
- if(!in_argument)
- {
- in_argument = 1;
- }
- if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
- &buffer_end, &buffer_size, *c))
- {
- failed = 1;
- break;
- }
- in_escape = 0;
- }
- else if(*c == '\\')
- {
- /* The next character should be escaped. */
- in_escape = 1;
- }
- else if(*c == '\'' && !in_double)
- {
- /* Enter or exit single-quote state. */
- if(in_single)
- {
- in_single = 0;
- }
- else
- {
- in_single = 1;
- if(!in_argument)
- {
- in_argument = 1;
- }
- }
- }
- else if(*c == '"' && !in_single)
- {
- /* Enter or exit double-quote state. */
- if(in_double)
- {
- in_double = 0;
- }
- else
- {
- in_double = 1;
- if(!in_argument)
- {
- in_argument = 1;
- }
- }
- }
- else if(isspace((unsigned char) *c))
- {
- if(in_argument)
- {
- if(in_single || in_double)
- {
- /* This space belongs to a quoted argument. */
- if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
- &buffer_end, &buffer_size, *c))
- {
- failed = 1;
- break;
- }
- }
- else
- {
- /* This argument has been terminated by whitespace. */
- if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
- &pointer_end, &pointers_size,
- local_buffer, &buffer_begin,
- &buffer_end, &buffer_size))
- {
- failed = 1;
- break;
- }
- in_argument = 0;
- }
- }
- }
- else
- {
- /* This character belong to an argument. */
- if(!in_argument)
- {
- in_argument = 1;
- }
- if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
- &buffer_end, &buffer_size, *c))
- {
- failed = 1;
- break;
- }
- }
- }
-
- /* Finish the last argument. */
- if(in_argument)
- {
- if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
- &pointer_end, &pointers_size,
- local_buffer, &buffer_begin,
- &buffer_end, &buffer_size))
- {
- failed = 1;
- }
- }
-
- /* If we still have memory allocate space for the new command
- buffer. */
- if(!failed)
- {
- kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
- newCommand = (char**)malloc((size_t)(n+1)*sizeof(char*));
- }
-
- if(newCommand)
- {
- /* Copy the arguments into the new command buffer. */
- kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
- memcpy(newCommand, pointer_begin, sizeof(char*)*(size_t)(n));
- newCommand[n] = 0;
- }
- else
- {
- /* Free arguments already allocated. */
- while(pointer_end != pointer_begin)
- {
- free(*(--pointer_end));
- }
- }
-
- /* Free temporary buffers. */
- if(pointer_begin != local_pointers)
- {
- free(pointer_begin);
- }
- if(buffer_begin != local_buffer)
- {
- free(buffer_begin);
- }
-
- /* The flags argument is currently unused. */
- (void)flags;
-
- /* Return the final command buffer. */
- return newCommand;
-}
-
-/*--------------------------------------------------------------------------*/
-char** kwsysSystem_Parse_CommandForUnix(const char* command, int flags)
-{
- /* Validate the flags. */
- if(flags != 0)
- {
- return 0;
- }
-
- /* Forward to our internal implementation. */
- return kwsysSystem__ParseUnixCommand(command, flags);
-}
diff --git a/src/kwsys/System.h.in b/src/kwsys/System.h.in
deleted file mode 100644
index 3f3d3f4..0000000
--- a/src/kwsys/System.h.in
+++ /dev/null
@@ -1,69 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_System_h
-#define @KWSYS_NAMESPACE@_System_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#if !defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysSystem_Parse_CommandForUnix kwsys_ns(System_Parse_CommandForUnix)
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/**
- * Parse a unix-style command line string into separate arguments.
- *
- * On success, returns a pointer to an array of pointers to individual
- * argument strings. Each string is null-terminated and the last
- * entry in the array is a NULL pointer (just like argv). It is the
- * caller's responsibility to free() the strings and the array of
- * pointers to them.
- *
- * On failure, returns NULL. Failure occurs only on invalid flags or
- * when memory cannot be allocated; never due to content of the input
- * string. Missing close-quotes are treated as if the necessary
- * closing quote appears.
- *
- * By default single- and double-quoted arguments are supported, and
- * any character may be escaped by a backslash. The flags argument is
- * reserved for future use, and must be zero (or the call will fail).
- */
-kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
- int flags);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsys .c or .cxx file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_NAMESPACE)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysSystem_Parse_CommandForUnix
-# endif
-#endif
-
-#endif
diff --git a/src/kwsys/kwsysPlatformTests.cmake b/src/kwsys/kwsysPlatformTests.cmake
deleted file mode 100644
index 0da0f63..0000000
--- a/src/kwsys/kwsysPlatformTests.cmake
+++ /dev/null
@@ -1,219 +0,0 @@
-#=============================================================================
-# KWSys - Kitware System Library
-# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
-SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
-
-MACRO(KWSYS_PLATFORM_TEST lang var description invert)
- IF(NOT DEFINED ${var}_COMPILED)
- MESSAGE(STATUS "${description}")
- TRY_COMPILE(${var}_COMPILED
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
- COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
- CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}"
- OUTPUT_VARIABLE OUTPUT)
- IF(${var}_COMPILED)
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
-
-MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
- IF(NOT DEFINED ${var})
- MESSAGE(STATUS "${description}")
- TRY_RUN(${var} ${var}_COMPILED
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
- COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
- OUTPUT_VARIABLE OUTPUT)
-
- # Note that ${var} will be a 0 return value on success.
- IF(${var}_COMPILED)
- IF(${var})
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- ELSE()
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- SET(${var} -1 CACHE INTERNAL "${description} failed to compile.")
- ENDIF()
-
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ENDIF()
- ENDIF()
-
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
-
-MACRO(KWSYS_PLATFORM_C_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
- KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
-
-MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
- KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
-
-MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
- KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
-ENDMACRO()
-
-MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
- KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
-
-#-----------------------------------------------------------------------------
-# KWSYS_PLATFORM_INFO_TEST(lang var description)
-#
-# Compile test named by ${var} and store INFO strings extracted from binary.
-MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
- # We can implement this macro on CMake 2.6 and above.
- IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
- SET(${var} "")
- ELSE()
- # Choose a location for the result binary.
- SET(KWSYS_PLATFORM_INFO_FILE
- ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin)
-
- # Compile the test binary.
- IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
- MESSAGE(STATUS "${description}")
- TRY_COMPILE(${var}_COMPILED
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
- COMPILE_DEFINITIONS -DTEST_${var}
- ${KWSYS_PLATFORM_${lang}_TEST_DEFINES}
- ${KWSYS_PLATFORM_${lang}_TEST_EXTRA_FLAGS}
- OUTPUT_VARIABLE OUTPUT
- COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
- )
- IF(${var}_COMPILED)
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - compiled")
- ELSE()
- MESSAGE(STATUS "${description} - failed")
- ENDIF()
- ENDIF()
-
- # Parse info strings out of the compiled binary.
- IF(${var}_COMPILED)
- FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
- ELSE()
- SET(${var} "")
- ENDIF()
-
- SET(KWSYS_PLATFORM_INFO_FILE)
- ENDIF()
-ENDMACRO()
diff --git a/src/kwsys/kwsysPlatformTestsC.c b/src/kwsys/kwsysPlatformTestsC.c
deleted file mode 100644
index e602964..0000000
--- a/src/kwsys/kwsysPlatformTestsC.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-/*
- Macros to define main() in a cross-platform way.
-
- Usage:
-
- int KWSYS_PLATFORM_TEST_C_MAIN()
- {
- return 0;
- }
-
- int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
- {
- (void)argc; (void)argv;
- return 0;
- }
-*/
-#if defined(__CLASSIC_C__)
-# define KWSYS_PLATFORM_TEST_C_MAIN() \
- main()
-# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
- main(argc,argv) int argc; char* argv[];
-#else
-# define KWSYS_PLATFORM_TEST_C_MAIN() \
- main(void)
-# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
- main(int argc, char* argv[])
-#endif
-
-/*--------------------------------------------------------------------------*/
-#ifdef TEST_KWSYS_C_HAS_PTRDIFF_T
-#include <stddef.h>
-int f(ptrdiff_t n) { return n > 0; }
-int KWSYS_PLATFORM_TEST_C_MAIN()
-{
- char* p = 0;
- ptrdiff_t d = p - p;
- (void)d;
- return f(p - p);
-}
-#endif
-
-/*--------------------------------------------------------------------------*/
-#ifdef TEST_KWSYS_C_HAS_SSIZE_T
-#include <unistd.h>
-int f(ssize_t n) { return (int)n; }
-int KWSYS_PLATFORM_TEST_C_MAIN()
-{
- ssize_t n = 0;
- return f(n);
-}
-#endif
-
-/*--------------------------------------------------------------------------*/
-#ifdef TEST_KWSYS_C_TYPE_MACROS
-char* info_macros =
-#if defined(__SIZEOF_SHORT__)
-"INFO:macro[__SIZEOF_SHORT__]\n"
-#endif
-#if defined(__SIZEOF_INT__)
-"INFO:macro[__SIZEOF_INT__]\n"
-#endif
-#if defined(__SIZEOF_LONG__)
-"INFO:macro[__SIZEOF_LONG__]\n"
-#endif
-#if defined(__SIZEOF_LONG_LONG__)
-"INFO:macro[__SIZEOF_LONG_LONG__]\n"
-#endif
-#if defined(__SHORT_MAX__)
-"INFO:macro[__SHORT_MAX__]\n"
-#endif
-#if defined(__INT_MAX__)
-"INFO:macro[__INT_MAX__]\n"
-#endif
-#if defined(__LONG_MAX__)
-"INFO:macro[__LONG_MAX__]\n"
-#endif
-#if defined(__LONG_LONG_MAX__)
-"INFO:macro[__LONG_LONG_MAX__]\n"
-#endif
- "";
-
-int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
-{
- int require = 0;
- require += info_macros[argc];
- (void)argv;
- return require;
-}
-#endif
diff --git a/src/kwsys/kwsysPlatformTestsCXX.cxx b/src/kwsys/kwsysPlatformTestsCXX.cxx
deleted file mode 100644
index 1596fe4..0000000
--- a/src/kwsys/kwsysPlatformTestsCXX.cxx
+++ /dev/null
@@ -1,699 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-// Setup for tests that use result of stl namespace test.
-#if defined(KWSYS_STL_HAVE_STD)
-# if KWSYS_STL_HAVE_STD
-# define kwsys_stl std
-# else
-# define kwsys_stl
-# endif
-#endif
-
-// Setup for tests that use iostreams.
-#if defined(KWSYS_IOS_USE_ANSI) && defined(KWSYS_IOS_HAVE_STD)
-# if defined(_MSC_VER)
-# pragma warning (push,1)
-# endif
-# if KWSYS_IOS_USE_ANSI
-# include <iostream>
-# else
-# include <iostream.h>
-# endif
-# if defined(_MSC_VER)
-# pragma warning (pop)
-# endif
-# if KWSYS_IOS_HAVE_STD
-# define kwsys_ios std
-# else
-# define kwsys_ios
-# endif
-#endif
-
-#ifdef TEST_KWSYS_STL_HAVE_STD
-#include <list>
-void f(std ::list<int>*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_ANSI
-#include <iosfwd>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAVE_STD
-#include <iosfwd>
-void f(std ::ostream*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_SSTREAM
-#include <sstream>
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 96
-# error "GCC 2.96 stringstream is buggy"
-#endif
-int main()
-{
- std ::ostringstream ostr;
- ostr << "hello";
- if(ostr.str().size() == 5)
- {
- return 0;
- }
- return -1;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREAM_H
-#include <strstream.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREA_H
-#include <strstrea.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_OSTREAM
-# include <iostream.h>
-# include <string>
-void f(ostream& os, const kwsys_stl::string& s) { os << s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_ISTREAM
-# include <iostream.h>
-# include <string>
-void f(istream& is, kwsys_stl::string& s) { is >> s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_NEQ_CHAR
-# include <string>
-bool f(const kwsys_stl::string& s) { return s != ""; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_CSTDIO
-#include <cstdio>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_CSTDDEF
-#include <cstddef>
-void f(size_t) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
-long long f(long long n) { return n; }
-int main()
-{
- long long n = 0;
- return static_cast<int>(f(n));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS___INT64
-__int64 f(__int64 n) { return n; }
-int main()
-{
- __int64 n = 0;
- return static_cast<int>(f(n));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
-template <class T> class A;
-template <class T> int f(A<T>&);
-template <class T> class A
-{
-public:
- // "friend int f<>(A<T>&)" would conform
- friend int f(A<T>&);
-private:
- int x;
-};
-
-template <class T> int f(A<T>& a) { return a.x = 0; }
-template int f(A<int>&);
-
-int main()
-{
- A<int> a;
- return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_MEMBER_TEMPLATES
-template <class U>
-class A
-{
-public:
- U u;
- A(): u(0) {}
- template <class V> V m(V* p) { return *p = u; }
-};
-
-int main()
-{
- A<short> a;
- int s = 1;
- return a.m(&s);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_FULL_SPECIALIZATION
-template <class T> struct A {};
-template <> struct A<int*>
-{
- static int f() { return 0; }
-};
-int main() { return A<int*>::f(); }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-namespace N
-{
- class A {};
- int f(A*) { return 0; }
-}
-void f(void*);
-int main()
-{
- N::A* a = 0;
- return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_TRAITS
-#include <iterator>
-#include <list>
-void f(kwsys_stl::iterator_traits<kwsys_stl::list<int>::iterator>::iterator_category const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS___ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::__iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
-#include <memory>
-template <class Alloc>
-void f(const Alloc&)
-{
- typedef typename Alloc::size_type alloc_size_type;
-}
-int main()
-{
- f(kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
-#include <memory>
-void f(kwsys_stl::allocator::size_type const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_REBIND
-#include <memory>
-template <class T, class Alloc>
-void f(const T&, const Alloc&)
-{
- typedef typename Alloc::template rebind<T>::other alloc_type;
-}
-int main()
-{
- f(0, kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-#include <memory>
-void f(kwsys_stl::allocator<char> const& a)
-{
- a.max_size(sizeof(int));
-}
-int main()
-{
- f(kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS
-#include <vector>
-void f(kwsys_stl::vector<int> const& v1)
-{
- kwsys_stl::vector<int>(1, 1, v1.get_allocator());
-}
-int main()
-{
- f(kwsys_stl::vector<int>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STAT_HAS_ST_MTIM
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-int main()
-{
- struct stat stat1;
- (void)stat1.st_mtim.tv_sec;
- (void)stat1.st_mtim.tv_nsec;
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
-void function(long**) {}
-int main()
-{
- __int64** p = 0;
- function(p);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64
-void function(long long**) {}
-int main()
-{
- __int64** p = 0;
- function(p);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CAN_CONVERT_UI64_TO_DOUBLE
-void function(double& l, unsigned __int64 const& r)
-{
- l = static_cast<double>(r);
-}
-
-int main()
-{
- double tTo = 0.0;
- unsigned __int64 tFrom = 0;
- function(tTo, tFrom);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAVE_BINARY
-int test_binary(int, ...)
-{
- return 0;
-}
-int main()
-{
- return test_binary(1, kwsys_ios::ios::binary);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-int test_istream(kwsys_ios::istream& is, long long& x)
-{
- return (is >> x)? 1:0;
-}
-int main()
-{
- long long x = 0;
- return test_istream(kwsys_ios::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-int test_ostream(kwsys_ios::ostream& os, long long x)
-{
- return (os << x)? 1:0;
-}
-int main()
-{
- long long x = 0;
- return test_ostream(kwsys_ios::cout, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
-int test_istream(kwsys_ios::istream& is, __int64& x)
-{
- return (is >> x)? 1:0;
-}
-int main()
-{
- __int64 x = 0;
- return test_istream(kwsys_ios::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
-int test_ostream(kwsys_ios::ostream& os, __int64 x)
-{
- return (os << x)? 1:0;
-}
-int main()
-{
- __int64 x = 0;
- return test_ostream(kwsys_ios::cout, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_CHAR_IS_SIGNED
-/* Return 0 for char signed and 1 for char unsigned. */
-int main()
-{
- unsigned char uc = 255;
- return (*reinterpret_cast<char*>(&uc) < 0)?0:1;
-}
-#endif
-
-#ifdef TEST_KWSYS_LFS_WORKS
-/* Return 0 when LFS is available and 1 otherwise. */
-#define _LARGEFILE_SOURCE
-#define _LARGEFILE64_SOURCE
-#define _LARGE_FILES
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#if KWSYS_CXX_HAS_CSTDIO
-# include <cstdio>
-#endif
-#include <stdio.h>
-
-int main(int, char **argv)
-{
- /* check that off_t can hold 2^63 - 1 and perform basic operations... */
-#define OFF_T_64 (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- if (OFF_T_64 % 2147483647 != 1)
- return 1;
-
- // stat breaks on SCO OpenServer
- struct stat buf;
- stat( argv[0], &buf );
- if (!S_ISREG(buf.st_mode))
- return 2;
-
- FILE *file = fopen( argv[0], "r" );
- off_t offset = ftello( file );
- fseek( file, offset, SEEK_CUR );
- fclose( file );
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_SETENV
-#include <stdlib.h>
-int main()
-{
- return setenv("A", "B", 1);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_UNSETENV
-#include <stdlib.h>
-int main()
-{
- unsetenv("A");
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
-#include <stdlib.h>
-int main()
-{
- char* e = environ[0];
- return e? 0:1;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
-// Match feature definitions from SystemInformation.cxx
-#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
-# define _GNU_SOURCE
-#endif
-#include <stdlib.h>
-int main()
-{
- double loadavg[3] = { 0.0, 0.0, 0.0 };
- return getloadavg(loadavg, 3);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
-# if defined(KWSYS_HAS_LFS)
-# define _LARGEFILE_SOURCE
-# define _LARGEFILE64_SOURCE
-# define _LARGE_FILES
-# define _FILE_OFFSET_BITS 64
-# endif
-# include <sys/resource.h>
-int main()
-{
- struct rlimit64 rlim;
- return getrlimit64(0,&rlim);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ATOLL
-#include <stdlib.h>
-int main()
-{
- const char *str="1024";
- return static_cast<int>(atoll(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ATOL
-#include <stdlib.h>
-int main()
-{
- const char *str="1024";
- return static_cast<int>(atol(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS__ATOI64
-#include <stdlib.h>
-int main()
-{
- const char *str="1024";
- return static_cast<int>(_atoi64(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_UTIMES
-#include <sys/time.h>
-int main()
-{
- struct timeval* current_time = 0;
- return utimes("/example", current_time);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_UTIMENSAT
-#include <fcntl.h>
-#include <sys/stat.h>
-int main()
-{
- struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}};
- return utimensat(AT_FDCWD, "/example", times, AT_SYMLINK_NOFOLLOW);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_BACKTRACE
-#if defined(__PATHSCALE__) || defined(__PATHCC__) \
- || (defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41))
-backtrace doesnt work with this compiler or os
-#endif
-#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
-# define _GNU_SOURCE
-#endif
-#include <execinfo.h>
-int main()
-{
- void *stackSymbols[256];
- backtrace(stackSymbols,256);
- backtrace_symbols(&stackSymbols[0],1);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_DLADDR
-#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
-# define _GNU_SOURCE
-#endif
-#include <dlfcn.h>
-int main()
-{
- Dl_info info;
- int ierr=dladdr((void*)main,&info);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_CXXABI
-#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
-# define _GNU_SOURCE
-#endif
-#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 \
- && __linux && __SUNPRO_CC_COMPAT == 'G'
-# include <iostream>
-#endif
-#include <cxxabi.h>
-int main()
-{
- int status = 0;
- size_t bufferLen = 512;
- char buffer[512] = {'\0'};
- const char *function="_ZN5kwsys17SystemInformation15GetProgramStackEii";
- char *demangledFunction =
- abi::__cxa_demangle(function, buffer, &bufferLen, &status);
- return status;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_TYPE_INFO
-/* Collect fundamental type information and save it to a CMake script. */
-
-/* Include limits.h to get macros indicating long long and __int64.
- Note that certain compilers need special macros to define these
- macros in limits.h. */
-#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
-# define _MSC_EXTENSIONS
-#endif
-#if defined(__GNUC__) && __GNUC__ < 3
-# define _GNU_SOURCE
-#endif
-#include <limits.h>
-
-#include <stdio.h>
-#include <string.h>
-
-/* Due to shell differences and limitations of ADD_DEFINITIONS the
- KWSYS_CXX_TYPE_INFO_FILE macro will sometimes have double quotes
- and sometimes not. This macro will make sure the value is treated
- as a double-quoted string. */
-#define TO_STRING(x) TO_STRING0(x)
-#define TO_STRING0(x) TO_STRING1(x)
-#define TO_STRING1(x) #x
-
-void f() {}
-
-int main()
-{
- /* Construct the output file name. Some preprocessors will add an
- extra level of double quotes, so strip them. */
- char fbuf[] = TO_STRING(KWSYS_CXX_TYPE_INFO_FILE);
- char* fname = fbuf;
- if(fname[0] == '"')
- {
- ++fname;
- int len = static_cast<int>(strlen(fname));
- if(len > 0 && fname[len-1] == '"')
- {
- fname[len-1] = 0;
- }
- }
-
- /* Try to open the output file. */
- if(FILE* fout = fopen(fname, "w"))
- {
- /* Set the size of standard types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_CHAR %d)\n", static_cast<int>(sizeof(char)));
- fprintf(fout, "SET(KWSYS_SIZEOF_SHORT %d)\n", static_cast<int>(sizeof(short)));
- fprintf(fout, "SET(KWSYS_SIZEOF_INT %d)\n", static_cast<int>(sizeof(int)));
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG %d)\n", static_cast<int>(sizeof(long)));
-
- /* Set the size of some non-standard but common types. */
- /* Check for a limits.h macro for long long to see if the type exists. */
-#if defined(LLONG_MAX) || defined(LONG_LONG_MAX) || defined(LONGLONG_MAX)
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG %d)\n", static_cast<int>(sizeof(long long)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG 0) # No long long available.\n");
-#endif
- /* Check for a limits.h macro for __int64 to see if the type exists. */
-#if defined(_I64_MIN)
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 %d)\n", static_cast<int>(sizeof(__int64)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 0) # No __int64 available.\n");
-#endif
-
- /* Set the size of some pointer types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_PDATA %d)\n", static_cast<int>(sizeof(void*)));
- fprintf(fout, "SET(KWSYS_SIZEOF_PFUNC %d)\n", static_cast<int>(sizeof(&f)));
-
- /* Set whether the native type "char" is signed or unsigned. */
- unsigned char uc = 255;
- fprintf(fout, "SET(KWSYS_CHAR_IS_SIGNED %d)\n",
- (*reinterpret_cast<char*>(&uc) < 0)?1:0);
-
- fclose(fout);
- return 0;
- }
- else
- {
- fprintf(stderr, "Failed to write fundamental type info to \"%s\".\n",
- fname);
- return 1;
- }
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
-int main()
-{
- int a = 1;
- __asm {
- xor EBX, EBX;
- mov a, EBX;
- }
-
- return a;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
-int main()
-{
- int a = 0;
- __asm {
- xor EAX, EAX;
- cpuid;
- mov a, EAX;
- }
-
- return a;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_WSTRING
-#include <string>
-void f(std ::wstring*) {}
-int main() { return 0; }
-#endif
diff --git a/src/kwsys/kwsysPrivate.h b/src/kwsys/kwsysPrivate.h
deleted file mode 100644
index 3a26c26..0000000
--- a/src/kwsys/kwsysPrivate.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef KWSYS_NAMESPACE
-# error "Do not include kwsysPrivate.h outside of kwsys c and cxx files."
-#endif
-
-#ifndef _kwsysPrivate_h
-#define _kwsysPrivate_h
-
-/*
- Define KWSYS_HEADER macro to help the c and cxx files include kwsys
- headers from the configured namespace directory. The macro can be
- used like this:
-
- #include KWSYS_HEADER(Directory.hxx)
- #include KWSYS_HEADER(std/vector)
-*/
-#define KWSYS_HEADER(x) KWSYS_HEADER0(KWSYS_NAMESPACE/x)
-#define KWSYS_HEADER0(x) KWSYS_HEADER1(x)
-#define KWSYS_HEADER1(x) <x>
-
-/*
- Define KWSYS_NAMESPACE_STRING to be a string constant containing the
- name configured for this instance of the kwsys library.
-*/
-#define KWSYS_NAMESPACE_STRING KWSYS_NAMESPACE_STRING0(KWSYS_NAMESPACE)
-#define KWSYS_NAMESPACE_STRING0(x) KWSYS_NAMESPACE_STRING1(x)
-#define KWSYS_NAMESPACE_STRING1(x) #x
-
-#else
-# error "kwsysPrivate.h included multiple times."
-#endif