Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -0,0 +1,17 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AlignEscapedNewlinesLeft: false
AllowShortFunctionsOnASingleLine: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces: Allman
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IndentCaseLabels: true
IndentWidth: 4
PointerAlignment: Left
TabWidth: 4
...

View File

@@ -0,0 +1,238 @@
cmake_minimum_required(VERSION 2.8.12)
project(CoreFX)
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_INSTALL_PREFIX $ENV{__CMakeBinDir})
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_C_FLAGS "-std=c11")
set(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(VERSION_FILE_PATH "${CMAKE_BINARY_DIR}/../../version.c")
add_compile_options(-Weverything)
add_compile_options(-Wno-format-nonliteral)
add_compile_options(-Wno-missing-prototypes)
add_compile_options(-Wno-disabled-macro-expansion)
add_compile_options(-Wno-c++98-compat)
add_compile_options(-Wno-c++98-compat-pedantic)
add_compile_options(-Werror)
add_compile_options(-fPIC)
add_compile_options(-I${CMAKE_CURRENT_SOURCE_DIR}/Common)
add_compile_options(-I${CMAKE_CURRENT_BINARY_DIR}/Common)
add_compile_options(-Wno-c99-extensions)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
add_compile_options(-Wno-unreachable-code)
endif ()
if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
add_definitions(-DBIT64=1)
add_definitions(-D_AMD64_)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL x86 OR CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
add_definitions(-DBIT32=1)
add_definitions(-D_X86_)
add_definitions(-D_FILE_OFFSET_BITS=64)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
add_definitions(-DBIT64=1)
add_definitions(-D_ARM64_)
# Because we don't use CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to use clang
# we have to set the triple by adding a compiler argument
add_compile_options(-target aarch64-linux-gnu)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
add_definitions(-DBIT32=1)
add_definitions(-D_ARM_)
add_definitions(-D_FILE_OFFSET_BITS=64)
# Because we don't use CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to use clang
# we have to set the triple by adding a compiler argument
if(ARM_SOFTFP)
add_compile_options(-target armv7-linux-gnueabi)
add_compile_options(-mfloat-abi=softfp)
else ()
add_compile_options(-target armv7-linux-gnueabihf)
endif ()
add_compile_options(-mthumb)
add_compile_options(-mfpu=vfpv3)
endif ()
string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)
if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
add_compile_options(-g -O0)
add_definitions(-DDEBUG)
# obtain settings from running coreclr\enablesanitizers.sh
string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS)
string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS)
if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1))
set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS} -fsanitize=")
set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS} -fsanitize=")
if (${__ASAN_POS} GREATER -1)
set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}address,")
set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS}address,")
message("Address Sanitizer (asan) enabled")
endif ()
if (${__UBSAN_POS} GREATER -1)
set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}undefined")
set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS}undefined")
message("Undefined Behavior Sanitizer (ubsan) enabled")
endif ()
# -fdata-sections -ffunction-sections: each function has own section instead of one per .o file (needed for --gc-sections)
# -fPIC: enable Position Independent Code normally just for shared libraries but required when linking with address sanitizer
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CLR_SANITIZE_CXX_FLAGS} -fdata-sections -ffunction-sections -fPIC")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${CLR_SANITIZE_LINK_FLAGS}")
# -Wl and --gc-sections: drop unused sections\functions (similar to Windows /Gy function-level-linking)
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${CLR_SANITIZE_LINK_FLAGS} -Wl,--gc-sections")
endif ()
elseif (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE)
add_compile_options (-O3)
add_definitions(-DNDEBUG)
else ()
message(FATAL_ERROR "Unknown build type. Set CMAKE_BUILD_TYPE to DEBUG or RELEASE.")
endif ()
if (APPLE)
add_definitions(-D__APPLE_USE_RFC_3542)
# We cannot enable "stack-protector-strong" on OS X due to a bug in clang compiler (current version 7.0.2)
add_compile_options(-fstack-protector)
else ()
add_compile_options(-fstack-protector-strong)
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=sha1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1")
endif ()
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
set(CLR_CMAKE_PLATFORM_UNIX 1)
endif(CMAKE_SYSTEM_NAME STREQUAL Linux)
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(CLR_CMAKE_PLATFORM_UNIX 1)
endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
set(CLR_CMAKE_PLATFORM_UNIX 1)
add_definitions(-D_BSD_SOURCE) # required for getline
endif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
if(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
set(CLR_CMAKE_PLATFORM_UNIX 1)
endif(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
set(CLR_CMAKE_PLATFORM_UNIX 1)
endif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
if(CMAKE_SYSTEM_NAME STREQUAL SunOS)
set(CLR_CMAKE_PLATFORM_UNIX 1)
endif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
if (NOT WIN32)
if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
# Ensure that dsymutil and strip are present
find_program(DSYMUTIL dsymutil)
if (DSYMUTIL STREQUAL "DSYMUTIL-NOTFOUND")
message(FATAL_ERROR "dsymutil not found")
endif()
find_program(STRIP strip)
if (STRIP STREQUAL "STRIP-NOTFOUND")
message(FATAL_ERROR "strip not found")
endif()
else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
# Ensure that objcopy is present
if(DEFINED ENV{CROSSCOMPILE})
if(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
find_program(OBJCOPY ${TOOLCHAIN}-objcopy)
else()
message(FATAL_ERROR "Only AMD64, X86, ARM64 and ARM are supported")
endif()
else()
find_program(OBJCOPY objcopy)
endif()
if (OBJCOPY STREQUAL "OBJCOPY-NOTFOUND" AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
message(FATAL_ERROR "objcopy not found")
endif()
endif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
endif ()
function(strip_symbols targetName outputFilename)
if(CLR_CMAKE_PLATFORM_UNIX)
if(STRIP_SYMBOLS)
# On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
# generator expression doesn't work correctly returning the wrong path and on
# the newer cmake versions the LOCATION property isn't supported anymore.
if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
set(strip_source_file $<TARGET_FILE:${targetName}>)
else()
get_property(strip_source_file TARGET ${targetName} PROPERTY LOCATION)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(strip_destination_file ${strip_source_file}.dwarf)
add_custom_command(
TARGET ${targetName}
POST_BUILD
VERBATIM
COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
COMMAND ${STRIP} -u -r ${strip_source_file}
COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
)
else(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(strip_destination_file ${strip_source_file}.dbg)
add_custom_command(
TARGET ${targetName}
POST_BUILD
VERBATIM
COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
COMMAND ${OBJCOPY} --strip-unneeded ${strip_source_file}
COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
)
endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
endif(STRIP_SYMBOLS)
endif(CLR_CMAKE_PLATFORM_UNIX)
endfunction()
function(install_library_and_symbols targetName)
strip_symbols(${targetName} strip_destination_file)
# On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
# generator expression doesn't work correctly returning the wrong path and on
# the newer cmake versions the LOCATION property isn't supported anymore.
if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
set(install_source_file $<TARGET_FILE:${targetName}>)
else()
get_property(install_source_file TARGET ${targetName} PROPERTY LOCATION)
endif()
install(PROGRAMS ${install_source_file} DESTINATION .)
if(WIN32)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION PDB)
else()
install(FILES ${strip_destination_file} DESTINATION .)
endif()
endfunction()
include(configure.cmake)
add_subdirectory(System.IO.Compression.Native)
add_subdirectory(System.Native)
add_subdirectory(System.Net.Http.Native)
add_subdirectory(System.Net.Security.Native)
add_subdirectory(System.Security.Cryptography.Native)
if(APPLE)
add_subdirectory(System.Security.Cryptography.Native.Apple)
endif()

View File

@@ -0,0 +1,74 @@
#pragma once
#cmakedefine PAL_UNIX_NAME @PAL_UNIX_NAME@
#cmakedefine01 HAVE_STAT64
#cmakedefine01 HAVE_PIPE2
#cmakedefine01 HAVE_STAT_BIRTHTIME
#cmakedefine01 HAVE_GNU_STRERROR_R
#cmakedefine01 HAVE_READDIR_R
#cmakedefine01 HAVE_DIRENT_NAME_LEN
#cmakedefine01 HAVE_MNTINFO
#cmakedefine01 HAVE_STATFS_FSTYPENAME
#cmakedefine01 HAVE_STATVFS_FSTYPENAME
#cmakedefine01 HAVE_STRCPY_S
#cmakedefine01 HAVE_STRLCPY
#cmakedefine01 HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP
#cmakedefine01 HAVE_POSIX_ADVISE
#cmakedefine01 PRIORITY_REQUIRES_INT_WHO
#cmakedefine01 KEVENT_REQUIRES_INT_PARAMS
#cmakedefine01 HAVE_IN6_U
#cmakedefine01 HAVE_U6_ADDR
#cmakedefine01 HAVE_IOCTL
#cmakedefine01 HAVE_TIOCGWINSZ
#cmakedefine01 HAVE_SCHED_GETAFFINITY
#cmakedefine01 HAVE_SCHED_SETAFFINITY
#cmakedefine01 KEVENT_HAS_VOID_UDATA
#cmakedefine01 HAVE_FDS_BITS
#cmakedefine01 HAVE_PRIVATE_FDS_BITS
#cmakedefine01 HAVE_STATFS
#cmakedefine01 HAVE_EPOLL
#cmakedefine01 HAVE_KQUEUE
#cmakedefine01 HAVE_SENDFILE_4
#cmakedefine01 HAVE_SENDFILE_6
#cmakedefine01 HAVE_FCOPYFILE
#cmakedefine01 HAVE_GETHOSTBYNAME_R
#cmakedefine01 HAVE_GETHOSTBYADDR_R
#cmakedefine01 HAVE_GETPEEREID
#cmakedefine01 HAVE_SUPPORT_FOR_DUAL_MODE_IPV4_PACKET_INFO
#cmakedefine01 HAVE_THREAD_SAFE_GETHOSTBYNAME_AND_GETHOSTBYADDR
#cmakedefine01 HAVE_TCGETATTR
#cmakedefine01 HAVE_TCSETATTR
#cmakedefine01 HAVE_ECHO
#cmakedefine01 HAVE_ICANON
#cmakedefine01 HAVE_TCSANOW
#cmakedefine01 HAVE_IN_PKTINFO
#cmakedefine01 HAVE_IP_MREQN
#cmakedefine01 HAVE_TCP_VAR_H
#cmakedefine01 HAVE_RT_MSGHDR
#cmakedefine01 HAVE_SYS_SYSCTL_H
#cmakedefine01 HAVE_LINUX_RTNETLINK_H
#cmakedefine01 HAVE_GETDOMAINNAME_SIZET
#cmakedefine01 HAVE_INOTIFY
#cmakedefine01 HAVE_CLOCK_MONOTONIC
#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME
#cmakedefine01 HAVE_MACH_TIMEBASE_INFO
#cmakedefine01 HAVE_CURLM_ADDED_ALREADY
#cmakedefine01 HAVE_CURL_HTTP_VERSION_2_0
#cmakedefine01 HAVE_CURLPIPE_MULTIPLEX
#cmakedefine01 HAVE_CURL_SSLVERSION_TLSv1_012
#cmakedefine01 HAVE_TCP_H_TCPSTATE_ENUM
#cmakedefine01 HAVE_TCP_FSM_H
#cmakedefine01 HAVE_GSSFW_HEADERS
#cmakedefine01 HAVE_GSS_SPNEGO_MECHANISM
#cmakedefine01 HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
#cmakedefine01 HAVE_HEIMDAL_HEADERS
#cmakedefine01 HAVE_NSGETENVIRON
#cmakedefine01 HAVE_CRT_EXTERNS_H
// Mac OS X has stat64, but it is deprecated since plain stat now
// provides the same 64-bit aware struct when targeting OS X > 10.5
// and not passing _DARWIN_NO_64_BIT_INODE.
#ifdef __APPLE__
#undef HAVE_STAT64
#define HAVE_STAT64 0
#endif

View File

@@ -0,0 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <safemath/safemath.h> // remove once __builtin_*_overflow builtins are available everywhere
// Multiplies a and b into result.
// Returns true if safe, false if overflows.
template <typename T>
inline static bool multiply_s(T a, T b, T* result)
{
return
#if __has_builtin(__builtin_mul_overflow)
!__builtin_mul_overflow(a, b, result);
#else
ClrSafeInt<T>::multiply(a, b, *result);
#endif
}
// Adds a and b into result.
// Returns true if safe, false if overflows.
template <typename T>
inline static bool add_s(T a, T b, T* result)
{
return
#if __has_builtin(__builtin_add_overflow)
!__builtin_add_overflow(a, b, result);
#else
ClrSafeInt<T>::addition(a, b, *result);
#endif
}
typedef int errno_t;
inline static errno_t memcpy_s(void* dst, size_t sizeInBytes, const void* src, size_t count)
{
if (count > 0)
{
assert(dst != nullptr);
assert(src != nullptr);
assert(sizeInBytes >= count);
assert( // should be using memmove if this fails
(static_cast<const char*>(dst) + count <= static_cast<const char*>(src)) ||
(static_cast<const char*>(src) + count <= static_cast<const char*>(dst)));
if (dst == nullptr)
{
return EINVAL;
}
if (src == nullptr || sizeInBytes < count)
{
memset(dst, 0, sizeInBytes);
return src == nullptr ? EINVAL : ERANGE;
}
memcpy(dst, src, count);
}
return 0;
}

View File

@@ -0,0 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include <stdint.h> // int32_t, int64_t, etc.

View File

@@ -0,0 +1,145 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include "pal_types.h"
#include "pal_config.h"
#include <assert.h>
#include <errno.h>
#include <limits>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <type_traits>
#include <unistd.h>
/**
* ResultOf<T> is shorthand for typename std::result_of<T>::type.
* Equivalent to C++14 std::result_of_t.
*/
template <typename T>
using ResultOf = typename std::result_of<T>::type;
/**
* EnableIf<B, T> is shorthand for typename std::enable_of<B, T>::type.
* Equivalent to C++14 std::enable_if_t.
*/
template <bool B, typename T = void>
using EnableIf = typename std::enable_if<B, T>::type;
/**
* NonVoidResultOf<F> evaluates to non-void return type of F.
* Causes substitution failure if F returns void.
*/
template <typename F>
using NonVoidResultOf = EnableIf<!std::is_void<ResultOf<F>>::value, ResultOf<F>>;
/**
* ReplaceVoid<F, T> evaluates to T if F returns void.
* Causes substitution failure if F does not return void.
*/
template <typename F, typename T>
using ReplaceVoidResultOf = EnableIf<std::is_void<ResultOf<F>>::value, T>;
/**
* Cast an unsigned integer value to the appropriately sized signed integer type.
*
* We use this when we've already ensured that the value is within the
* signed range, but we don't want to cast to a specific signed type as that could
* inadvertently defeat the compiler's narrowing conversion warnings
* (which we treat as error).
*/
template <typename T>
inline typename std::make_signed<T>::type SignedCast(T value)
{
assert(value <= std::numeric_limits<typename std::make_signed<T>::type>::max());
return static_cast<typename std::make_signed<T>::type>(value);
}
/**
* Cast a positive value typed as a signed integer to the
* appropriately sized unsigned integer type.
*
* We use this when we've already ensured that the value is positive,
* but we don't want to cast to a specific unsigned type as that could
* inadvertently defeat the compiler's narrowing conversion warnings
* (which we treat as error).
*/
template <typename T>
inline typename std::make_unsigned<T>::type UnsignedCast(T value)
{
assert(value >= 0);
return static_cast<typename std::make_unsigned<T>::type>(value);
}
/**
* Clang doesn't have an ARRAY_SIZE macro so use the solution from
* MSDN blogs: http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx
*/
template <typename T, size_t N>
char(&_ArraySizeHelper(T(&array)[N]))[N];
#define ARRAY_SIZE(array) (sizeof(_ArraySizeHelper(array)))
/**
* Abstraction helper method to safely copy strings using strlcpy or strcpy_s
* or a different safe copy method, depending on the current platform.
*/
inline void SafeStringCopy(char* destination, size_t destinationSize, const char* source)
{
#if HAVE_STRCPY_S
strcpy_s(destination, destinationSize, source);
#elif HAVE_STRLCPY
strlcpy(destination, source, destinationSize);
#else
snprintf(destination, destinationSize, "%s", source);
#endif
}
/**
* Overload of SafeStringCopy that takes a signed int32_t as buffer
* size. Asserts that its positive, but defensively treats the size
* as 0 (no-op) if it's negative.
*/
inline void SafeStringCopy(char* destination, int32_t destinationSize, const char* source)
{
assert(destinationSize >= 0);
if (destinationSize > 0)
{
size_t unsignedSize = UnsignedCast(destinationSize);
SafeStringCopy(destination, unsignedSize, source);
}
}
/**
* Converts an intptr_t to a file descriptor.
* intptr_t is the type used to marshal file descriptors so we can use SafeHandles effectively.
*/
inline static int ToFileDescriptor(intptr_t fd)
{
assert(0 <= fd && fd < sysconf(_SC_OPEN_MAX));
return static_cast<int>(fd);
}
/**
* Converts an intptr_t to a file descriptor.
* intptr_t is the type used to marshal file descriptors so we can use SafeHandles effectively.
*/
inline static int ToFileDescriptorUnchecked(intptr_t fd)
{
return static_cast<int>(fd);
}
/**
* Checks if the IO operation was interupted and needs to be retried.
* Returns true if the operation was interupted; otherwise, false.
*/
template <typename TInt>
static inline bool CheckInterrupted(TInt result)
{
return result < 0 && errno == EINTR;
}

View File

@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//*****************************************************************************
// DebugMacrosExt.h
//
// Simple debugging macros that take no dependencies on CLR headers.
// This header can be used from outside the CLR.
//
//*****************************************************************************
#pragma once
#if !defined(_DEBUG_IMPL) && defined(_DEBUG) && !defined(DACCESS_COMPILE)
#define _DEBUG_IMPL 1
#endif
#ifdef _DEBUG
// A macro to execute a statement only in _DEBUG.
#define DEBUG_STMT(stmt) stmt
#define INDEBUG(x) x
#define INDEBUG_COMMA(x) x,
#define COMMA_INDEBUG(x) ,x
#define NOT_DEBUG(x)
#else
#define DEBUG_STMT(stmt)
#define INDEBUG(x)
#define INDEBUG_COMMA(x)
#define COMMA_INDEBUG(x)
#define NOT_DEBUG(x) x
#endif
#ifdef _DEBUG_IMPL
#define INDEBUGIMPL(x) x
#define INDEBUGIMPL_COMMA(x) x,
#define COMMA_INDEBUGIMPL(x) ,x
#else
#define INDEBUGIMPL(x)
#define INDEBUGIMPL_COMMA(x)
#define COMMA_INDEBUGIMPL(x)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
project(System.IO.Compression.Native)
find_package(ZLIB REQUIRED)
set(NATIVECOMPRESSION_SOURCES
pal_zlib.cpp
)
add_library(System.IO.Compression.Native
SHARED
${NATIVECOMPRESSION_SOURCES}
${VERSION_FILE_PATH}
)
target_link_libraries(System.IO.Compression.Native
${ZLIB_LIBRARIES}
)
install_library_and_symbols (System.IO.Compression.Native)

View File

@@ -0,0 +1,189 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "pal_zlib.h"
#include "pal_utilities.h"
#include <assert.h>
#include <memory>
#include <zlib.h>
static_assert(PAL_Z_NOFLUSH == Z_NO_FLUSH, "");
static_assert(PAL_Z_FINISH == Z_FINISH, "");
static_assert(PAL_Z_OK == Z_OK, "");
static_assert(PAL_Z_STREAMEND == Z_STREAM_END, "");
static_assert(PAL_Z_STREAMERROR == Z_STREAM_ERROR, "");
static_assert(PAL_Z_DATAERROR == Z_DATA_ERROR, "");
static_assert(PAL_Z_MEMERROR == Z_MEM_ERROR, "");
static_assert(PAL_Z_BUFERROR == Z_BUF_ERROR, "");
static_assert(PAL_Z_VERSIONERROR == Z_VERSION_ERROR, "");
static_assert(PAL_Z_NOCOMPRESSION == Z_NO_COMPRESSION, "");
static_assert(PAL_Z_BESTSPEED == Z_BEST_SPEED, "");
static_assert(PAL_Z_DEFAULTCOMPRESSION == Z_DEFAULT_COMPRESSION, "");
static_assert(PAL_Z_DEFAULTSTRATEGY == Z_DEFAULT_STRATEGY, "");
static_assert(PAL_Z_DEFLATED == Z_DEFLATED, "");
/*
Initializes the PAL_ZStream by creating and setting its underlying z_stream.
*/
static int32_t Init(PAL_ZStream* stream)
{
z_stream* zStream = new (std::nothrow) z_stream;
stream->internalState = zStream;
if (zStream != nullptr)
{
zStream->zalloc = Z_NULL;
zStream->zfree = Z_NULL;
zStream->opaque = Z_NULL;
return PAL_Z_OK;
}
else
{
return PAL_Z_MEMERROR;
}
}
/*
Frees any memory on the PAL_ZStream that was created by Init.
*/
static void End(PAL_ZStream* stream)
{
z_stream* zStream = reinterpret_cast<z_stream*>(stream->internalState);
assert(zStream != nullptr);
if (zStream != nullptr)
{
delete zStream;
stream->internalState = nullptr;
}
}
/*
Transfers the output values from the underlying z_stream to the PAL_ZStream.
*/
static void TransferState(z_stream* from, PAL_ZStream* to)
{
to->nextIn = from->next_in;
to->availIn = from->avail_in;
to->nextOut = from->next_out;
to->availOut = from->avail_out;
to->msg = from->msg;
}
/*
Transfers the input values from the PAL_ZStream to the underlying z_stream object.
*/
static void TransferState(PAL_ZStream* from, z_stream* to)
{
to->next_in = from->nextIn;
to->avail_in = from->availIn;
to->next_out = from->nextOut;
to->avail_out = from->availOut;
}
/*
Gets the current z_stream object for the specified PAL_ZStream.
This ensures any inputs are transferred from the PAL_ZStream to the underlying z_stream,
since the current values are always needed.
*/
static z_stream* GetCurrentZStream(PAL_ZStream* stream)
{
z_stream* zStream = reinterpret_cast<z_stream*>(stream->internalState);
assert(zStream != nullptr);
TransferState(stream, zStream);
return zStream;
}
extern "C" int32_t CompressionNative_DeflateInit2_(
PAL_ZStream* stream, int32_t level, int32_t method, int32_t windowBits, int32_t memLevel, int32_t strategy)
{
assert(stream != nullptr);
int32_t result = Init(stream);
if (result == PAL_Z_OK)
{
z_stream* zStream = GetCurrentZStream(stream);
result = deflateInit2(zStream, level, method, windowBits, memLevel, strategy);
TransferState(zStream, stream);
}
return result;
}
extern "C" int32_t CompressionNative_Deflate(PAL_ZStream* stream, int32_t flush)
{
assert(stream != nullptr);
z_stream* zStream = GetCurrentZStream(stream);
int32_t result = deflate(zStream, flush);
TransferState(zStream, stream);
return result;
}
extern "C" int32_t CompressionNative_DeflateEnd(PAL_ZStream* stream)
{
assert(stream != nullptr);
z_stream* zStream = GetCurrentZStream(stream);
int32_t result = deflateEnd(zStream);
End(stream);
return result;
}
extern "C" int32_t CompressionNative_InflateInit2_(PAL_ZStream* stream, int32_t windowBits)
{
assert(stream != nullptr);
int32_t result = Init(stream);
if (result == PAL_Z_OK)
{
z_stream* zStream = GetCurrentZStream(stream);
result = inflateInit2(zStream, windowBits);
TransferState(zStream, stream);
}
return result;
}
extern "C" int32_t CompressionNative_Inflate(PAL_ZStream* stream, int32_t flush)
{
assert(stream != nullptr);
z_stream* zStream = GetCurrentZStream(stream);
int32_t result = inflate(zStream, flush);
TransferState(zStream, stream);
return result;
}
extern "C" int32_t CompressionNative_InflateEnd(PAL_ZStream* stream)
{
assert(stream != nullptr);
z_stream* zStream = GetCurrentZStream(stream);
int32_t result = inflateEnd(zStream);
End(stream);
return result;
}
extern "C" uint32_t CompressionNative_Crc32(uint32_t crc, uint8_t* buffer, int32_t len)
{
assert(buffer != nullptr);
unsigned long result = crc32(crc, buffer, UnsignedCast(len));
assert(result <= UINT32_MAX);
return static_cast<uint32_t>(result);
}

View File

@@ -0,0 +1,124 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "pal_types.h"
/*
A structure that holds the input and output values for the zlib functions.
*/
struct PAL_ZStream
{
uint8_t* nextIn; // next input byte
uint8_t* nextOut; // next output byte should be put there
char* msg; // last error message, NULL if no error
// the underlying z_stream object is held in internalState, but it should not be used by external callers
void* internalState;
uint32_t availIn; // number of bytes available at nextIn
uint32_t availOut; // remaining free space at nextOut
};
/*
Allowed flush values for the Deflate and Inflate functions.
*/
enum PAL_FlushCode : int32_t
{
PAL_Z_NOFLUSH = 0,
PAL_Z_FINISH = 4,
};
/*
Error codes from the zlib functions.
*/
enum PAL_ErrorCode : int32_t
{
PAL_Z_OK = 0,
PAL_Z_STREAMEND = 1,
PAL_Z_STREAMERROR = -2,
PAL_Z_DATAERROR = -3,
PAL_Z_MEMERROR = -4,
PAL_Z_BUFERROR = -5,
PAL_Z_VERSIONERROR = -6
};
/*
Compression levels
*/
enum PAL_CompressionLevel : int32_t
{
PAL_Z_NOCOMPRESSION = 0,
PAL_Z_BESTSPEED = 1,
PAL_Z_DEFAULTCOMPRESSION = -1,
};
/*
Compression strategy
*/
enum PAL_CompressionStrategy : int32_t
{
PAL_Z_DEFAULTSTRATEGY = 0
};
/*
The deflate compression method (the only one supported in this version)
*/
enum PAL_CompressionMethod : int32_t
{
PAL_Z_DEFLATED = 8
};
/*
Initializes the PAL_ZStream so the Deflate function can be invoked on it.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_DeflateInit2_(
PAL_ZStream* stream, int32_t level, int32_t method, int32_t windowBits, int32_t memLevel, int32_t strategy);
/*
Deflates (compresses) the bytes in the PAL_ZStream's nextIn buffer and puts the
compressed bytes in nextOut.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_Deflate(PAL_ZStream* stream, int32_t flush);
/*
All dynamically allocated data structures for this stream are freed.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_DeflateEnd(PAL_ZStream* stream);
/*
Initializes the PAL_ZStream so the Inflate function can be invoked on it.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_InflateInit2_(PAL_ZStream* stream, int32_t windowBits);
/*
Inflates (uncompresses) the bytes in the PAL_ZStream's nextIn buffer and puts the
uncompressed bytes in nextOut.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_Inflate(PAL_ZStream* stream, int32_t flush);
/*
All dynamically allocated data structures for this stream are freed.
Returns a PAL_ErrorCode indicating success or an error number on failure.
*/
extern "C" int32_t CompressionNative_InflateEnd(PAL_ZStream* stream);
/*
Update a running CRC-32 with the bytes buffer[0..len-1] and return the
updated CRC-32.
Returns the updated CRC-32.
*/
extern "C" uint32_t CompressionNative_Crc32(uint32_t crc, uint8_t* buffer, int32_t len);

View File

@@ -0,0 +1,50 @@
project(System.Native)
set(NATIVE_SOURCES
pal_console.cpp
pal_errno.cpp
pal_interfaceaddresses.cpp
pal_io.cpp
pal_maphardwaretype.cpp
pal_memory.cpp
pal_mount.cpp
pal_networking.cpp
pal_networkstatistics.cpp
pal_process.cpp
pal_runtimeinformation.cpp
pal_runtimeextensions.cpp
pal_string.cpp
pal_tcpstate.cpp
pal_time.cpp
pal_uid.cpp
)
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_networkchange.cpp)
if (!HAVE_LINUX_RTNETLINK_H)
message(FATAL_ERROR "Could not find linux/rtnetlink.h")
endif ()
endif ()
add_library(System.Native
SHARED
${NATIVE_SOURCES}
${VERSION_FILE_PATH}
)
add_library(System.Native-Static
STATIC
${NATIVE_SOURCES}
${VERSION_FILE_PATH}
)
SET_TARGET_PROPERTIES(System.Native-Static PROPERTIES PREFIX "")
SET_TARGET_PROPERTIES(System.Native-Static PROPERTIES OUTPUT_NAME System.Native CLEAN_DIRECT_OUTPUT 1)
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
target_link_libraries(System.Native rt)
endif ()
install_library_and_symbols (System.Native)
install (TARGETS System.Native-Static DESTINATION .)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include "pal_types.h"
/**
* Constants for terminal control codes.
*/
enum
{
PAL_VINTR = 0,
PAL_VQUIT = 1,
PAL_VERASE = 2,
PAL_VKILL = 3,
PAL_VEOF = 4,
PAL_VTIME = 5,
PAL_VMIN = 6,
PAL_VSWTC = 7,
PAL_VSTART = 8,
PAL_VSTOP = 9,
PAL_VSUSP = 10,
PAL_VEOL = 11,
PAL_VREPRINT = 12,
PAL_VDISCARD = 13,
PAL_VWERASE = 14,
PAL_VLNEXT = 15,
PAL_VEOL2 = 16
};
/*
* Window Size of the terminal
*/
struct WinSize
{
uint16_t Row;
uint16_t Col;
uint16_t XPixel;
uint16_t YPixel;
};
/**
* Gets the windows size of the terminal
*
* Returns 0 on success; otherwise, returns errorNo.
*/
extern "C" int32_t SystemNative_GetWindowSize(WinSize* windowsSize);
/**
* Gets whether the specified file descriptor is for a terminal.
*
* Returns 1 if the file descriptor is referring to a terminal;
* otherwise returns 0 and sets errno.
*/
extern "C" int32_t SystemNative_IsATty(intptr_t fd);
/**
* Initializes the console for use by System.Console.
*
* Returns 1 on success; otherwise returns 0 and sets errno.
*/
extern "C" int32_t SystemNative_InitializeConsole();
/**
* Stores the string that can be written to stdout to transition
* into "application mode".
*
* Returns 1 on success; otherwise returns 0 and sets errno.
*/
extern "C" void SystemNative_SetKeypadXmit(const char* terminfoString);
/**
* Gets the special control character codes for the requested control characters.
*
* controlCharacterLength is the length of the input controlCharacterNames array and the output controlCharacterValues array.
* The controlCharacterValues array is filled with the control codes for the corresponding control character names,
* or 0 if a particular name is unsupported or disabled. posixDisableValue is the special sentinel used in the output
* controlCharacterValues array to indicate no value is available.
*/
extern "C" void SystemNative_GetControlCharacters(
int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength,
uint8_t* posixDisableValue);
/**
* Returns 1 if any input is waiting on stdin; otherwise, 0.
*/
extern "C" int32_t SystemNative_StdinReady();
/**
* Initializes the terminal in preparation for a read operation.
*/
extern "C" void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout);
/**
* Restores the terminal's attributes to what they were before InitializeConsoleBeforeRead was called.
*/
extern "C" void SystemNative_UninitializeConsoleAfterRead();
/**
* Reads the number of bytes specified into the provided buffer from stdin.
* Returns the number of bytes read on success; otherwise, -1 is returned an errno is set.
*/
extern "C" int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize);
/**
* Gets the terminal's break mode.
*/
extern "C" int32_t SystemNative_GetSignalForBreak();
/**
* Configures the terminal's break mode.
*
* signalForBreak should be 1 to treat break as signals, or 0 to treat break as input.
*
* Returns 1 on success, 0 on failure, in which case errno is set.
*/
extern "C" int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak);
enum CtrlCode : int32_t
{
Interrupt = 0,
Break = 1
};
typedef int32_t (*CtrlCallback)(CtrlCode signalCode);
/**
* Hooks up the specified callback for notifications when SIGINT or SIGQUIT is received.
*
* Not thread safe. Caller must provide its owns synchronization to ensure RegisterForCtrl
* is not called concurrently with itself or with UnregisterForCtrl.
*
* Should only be called when a callback is not currently registered.
*/
extern "C" void SystemNative_RegisterForCtrl(CtrlCallback callback);
/**
* Unregisters the previously registered ctrlCCallback.
*
* Not thread safe. Caller must provide its owns synchronization to ensure UnregisterForCtrl
* is not called concurrently with itself or with RegisterForCtrl.
*
* Should only be called when a callback is currently registered. The pointer
* previously registered must remain valid until all ctrl handling activity
* has quiesced.
*/
extern "C" void SystemNative_UnregisterForCtrl();

View File

@@ -0,0 +1,430 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "pal_config.h"
#include "pal_errno.h"
#include "pal_utilities.h"
#include <errno.h>
// ENODATA is not defined on FreeBSD.
#if defined(__FreeBSD__)
#define ENODATA ENOATTR
#endif
#include <string.h>
#include <assert.h>
extern "C" Error SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno)
{
switch (platformErrno)
{
case 0:
return PAL_SUCCESS;
case E2BIG:
return PAL_E2BIG;
case EACCES:
return PAL_EACCES;
case EADDRINUSE:
return PAL_EADDRINUSE;
case EADDRNOTAVAIL:
return PAL_EADDRNOTAVAIL;
case EAFNOSUPPORT:
return PAL_EAFNOSUPPORT;
case EAGAIN:
return PAL_EAGAIN;
case EALREADY:
return PAL_EALREADY;
case EBADF:
return PAL_EBADF;
case EBADMSG:
return PAL_EBADMSG;
case EBUSY:
return PAL_EBUSY;
case ECANCELED:
return PAL_ECANCELED;
case ECHILD:
return PAL_ECHILD;
case ECONNABORTED:
return PAL_ECONNABORTED;
case ECONNREFUSED:
return PAL_ECONNREFUSED;
case ECONNRESET:
return PAL_ECONNRESET;
case EDEADLK:
return PAL_EDEADLK;
case EDESTADDRREQ:
return PAL_EDESTADDRREQ;
case EDOM:
return PAL_EDOM;
case EDQUOT:
return PAL_EDQUOT;
case EEXIST:
return PAL_EEXIST;
case EFAULT:
return PAL_EFAULT;
case EFBIG:
return PAL_EFBIG;
case EHOSTUNREACH:
return PAL_EHOSTUNREACH;
case EIDRM:
return PAL_EIDRM;
case EILSEQ:
return PAL_EILSEQ;
case EINPROGRESS:
return PAL_EINPROGRESS;
case EINTR:
return PAL_EINTR;
case EINVAL:
return PAL_EINVAL;
case EIO:
return PAL_EIO;
case EISCONN:
return PAL_EISCONN;
case EISDIR:
return PAL_EISDIR;
case ELOOP:
return PAL_ELOOP;
case EMFILE:
return PAL_EMFILE;
case EMLINK:
return PAL_EMLINK;
case EMSGSIZE:
return PAL_EMSGSIZE;
case EMULTIHOP:
return PAL_EMULTIHOP;
case ENAMETOOLONG:
return PAL_ENAMETOOLONG;
case ENETDOWN:
return PAL_ENETDOWN;
case ENETRESET:
return PAL_ENETRESET;
case ENETUNREACH:
return PAL_ENETUNREACH;
case ENFILE:
return PAL_ENFILE;
case ENOBUFS:
return PAL_ENOBUFS;
case ENODEV:
return PAL_ENODEV;
case ENOENT:
return PAL_ENOENT;
case ENOEXEC:
return PAL_ENOEXEC;
case ENOLCK:
return PAL_ENOLCK;
case ENOLINK:
return PAL_ENOLINK;
case ENOMEM:
return PAL_ENOMEM;
case ENOMSG:
return PAL_ENOMSG;
case ENOPROTOOPT:
return PAL_ENOPROTOOPT;
case ENOSPC:
return PAL_ENOSPC;
case ENOSYS:
return PAL_ENOSYS;
case ENOTCONN:
return PAL_ENOTCONN;
case ENOTDIR:
return PAL_ENOTDIR;
case ENOTEMPTY:
return PAL_ENOTEMPTY;
#ifdef ENOTRECOVERABLE // not available in NetBSD
case ENOTRECOVERABLE:
return PAL_ENOTRECOVERABLE;
#endif
case ENOTSOCK:
return PAL_ENOTSOCK;
case ENOTSUP:
return PAL_ENOTSUP;
case ENOTTY:
return PAL_ENOTTY;
case ENXIO:
return PAL_ENXIO;
case EOVERFLOW:
return PAL_EOVERFLOW;
#ifdef EOWNERDEAD // not available in NetBSD
case EOWNERDEAD:
return PAL_EOWNERDEAD;
#endif
case EPERM:
return PAL_EPERM;
case EPIPE:
return PAL_EPIPE;
case EPROTO:
return PAL_EPROTO;
case EPROTONOSUPPORT:
return PAL_EPROTONOSUPPORT;
case EPROTOTYPE:
return PAL_EPROTOTYPE;
case ERANGE:
return PAL_ERANGE;
case EROFS:
return PAL_EROFS;
case ESPIPE:
return PAL_ESPIPE;
case ESRCH:
return PAL_ESRCH;
case ESTALE:
return PAL_ESTALE;
case ETIMEDOUT:
return PAL_ETIMEDOUT;
case ETXTBSY:
return PAL_ETXTBSY;
case EXDEV:
return PAL_EXDEV;
case ESOCKTNOSUPPORT:
return PAL_ESOCKTNOSUPPORT;
case EPFNOSUPPORT:
return PAL_EPFNOSUPPORT;
case ESHUTDOWN:
return PAL_ESHUTDOWN;
case EHOSTDOWN:
return PAL_EHOSTDOWN;
case ENODATA:
return PAL_ENODATA;
// #if because these will trigger duplicate case label warnings when
// they have the same value, which is permitted by POSIX and common.
#if EOPNOTSUPP != ENOTSUP
case EOPNOTSUPP:
return PAL_EOPNOTSUPP;
#endif
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
return PAL_EWOULDBLOCK;
#endif
}
return PAL_ENONSTANDARD;
}
extern "C" int32_t SystemNative_ConvertErrorPalToPlatform(Error error)
{
switch (error)
{
case PAL_SUCCESS:
return 0;
case PAL_E2BIG:
return E2BIG;
case PAL_EACCES:
return EACCES;
case PAL_EADDRINUSE:
return EADDRINUSE;
case PAL_EADDRNOTAVAIL:
return EADDRNOTAVAIL;
case PAL_EAFNOSUPPORT:
return EAFNOSUPPORT;
case PAL_EAGAIN:
return EAGAIN;
case PAL_EALREADY:
return EALREADY;
case PAL_EBADF:
return EBADF;
case PAL_EBADMSG:
return EBADMSG;
case PAL_EBUSY:
return EBUSY;
case PAL_ECANCELED:
return ECANCELED;
case PAL_ECHILD:
return ECHILD;
case PAL_ECONNABORTED:
return ECONNABORTED;
case PAL_ECONNREFUSED:
return ECONNREFUSED;
case PAL_ECONNRESET:
return ECONNRESET;
case PAL_EDEADLK:
return EDEADLK;
case PAL_EDESTADDRREQ:
return EDESTADDRREQ;
case PAL_EDOM:
return EDOM;
case PAL_EDQUOT:
return EDQUOT;
case PAL_EEXIST:
return EEXIST;
case PAL_EFAULT:
return EFAULT;
case PAL_EFBIG:
return EFBIG;
case PAL_EHOSTUNREACH:
return EHOSTUNREACH;
case PAL_EIDRM:
return EIDRM;
case PAL_EILSEQ:
return EILSEQ;
case PAL_EINPROGRESS:
return EINPROGRESS;
case PAL_EINTR:
return EINTR;
case PAL_EINVAL:
return EINVAL;
case PAL_EIO:
return EIO;
case PAL_EISCONN:
return EISCONN;
case PAL_EISDIR:
return EISDIR;
case PAL_ELOOP:
return ELOOP;
case PAL_EMFILE:
return EMFILE;
case PAL_EMLINK:
return EMLINK;
case PAL_EMSGSIZE:
return EMSGSIZE;
case PAL_EMULTIHOP:
return EMULTIHOP;
case PAL_ENAMETOOLONG:
return ENAMETOOLONG;
case PAL_ENETDOWN:
return ENETDOWN;
case PAL_ENETRESET:
return ENETRESET;
case PAL_ENETUNREACH:
return ENETUNREACH;
case PAL_ENFILE:
return ENFILE;
case PAL_ENOBUFS:
return ENOBUFS;
case PAL_ENODEV:
return ENODEV;
case PAL_ENOENT:
return ENOENT;
case PAL_ENOEXEC:
return ENOEXEC;
case PAL_ENOLCK:
return ENOLCK;
case PAL_ENOLINK:
return ENOLINK;
case PAL_ENOMEM:
return ENOMEM;
case PAL_ENOMSG:
return ENOMSG;
case PAL_ENOPROTOOPT:
return ENOPROTOOPT;
case PAL_ENOSPC:
return ENOSPC;
case PAL_ENOSYS:
return ENOSYS;
case PAL_ENOTCONN:
return ENOTCONN;
case PAL_ENOTDIR:
return ENOTDIR;
case PAL_ENOTEMPTY:
return ENOTEMPTY;
#ifdef ENOTRECOVERABLE // not available in NetBSD
case PAL_ENOTRECOVERABLE:
return ENOTRECOVERABLE;
#endif
case PAL_ENOTSOCK:
return ENOTSOCK;
case PAL_ENOTSUP:
return ENOTSUP;
case PAL_ENOTTY:
return ENOTTY;
case PAL_ENXIO:
return ENXIO;
case PAL_EOVERFLOW:
return EOVERFLOW;
#ifdef EOWNERDEAD // not available in NetBSD
case PAL_EOWNERDEAD:
return EOWNERDEAD;
#endif
case PAL_EPERM:
return EPERM;
case PAL_EPIPE:
return EPIPE;
case PAL_EPROTO:
return EPROTO;
case PAL_EPROTONOSUPPORT:
return EPROTONOSUPPORT;
case PAL_EPROTOTYPE:
return EPROTOTYPE;
case PAL_ERANGE:
return ERANGE;
case PAL_EROFS:
return EROFS;
case PAL_ESPIPE:
return ESPIPE;
case PAL_ESRCH:
return ESRCH;
case PAL_ESTALE:
return ESTALE;
case PAL_ETIMEDOUT:
return ETIMEDOUT;
case PAL_ETXTBSY:
return ETXTBSY;
case PAL_EXDEV:
return EXDEV;
case PAL_EPFNOSUPPORT:
return EPFNOSUPPORT;
case PAL_ESOCKTNOSUPPORT:
return ESOCKTNOSUPPORT;
case PAL_ESHUTDOWN:
return ESHUTDOWN;
case PAL_EHOSTDOWN:
return EHOSTDOWN;
case PAL_ENODATA:
return ENODATA;
case PAL_ENONSTANDARD:
break; // fall through to assert
}
// We should not use this function to round-trip platform -> pal
// -> platform. It's here only to synthesize a platform number
// from the fixed set above. Note that the assert is outside the
// switch rather than in a default case block because not
// having a default will trigger a warning (as error) if there's
// an enum value we haven't handled. Should that trigger, make
// note that there is probably a corresponding missing case in the
// other direction above, but the compiler can't warn in that case
// because the platform values are not part of an enum.
assert(false && "Unknown error code");
return -1;
}
extern "C" const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize)
{
assert(buffer != nullptr);
assert(bufferSize > 0);
if (bufferSize < 0)
return nullptr;
// Note that we must use strerror_r because plain strerror is not
// thread-safe.
//
// However, there are two versions of strerror_r:
// - GNU: char* strerror_r(int, char*, size_t);
// - POSIX: int strerror_r(int, char*, size_t);
//
// The former may or may not use the supplied buffer, and returns
// the error message string. The latter stores the error message
// string into the supplied buffer and returns an error code.
#if HAVE_GNU_STRERROR_R
const char* message = strerror_r(platformErrno, buffer, UnsignedCast(bufferSize));
assert(message != nullptr);
return message;
#else
int error = strerror_r(platformErrno, buffer, UnsignedCast(bufferSize));
if (error == ERANGE)
{
// Buffer is too small to hold the entire message, but has
// still been filled to the extent possible and null-terminated.
return nullptr;
}
// The only other valid error codes are 0 for success or EINVAL for
// an unkown error, but in the latter case a reasonable string (e.g
// "Unknown error: 0x123") is returned.
assert(error == 0 || error == EINVAL);
return buffer;
#endif
}

View File

@@ -0,0 +1,161 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include "pal_types.h"
/**
* Error codes returned via ConvertErrno.
*
* Only the names (without the PAL_ prefix) are specified by POSIX.
*
* The values chosen below are simply assigned arbitrarily (originally
* in alphabetical order they appear in the spec, but they can't change so
* add new values to the end!).
*
* Also, the values chosen are deliberately outside the range of
* typical UNIX errnos (small numbers), HRESULTs (negative for errors)
* and Win32 errors (0x0000 - 0xFFFF). This isn't required for
* correctness, but may help debug a caller that is interpreting a raw
* int incorrectly.
*
* Wherever the spec says "x may be the same value as y", we do use
* the same value so that callers cannot not take a dependency on
* being able to distinguish between them.
*/
enum Error : int32_t
{
PAL_SUCCESS = 0,
PAL_E2BIG = 0x10001, // Argument list too long.
PAL_EACCES = 0x10002, // Permission denied.
PAL_EADDRINUSE = 0x10003, // Address in use.
PAL_EADDRNOTAVAIL = 0x10004, // Address not available.
PAL_EAFNOSUPPORT = 0x10005, // Address family not supported.
PAL_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK),
PAL_EALREADY = 0x10007, // Connection already in progress.
PAL_EBADF = 0x10008, // Bad file descriptor.
PAL_EBADMSG = 0x10009, // Bad message.
PAL_EBUSY = 0x1000A, // Device or resource busy.
PAL_ECANCELED = 0x1000B, // Operation canceled.
PAL_ECHILD = 0x1000C, // No child processes.
PAL_ECONNABORTED = 0x1000D, // Connection aborted.
PAL_ECONNREFUSED = 0x1000E, // Connection refused.
PAL_ECONNRESET = 0x1000F, // Connection reset.
PAL_EDEADLK = 0x10010, // Resource deadlock would occur.
PAL_EDESTADDRREQ = 0x10011, // Destination address required.
PAL_EDOM = 0x10012, // Mathematics argument out of domain of function.
PAL_EDQUOT = 0x10013, // Reserved.
PAL_EEXIST = 0x10014, // File exists.
PAL_EFAULT = 0x10015, // Bad address.
PAL_EFBIG = 0x10016, // File too large.
PAL_EHOSTUNREACH = 0x10017, // Host is unreachable.
PAL_EIDRM = 0x10018, // Identifier removed.
PAL_EILSEQ = 0x10019, // Illegal byte sequence.
PAL_EINPROGRESS = 0x1001A, // Operation in progress.
PAL_EINTR = 0x1001B, // Interrupted function.
PAL_EINVAL = 0x1001C, // Invalid argument.
PAL_EIO = 0x1001D, // I/O error.
PAL_EISCONN = 0x1001E, // Socket is connected.
PAL_EISDIR = 0x1001F, // Is a directory.
PAL_ELOOP = 0x10020, // Too many levels of symbolic links.
PAL_EMFILE = 0x10021, // File descriptor value too large.
PAL_EMLINK = 0x10022, // Too many links.
PAL_EMSGSIZE = 0x10023, // Message too large.
PAL_EMULTIHOP = 0x10024, // Reserved.
PAL_ENAMETOOLONG = 0x10025, // Filename too long.
PAL_ENETDOWN = 0x10026, // Network is down.
PAL_ENETRESET = 0x10027, // Connection aborted by network.
PAL_ENETUNREACH = 0x10028, // Network unreachable.
PAL_ENFILE = 0x10029, // Too many files open in system.
PAL_ENOBUFS = 0x1002A, // No buffer space available.
PAL_ENODEV = 0x1002C, // No such device.
PAL_ENOENT = 0x1002D, // No such file or directory.
PAL_ENOEXEC = 0x1002E, // Executable file format error.
PAL_ENOLCK = 0x1002F, // No locks available.
PAL_ENOLINK = 0x10030, // Reserved.
PAL_ENOMEM = 0x10031, // Not enough space.
PAL_ENOMSG = 0x10032, // No message of the desired type.
PAL_ENOPROTOOPT = 0x10033, // Protocol not available.
PAL_ENOSPC = 0x10034, // No space left on device.
PAL_ENOSYS = 0x10037, // Function not supported.
PAL_ENOTCONN = 0x10038, // The socket is not connected.
PAL_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory.
PAL_ENOTEMPTY = 0x1003A, // Directory not empty.
PAL_ENOTRECOVERABLE = 0x1003B, // State not recoverable.
PAL_ENOTSOCK = 0x1003C, // Not a socket.
PAL_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP).
PAL_ENOTTY = 0x1003E, // Inappropriate I/O control operation.
PAL_ENXIO = 0x1003F, // No such device or address.
PAL_EOVERFLOW = 0x10040, // Value too large to be stored in data type.
PAL_EOWNERDEAD = 0x10041, // Previous owner died.
PAL_EPERM = 0x10042, // Operation not permitted.
PAL_EPIPE = 0x10043, // Broken pipe.
PAL_EPROTO = 0x10044, // Protocol error.
PAL_EPROTONOSUPPORT = 0x10045, // Protocol not supported.
PAL_EPROTOTYPE = 0x10046, // Protocol wrong type for socket.
PAL_ERANGE = 0x10047, // Result too large.
PAL_EROFS = 0x10048, // Read-only file system.
PAL_ESPIPE = 0x10049, // Invalid seek.
PAL_ESRCH = 0x1004A, // No such process.
PAL_ESTALE = 0x1004B, // Reserved.
PAL_ETIMEDOUT = 0x1004D, // Connection timed out.
PAL_ETXTBSY = 0x1004E, // Text file busy.
PAL_EXDEV = 0x1004F, // Cross-device link.
PAL_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported.
PAL_EPFNOSUPPORT = 0x10060, // Protocol family not supported.
PAL_ESHUTDOWN = 0x1006C, // Socket shutdown.
PAL_EHOSTDOWN = 0x10070, // Host is down.
PAL_ENODATA = 0x10071, // No data available.
// POSIX permits these to have the same value and we make them
// always equal so that we cannot introduce a dependency on
// distinguishing between them that would not work on all
// platforms.
PAL_EOPNOTSUPP = PAL_ENOTSUP, // Operation not supported on socket
PAL_EWOULDBLOCK = PAL_EAGAIN, // Operation would block
// This one is not part of POSIX, but is a catch-all for the case
// where we cannot convert the raw errno value to something above.
PAL_ENONSTANDARD = 0x1FFFF,
};
/**
* Converts the given raw numeric value obtained via errno ->
* GetLastWin32Error() to a standard numeric value defined by enum
* Error above. If the value is not recognized, returns
* PAL_ENONSTANDARD.
*/
extern "C" Error SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno);
/**
* Converts the given PAL Error value to a platform-specific errno
* value. This is to be used when we want to synthesize a given error
* and obtain the appropriate error message via StrErrorR.
*/
extern "C" int32_t SystemNative_ConvertErrorPalToPlatform(Error error);
/**
* Obtains the system error message for the given raw numeric value
* obtained by errno/ Marhsal.GetLastWin32Error().
*
* By design, this does not take a PAL errno, but a raw system errno,
* so that:
*
* 1. We don't waste cycles converting back and forth (generally, if
* we have a PAL errno, we had a platform errno just a few
* instructions ago.)
*
* 2. We don't lose the ability to get the system error message for
* non-standard, platform-specific errors.
*
* Note that buffer may or may not be used and the error message is
* passed back via the return value.
*
* If the buffer was too small to fit the full message, null is
* returned and the buffer is filled with as much of the message
* as possible and null-terminated.
*/
extern "C" const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize);

View File

@@ -0,0 +1,196 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "pal_config.h"
#include "pal_interfaceaddresses.h"
#include "pal_maphardwaretype.h"
#include "pal_utilities.h"
#include "pal_safecrt.h"
#include <sys/types.h>
#include <assert.h>
#include <ifaddrs.h>
#include <memory>
#include <net/if.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#if HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#if defined(AF_PACKET)
#include <linux/if_packet.h>
#elif defined(AF_LINK)
#include <net/if_dl.h>
#include <net/if_types.h>
#else
#error System must have AF_PACKET or AF_LINK.
#endif
#if HAVE_RT_MSGHDR
#include <net/route.h>
#endif
extern "C" int32_t SystemNative_EnumerateInterfaceAddresses(IPv4AddressFound onIpv4Found,
IPv6AddressFound onIpv6Found,
LinkLayerAddressFound onLinkLayerFound)
{
ifaddrs* headAddr;
if (getifaddrs(&headAddr) == -1)
{
return -1;
}
for (ifaddrs* current = headAddr; current != nullptr; current = current->ifa_next)
{
uint32_t interfaceIndex = if_nametoindex(current->ifa_name);
// ifa_name may be an aliased interface name.
// Use if_indextoname to map back to the true device name.
char actualName[IF_NAMESIZE];
char* result = if_indextoname(interfaceIndex, actualName);
if (result == nullptr)
{
freeifaddrs(headAddr);
return -1;
}
assert(result == actualName);
int family = current->ifa_addr->sa_family;
if (family == AF_INET)
{
if (onIpv4Found != nullptr)
{
// IP Address
IpAddressInfo iai;
memset(&iai, 0, sizeof(IpAddressInfo));
iai.InterfaceIndex = interfaceIndex;
iai.NumAddressBytes = NUM_BYTES_IN_IPV4_ADDRESS;
sockaddr_in* sain = reinterpret_cast<sockaddr_in*>(current->ifa_addr);
memcpy_s(iai.AddressBytes, sizeof(IpAddressInfo::AddressBytes), &sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr));
// Net Mask
IpAddressInfo maskInfo;
memset(&maskInfo, 0, sizeof(IpAddressInfo));
maskInfo.InterfaceIndex = interfaceIndex;
maskInfo.NumAddressBytes = NUM_BYTES_IN_IPV4_ADDRESS;
sockaddr_in* mask_sain = reinterpret_cast<sockaddr_in*>(current->ifa_netmask);
memcpy_s(maskInfo.AddressBytes, sizeof(IpAddressInfo::AddressBytes), &mask_sain->sin_addr.s_addr, sizeof(mask_sain->sin_addr.s_addr));
onIpv4Found(actualName, &iai, &maskInfo);
}
}
else if (family == AF_INET6)
{
if (onIpv6Found != nullptr)
{
IpAddressInfo iai;
memset(&iai, 0, sizeof(IpAddressInfo));
iai.InterfaceIndex = interfaceIndex;
iai.NumAddressBytes = NUM_BYTES_IN_IPV6_ADDRESS;
sockaddr_in6* sain6 = reinterpret_cast<sockaddr_in6*>(current->ifa_addr);
memcpy_s(iai.AddressBytes, sizeof(IpAddressInfo::AddressBytes), sain6->sin6_addr.s6_addr, sizeof(sain6->sin6_addr.s6_addr));
uint32_t scopeId = sain6->sin6_scope_id;
onIpv6Found(actualName, &iai, &scopeId);
}
}
#if defined(AF_PACKET)
else if (family == AF_PACKET)
{
if (onLinkLayerFound != nullptr)
{
sockaddr_ll* sall = reinterpret_cast<sockaddr_ll*>(current->ifa_addr);
LinkLayerAddressInfo lla;
memset(&lla, 0, sizeof(LinkLayerAddressInfo));
lla.InterfaceIndex = interfaceIndex;
lla.NumAddressBytes = sall->sll_halen;
lla.HardwareType = MapHardwareType(sall->sll_hatype);
memcpy_s(&lla.AddressBytes, sizeof(LinkLayerAddressInfo::AddressBytes), &sall->sll_addr, sall->sll_halen);
onLinkLayerFound(current->ifa_name, &lla);
}
}
#elif defined(AF_LINK)
else if (family == AF_LINK)
{
if (onLinkLayerFound != nullptr)
{
sockaddr_dl* sadl = reinterpret_cast<sockaddr_dl*>(current->ifa_addr);
LinkLayerAddressInfo lla = {
.InterfaceIndex = interfaceIndex,
.NumAddressBytes = sadl->sdl_alen,
.HardwareType = MapHardwareType(sadl->sdl_type),
};
memcpy_s(&lla.AddressBytes, sizeof(LinkLayerAddressInfo::AddressBytes), reinterpret_cast<uint8_t*>(LLADDR(sadl)), sadl->sdl_alen);
onLinkLayerFound(current->ifa_name, &lla);
}
}
#endif
}
freeifaddrs(headAddr);
return 0;
}
#if HAVE_RT_MSGHDR
extern "C" int32_t SystemNative_EnumerateGatewayAddressesForInterface(uint32_t interfaceIndex, GatewayAddressFound onGatewayFound)
{
int routeDumpName[] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0};
size_t byteCount;
if (sysctl(routeDumpName, 6, nullptr, &byteCount, nullptr, 0) != 0)
{
return -1;
}
uint8_t* buffer = new (std::nothrow) uint8_t[byteCount];
if (buffer == nullptr)
{
errno = ENOMEM;
return -1;
}
while (sysctl(routeDumpName, 6, buffer, &byteCount, nullptr, 0) != 0)
{
delete[] buffer;
buffer = new (std::nothrow) uint8_t[byteCount];
if (buffer == nullptr)
{
errno = ENOMEM;
return -1;
}
}
rt_msghdr* hdr;
for (size_t i = 0; i < byteCount; i += hdr->rtm_msglen)
{
hdr = reinterpret_cast<rt_msghdr*>(&buffer[i]);
int flags = hdr->rtm_flags;
int isGateway = flags & RTF_GATEWAY;
int gatewayPresent = hdr->rtm_addrs & RTA_GATEWAY;
if (isGateway && gatewayPresent)
{
IpAddressInfo iai = {};
iai.InterfaceIndex = interfaceIndex;
iai.NumAddressBytes = NUM_BYTES_IN_IPV4_ADDRESS;
sockaddr_in* sain = reinterpret_cast<sockaddr_in*>(hdr + 1);
sain = sain + 1; // Skip over the first sockaddr, the destination address. The second is the gateway.
memcpy_s(iai.AddressBytes, sizeof(IpAddressInfo::AddressBytes), &sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr));
onGatewayFound(&iai);
}
}
delete[] buffer;
return 0;
}
#endif // HAVE_RT_MSGHDR

View File

@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include "pal_maphardwaretype.h"
#include "pal_types.h"
struct LinkLayerAddressInfo
{
uint32_t InterfaceIndex; // The index of the interface to which this address belongs.
uint8_t AddressBytes[8]; // A pointer to the bytes containing the address.
uint8_t NumAddressBytes; // The number of bytes actually stored in the address.
uint8_t __padding;
NetworkInterfaceType HardwareType;
};
struct IpAddressInfo
{
uint32_t InterfaceIndex;
uint8_t AddressBytes[16];
uint8_t NumAddressBytes;
uint8_t __padding[3];
};
typedef void (*IPv4AddressFound)(const char* interfaceName, IpAddressInfo* addressInfo, IpAddressInfo* netMaskInfo);
typedef void (*IPv6AddressFound)(const char* interfaceName, IpAddressInfo* info, uint32_t* scopeId);
typedef void (*LinkLayerAddressFound)(const char* interfaceName, LinkLayerAddressInfo* llAddress);
typedef void (*GatewayAddressFound)(IpAddressInfo* addressInfo);
int32_t EnumerateGatewayAddressesForInterface(uint32_t interfaceIndex,
GatewayAddressFound onGatewayFound,
uint16_t addressFamily);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More