mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Add configure to CMake to detect GNU strerror_r
* Add getstrerror to libpsl-native * Add Unix.GetLastPerror to CorePsPlatform
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -9,4 +9,5 @@ Testing/
|
||||
test/psl-native-test
|
||||
src/libpsl-native.so
|
||||
src/libpsl-native.dylib
|
||||
src/config.h
|
||||
test/native-tests.xml
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#cmakedefine HAVE_GNU_STRERROR_R 1
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* GetStrError(int);
|
||||
|
||||
PAL_END_EXTERNC
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
Reference in New Issue
Block a user