Add configure to CMake to detect GNU strerror_r

* Add getstrerror to libpsl-native
* Add Unix.GetLastPerror to CorePsPlatform
This commit is contained in:
Andrew Schwartzmeyer
2016-10-14 15:30:19 -07:00
parent b0cd7ba3dc
commit 6c3e536ca8
7 changed files with 78 additions and 0 deletions
@@ -453,6 +453,11 @@ namespace System.Management.Automation
internal static class Unix
{
internal static string GetLastPerror()
{
return Unix.NativeMethods.GetStrError(Marshal.GetLastWin32Error());
}
private static string s_userName;
public static string UserName
{
@@ -568,6 +573,10 @@ namespace System.Management.Automation
// C bools are 1 byte and so must be marshaled as I1
[DllImport(psLib, CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string GetStrError(int errno);
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string GetUserName();
+1
View File
@@ -9,4 +9,5 @@ Testing/
test/psl-native-test
src/libpsl-native.so
src/libpsl-native.dylib
src/config.h
test/native-tests.xml
+16
View File
@@ -1,3 +1,18 @@
include(CheckCXXSourceCompiles)
check_cxx_source_compiles(
"
#include <string.h>
int main()
{
char buffer[1];
char* c = strerror_r(0, buffer, 0);
(void)c;
}
"
HAVE_GNU_STRERROR_R)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
add_library(psl-native SHARED
getstat.cpp
getlstat.cpp
@@ -9,6 +24,7 @@ add_library(psl-native SHARED
getcomputername.cpp
getlinkcount.cpp
getfullyqualifiedname.cpp
getstrerror.cpp
isfile.cpp
isdirectory.cpp
issymlink.cpp
+1
View File
@@ -0,0 +1 @@
#cmakedefine HAVE_GNU_STRERROR_R 1
+40
View File
@@ -0,0 +1,40 @@
#include "getstrerror.h"
#include <assert.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
char* GetStrError(int errnum)
{
size_t buflen = 256;
char* buf = (char*)calloc(buflen, sizeof(char));
// 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* ret = strerror_r(errnum, buf, buflen);
assert(ret != NULL);
if (ret != buf)
{
// message was returned but is static, copy for return
strncpy(buf, ret, buflen);
}
#else
int ret = strerror_r(errnum, buf, buflen);
// EINVAL: unknown error but reasonable message returned.
// ERANGE: too small for entire message, but still filled and null-terminated.
assert(ret == 0 || ret == EINVAL || ret == ERANGE);
#endif
return buf;
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "pal.h"
PAL_BEGIN_EXTERNC
char* GetStrError(int);
PAL_END_EXTERNC
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>