Skip to content

Instantly share code, notes, and snippets.

@NattyNarwhal
Created May 31, 2018 13:07
Show Gist options
  • Save NattyNarwhal/dd0d2a85400d11e9cf4fd959dd760dc3 to your computer and use it in GitHub Desktop.
Save NattyNarwhal/dd0d2a85400d11e9cf4fd959dd760dc3 to your computer and use it in GitHub Desktop.
diff --git a/src/Native/Unix/System.Native/pal_errno.c b/src/Native/Unix/System.Native/pal_errno.c
index 3a7972369..4cff18a 100644
--- a/src/Native/Unix/System.Native/pal_errno.c
+++ b/src/Native/Unix/System.Native/pal_errno.c
@@ -130,8 +130,10 @@ int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno)
return Error_ENOTCONN;
case ENOTDIR:
return Error_ENOTDIR;
+#if !defined(_AIX)
case ENOTEMPTY:
return Error_ENOTEMPTY;
+#endif
#ifdef ENOTRECOVERABLE // not available in NetBSD
case ENOTRECOVERABLE:
return Error_ENOTRECOVERABLE;
diff --git a/src/Native/Unix/System.Native/pal_io.c b/src/Native/Unix/System.Native/pal_io.c
index 320dccd..fd8354d 100644
--- a/src/Native/Unix/System.Native/pal_io.c
+++ b/src/Native/Unix/System.Native/pal_io.c
@@ -2,6 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#ifdef _AIX
+// For getline (declare this before stdio)
+#define _GETDELIM 1
+#endif
+
#include "pal_compiler.h"
#include "pal_config.h"
#include "pal_errno.h"
@@ -37,6 +42,13 @@
#include <sys/inotify.h>
#endif
+#if defined(_AIX)
+#include <alloca.h>
+// Somehow, AIX mangles the definition for this behind a C++ def
+// Redeclare it here
+extern int getpeereid(int, uid_t *__restrict__, gid_t *__restrict__);
+#endif
+
#if HAVE_STAT64
#define stat_ stat64
#define fstat_ fstat64
@@ -78,6 +90,8 @@ c_static_assert(PAL_S_IFSOCK == S_IFSOCK);
// Validate that our enum for inode types is the same as what is
// declared by the dirent.h header on the local system.
+// (AIX doesn't have dirent d_type, so none of this there)
+#if !defined(_AIX)
c_static_assert(PAL_DT_UNKNOWN == DT_UNKNOWN);
c_static_assert(PAL_DT_FIFO == DT_FIFO);
c_static_assert(PAL_DT_CHR == DT_CHR);
@@ -87,6 +101,7 @@ c_static_assert(PAL_DT_REG == DT_REG);
c_static_assert(PAL_DT_LNK == DT_LNK);
c_static_assert(PAL_DT_SOCK == DT_SOCK);
c_static_assert(PAL_DT_WHT == DT_WHT);
+#endif
// Validate that our Lock enum value are correct for the platform
c_static_assert(PAL_LOCK_SH == LOCK_SH);
@@ -233,14 +248,20 @@ static int32_t ConvertOpenFlags(int32_t flags)
return -1;
}
+#if defined(_AIX)
+ if (flags & ~(PAL_O_ACCESS_MODE_MASK | PAL_O_CREAT | PAL_O_EXCL | PAL_O_TRUNC | PAL_O_SYNC))
+#else
if (flags & ~(PAL_O_ACCESS_MODE_MASK | PAL_O_CLOEXEC | PAL_O_CREAT | PAL_O_EXCL | PAL_O_TRUNC | PAL_O_SYNC))
+#endif
{
assert_msg(false, "Unknown Open flag", (int)flags);
return -1;
}
+#if !defined(_AIX)
if (flags & PAL_O_CLOEXEC)
ret |= O_CLOEXEC;
+#endif
if (flags & PAL_O_CREAT)
ret |= O_CREAT;
if (flags & PAL_O_EXCL)
@@ -265,6 +286,14 @@ intptr_t SystemNative_Open(const char* path, int32_t flags, int32_t mode)
int result;
while ((result = open(path, flags, (mode_t)mode)) < 0 && errno == EINTR);
+#if defined(_AIX)
+ // the versions of AIX and PASE we target don't all have O_CLOEXEC
+ // so simulate it
+ if (flags & PAL_O_CLOEXEC)
+ {
+ fcntl(result, F_SETFD, FD_CLOEXEC);
+ }
+#endif
return result;
}
@@ -325,7 +354,30 @@ static void ConvertDirent(const struct dirent* entry, struct DirectoryEntry* out
// the start of the unmanaged string. Give the caller back a pointer to the
// location of the start of the string that exists in their own byte buffer.
outputEntry->Name = entry->d_name;
+#if defined(_AIX)
+ /* AIX has no d_type, make a substitute */
+ struct stat s;
+ stat(entry->d_name, &s);
+ if (S_ISDIR(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_DIR;
+ } else if (S_ISFIFO(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_FIFO;
+ } else if (S_ISCHR(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_CHR;
+ } else if (S_ISBLK(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_BLK;
+ } else if (S_ISREG(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_REG;
+ } else if (S_ISLNK(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_LNK;
+ } else if (S_ISSOCK(s.st_mode)) {
+ outputEntry->InodeType = PAL_DT_SOCK;
+ } else {
+ outputEntry->InodeType = PAL_DT_UNKNOWN;
+ }
+#else
outputEntry->InodeType = (int32_t)entry->d_type;
+#endif
#if HAVE_DIRENT_NAME_LEN
outputEntry->NameLength = entry->d_namlen;
diff --git a/src/Native/Unix/System.Native/pal_io.h b/src/Native/Unix/System.Native/pal_io.h
index b12485f..0f4771b 100644
--- a/src/Native/Unix/System.Native/pal_io.h
+++ b/src/Native/Unix/System.Native/pal_io.h
@@ -15,6 +15,17 @@ BEGIN_EXTERN_C
#include <dirent.h>
#include <sys/types.h>
+#if defined(_AIX) && !defined(O_CLOEXEC)
+// HACK: Try to get AIX 6.1 & i 7.1 working; AIX 7.1 & i (claims) 7.2 has these but we target
+// these older versions too.
+// We ifdef it out for the open call in .c and simulate with fcntl, but for SystemNative_Pipe,
+// since we also don't have pipe2 on AIX/i, it'll fall back to using FD_CLOEXEC.
+// (i 7.2 at least defines O_CLOEXEC as 0x0000001000000000LL)
+#define 0x0000001000000000LL
+// Nop this out
+#define F_DUPFD_CLOEXEC 0
+#endif
+
/**
* File status returned by Stat or FStat.
*/
diff --git a/src/Native/Unix/System.Native/pal_maphardwaretype.c b/src/Native/Unix/System.Native/pal_maphardwaretype.c
index d1284cb..7f8e825 100644
--- a/src/Native/Unix/System.Native/pal_maphardwaretype.c
+++ b/src/Native/Unix/System.Native/pal_maphardwaretype.c
@@ -76,8 +76,10 @@ uint16_t MapHardwareType(uint16_t nativeType)
return NetworkInterfaceType_Atm;
case IFT_MODEM:
return NetworkInterfaceType_GenericModem;
+#if defined(IFT_IEEE1394)
case IFT_IEEE1394:
return NetworkInterfaceType_HighPerformanceSerialBus;
+#endif
default:
return NetworkInterfaceType_Unknown;
}
diff --git a/src/Native/Unix/System.Native/pal_networking.c b/src/Native/Unix/System.Native/pal_networking.c
index 6868539..54dffe3 100644
--- a/src/Native/Unix/System.Native/pal_networking.c
+++ b/src/Native/Unix/System.Native/pal_networking.c
@@ -20,6 +20,8 @@
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
+#else
+#include <sys/poll.h>
#endif
#include <errno.h>
#include <netdb.h>
@@ -39,15 +41,19 @@
#endif
#include <unistd.h>
#include <pwd.h>
+#if !defined(_AIX)
#if HAVE_SENDFILE_4
#include <sys/sendfile.h>
#elif HAVE_SENDFILE_6
#include <sys/uio.h>
#endif
+#endif
#if !HAVE_IN_PKTINFO
#include <net/if.h>
+#if !defined(_AIX)
#include <ifaddrs.h>
#endif
+#endif
#if HAVE_KQUEUE
#if KEVENT_HAS_VOID_UDATA
@@ -782,6 +788,8 @@ static int32_t GetIPv4PacketInformation(struct cmsghdr* controlMessage, struct I
ConvertInAddrToByteArray(&packetInfo->Address.Address[0], NUM_BYTES_IN_IPV4_ADDRESS, &pktinfo->ipi_addr);
#if HAVE_IN_PKTINFO
packetInfo->InterfaceIndex = (int32_t)pktinfo->ipi_ifindex;
+#elif defined(_AIX)
+ // TODO: SIOCGIFCONF based fallback
#else
packetInfo->InterfaceIndex = 0;
@@ -2247,7 +2255,32 @@ static int32_t WaitForSocketEventsInner(int32_t port, struct SocketEvent* buffer
}
#else
-#error Asynchronous sockets require epoll or kqueue support.
+// TODO: Poll fallback
+static const size_t SocketEventBufferElementSize = sizeof(struct pollmsg);
+
+static enum SocketEvents GetSocketEvents(int16_t filter, uint16_t flags)
+{
+ return SocketEvents_SA_NONE;
+}
+static int32_t CloseSocketEventPortInner(int32_t port)
+{
+ return Error_ENOSYS;
+}
+static int32_t CreateSocketEventPortInner(int32_t* port)
+{
+ return Error_ENOSYS;
+}
+static int32_t TryChangeSocketEventRegistrationInner(
+ int32_t port, int32_t socket, enum SocketEvents currentEvents, enum SocketEvents newEvents,
+uintptr_t data)
+{
+ return Error_ENOSYS;
+}
+static int32_t WaitForSocketEventsInner(int32_t port, struct SocketEvent* buffer, int32_t* count)
+{
+ return Error_ENOSYS;
+}
+
#endif
int32_t SystemNative_CreateSocketEventPort(intptr_t* port)
@@ -2413,7 +2446,7 @@ int32_t SystemNative_SendFile(intptr_t out_fd, intptr_t in_fd, int64_t offset, i
*sent = 0;
return SystemNative_ConvertErrorPlatformToPal(errno);
-#elif HAVE_SENDFILE_6
+#elif HAVE_SENDFILE_6 && !defined(_AIX) /* why is AIX getting this? */
*sent = 0;
while (1) // in case we need to retry for an EINTR
{
diff --git a/src/Native/Unix/System.Native/pal_random.c b/src/Native/Unix/System.Native/pal_random.c
index a46896e..e82631b 100644
--- a/src/Native/Unix/System.Native/pal_random.c
+++ b/src/Native/Unix/System.Native/pal_random.c
@@ -40,7 +40,12 @@ void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int3
do
{
+#ifdef O_CLOEXEC
fd = open("/dev/urandom", O_RDONLY, O_CLOEXEC);
+#else
+ fd = open("/dev/urandom", O_RDONLY, NULL);
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
}
while ((fd == -1) && (errno == EINTR));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment