Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion src/native/corehost/hostmisc/pal.unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#endif
#elif defined(TARGET_HAIKU)
#include <image.h>
#include <OS.h>
#include <sys/utsname.h>
#endif // TARGET_HAIKU

#if !HAVE_DIRENT_D_TYPE
#define DT_UNKNOWN 0
Expand Down Expand Up @@ -136,6 +140,7 @@ bool pal::getcwd(pal::string_t* recv)
return true;
}

#if !defined(TARGET_HAIKU)
namespace
{
bool get_loaded_library_from_proc_maps(const pal::char_t* library_name, pal::dll_t* dll, pal::string_t* path)
Expand Down Expand Up @@ -183,6 +188,7 @@ namespace
return true;
}
}
#endif // !TARGET_HAIKU

bool pal::get_loaded_library(
const char_t* library_name,
Expand All @@ -197,6 +203,33 @@ bool pal::get_loaded_library(
#endif
library_name_local.append(library_name);

#if defined(TARGET_HAIKU)
// Haiku does not have RTLD_NOLOAD so dlopen will attempt to load the library
// instead of fetching a handle to the already loaded one.
int32 cookie = 0;
image_info info;

while (get_next_image_info(0, &cookie, &info) == B_OK)
{
if (info.type != B_LIBRARY_IMAGE)
continue;

pal::string_t path_local(info.name);
size_t pos = path_local.rfind(DIR_SEPARATOR);
if (pos == std::string::npos)
continue;

pos = path_local.find(library_name, pos);
if (pos != std::string::npos)
{
*dll = (pal::dll_t)(intptr_t)info.id;
path->assign(path_local);
return true;
}
}

return false;
#else
dll_t dll_maybe = dlopen(library_name_local.c_str(), RTLD_LAZY | RTLD_NOLOAD);
if (dll_maybe == nullptr)
{
Expand All @@ -223,6 +256,7 @@ bool pal::get_loaded_library(
*dll = dll_maybe;
path->assign(info.dli_fname);
return true;
#endif // !TARGET_HAIKU
}

bool pal::load_library(const string_t* path, dll_t* dll)
Expand Down Expand Up @@ -768,6 +802,21 @@ pal::string_t pal::get_current_os_rid_platform()

return ridOS;
}
#elif defined(TARGET_HAIKU)
pal::string_t pal::get_current_os_rid_platform()
{
pal::string_t ridOS;
struct utsname utsname_obj;
if (uname(&utsname_obj) < 0)
{
return ridOS;
}

ridOS.append(_X("haiku."))
.append(utsname_obj.release); // e.g. haiku.1

return ridOS;
}
#else
// For some distros, we don't want to use the full version from VERSION_ID. One example is
// Red Hat Enterprise Linux, which includes a minor version in their VERSION_ID but minor
Expand Down
2 changes: 1 addition & 1 deletion src/native/eventpipe/ds-ipc-pal-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ inline
int
ipc_socket_set_permission (ds_ipc_socket_t s)
{
#if defined(DS_IPC_PAL_AF_UNIX) && !(defined(__APPLE__) || defined(__FreeBSD__))
#if defined(DS_IPC_PAL_AF_UNIX) && !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__HAIKU__))
int result_fchmod;
DS_ENTER_BLOCKING_PAL_SECTION;
do {
Expand Down
5 changes: 5 additions & 0 deletions src/native/libs/Common/pal_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#cmakedefine01 HAVE_MNTINFO
#cmakedefine01 HAVE_STATFS_FSTYPENAME
#cmakedefine01 HAVE_STATVFS_FSTYPENAME
#cmakedefine01 HAVE_STATVFS_BASETYPE
#cmakedefine01 HAVE_NON_LEGACY_STATFS
#cmakedefine01 HAVE_STRCPY_S
#cmakedefine01 HAVE_STRLCPY
Expand Down Expand Up @@ -88,6 +89,7 @@
#cmakedefine01 HAVE_NETPACKET_PACKET_H
#cmakedefine01 HAVE_NET_IF_ARP_H
#cmakedefine01 HAVE_SYS_MNTENT_H
#cmakedefine01 HAVE_MNTENT_H
#cmakedefine01 HAVE_NET_IFMEDIA_H
#cmakedefine01 HAVE_IOS_NET_IFMEDIA_H
#cmakedefine01 HAVE_LINUX_RTNETLINK_H
Expand Down Expand Up @@ -128,6 +130,7 @@
#cmakedefine01 HAVE_TERMIOS_H
#cmakedefine01 HAVE_DLFCN_H
#cmakedefine01 HAVE_PTHREAD_H
#cmakedefine01 HAVE_SYS_STATFS_H
#cmakedefine01 HAVE_SYS_STATVFS_H
#cmakedefine01 HAVE_NET_IF_H
#cmakedefine01 HAVE_SYS_PROCINFO_H
Expand All @@ -141,6 +144,8 @@
#cmakedefine01 HAVE_MAKEDEV_SYSMACROSH
#cmakedefine01 HAVE_GETGRGID_R
#cmakedefine01 HAVE_TERMIOS2
#cmakedefine01 HAVE_DIRENT_NAME_SIZE
#cmakedefine01 DIRENT_NAME_SIZE

#ifndef HOST_WASI
#cmakedefine01 HAVE_GETRUSAGE
Expand Down
3 changes: 3 additions & 0 deletions src/native/libs/System.Native/pal_dynamicload.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ void* SystemNative_LoadLibrary(const char* filename)
// As a result, we have to use the full name (i.e. lib.so.6) that is defined by LIBC_SO.
// * For macOS, use constant value absolute path "/usr/lib/libc.dylib".
// * For FreeBSD, use constant value "libc.so.7".
// * For Haiku, use constant value "libroot.so".
// * For rest of Unices, use constant value "libc.so".
if (strcmp(filename, "libc") == 0)
{
#if defined(__APPLE__)
filename = "/usr/lib/libc.dylib";
#elif defined(__FreeBSD__)
filename = "libc.so.7";
#elif defined(__HAIKU__)
filename = "libroot.so";
#elif defined(LIBC_SO)
filename = LIBC_SO;
#else
Expand Down
49 changes: 45 additions & 4 deletions src/native/libs/System.Native/pal_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#include <sys/vfs.h>
#elif HAVE_STATFS_MOUNT // BSD
#include <sys/mount.h>
#elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS // SunOS
#elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS && HAVE_STATVFS_BASETYPE // SunOS
#include <sys/types.h>
#include <sys/statvfs.h>
#if HAVE_STATFS_VFS
Expand All @@ -58,6 +58,10 @@
#include <sys/param.h>
#endif

#ifdef TARGET_HAIKU
#include <fs_info.h>
#endif // TARGET_HAIKU

#ifdef _AIX
#include <alloca.h>
// Somehow, AIX mangles the definition for this behind a C++ def
Expand Down Expand Up @@ -399,7 +403,7 @@ int32_t SystemNative_IsMemfdSupported(void)
}
#endif

// Note that the name has no affect on file descriptor behavior. From linux manpage:
// Note that the name has no affect on file descriptor behavior. From linux manpage:
// Names do not affect the behavior of the file descriptor, and as such multiple files can have the same name without any side effects.
int32_t fd = (int32_t)syscall(__NR_memfd_create, "test", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd < 0) return 0;
Expand Down Expand Up @@ -515,8 +519,13 @@ int32_t SystemNative_GetReadDirRBufferSize(void)
#endif
// dirent should be under 2k in size
assert(result < 2048);
#if HAVE_DIRENT_NAME_SIZE
// add some extra space so we can align the buffer to dirent.
return (int32_t)(result + dirent_alignment - 1);
#else
// add some extra space for the name.
return sizeof(struct dirent) + NAME_MAX + dirent_alignment - 1;
#endif // HAVE_DIRENT_NAME_SIZE
#else
return 0;
#endif
Expand Down Expand Up @@ -882,8 +891,14 @@ void SystemNative_GetDeviceIdentifiers(uint64_t dev, uint32_t* majorNumber, uint
{
#if !defined(TARGET_WASI)
dev_t castedDev = (dev_t)dev;
#if !defined(TARGET_HAIKU)
*majorNumber = (uint32_t)major(castedDev);
*minorNumber = (uint32_t)minor(castedDev);
#else
// Haiku has no concept of major/minor numbers, but it does have device IDs.
*majorNumber = 0;
*minorNumber = (uint32_t)dev;
#endif // TARGET_HAIKU
#else /* TARGET_WASI */
dev_t castedDev = (dev_t)dev;
*majorNumber = 0;
Expand All @@ -894,7 +909,12 @@ void SystemNative_GetDeviceIdentifiers(uint64_t dev, uint32_t* majorNumber, uint
int32_t SystemNative_MkNod(const char* pathName, uint32_t mode, uint32_t major, uint32_t minor)
{
#if !defined(TARGET_WASI)
#if !defined(TARGET_HAIKU)
dev_t dev = (dev_t)makedev(major, minor);
#else
(void)major;
dev_t dev = (dev_t)minor;
#endif // !TARGET_HAIKU

int32_t result;
while ((result = mknod(pathName, (mode_t)mode, dev)) < 0 && errno == EINTR);
Expand Down Expand Up @@ -1641,7 +1661,7 @@ static int16_t ConvertLockType(int16_t managedLockType)
}
}

#if !HAVE_NON_LEGACY_STATFS || defined(TARGET_APPLE) || defined(TARGET_FREEBSD)
#if !HAVE_NON_LEGACY_STATFS || defined(TARGET_APPLE) || defined(TARGET_FREEBSD) || defined(TARGET_HAIKU)
static uint32_t MapFileSystemNameToEnum(const char* fileSystemName)
{
uint32_t result = 0;
Expand Down Expand Up @@ -1800,9 +1820,30 @@ uint32_t SystemNative_GetFileSystemType(intptr_t fd)
uint32_t result = (uint32_t)statfsArgs.f_type;
return result;
#endif
#elif defined(TARGET_HAIKU)
struct stat st;
int fstatRes;
while ((fstatRes = fstat(ToFileDescriptor(fd), &st)) == -1 && errno == EINTR)
{ }
if (fstatRes == -1) return 0;

struct fs_info info;
int fsStatDevRes;
while ((fsStatDevRes = fs_stat_dev(st.st_dev, &info)) == -1 && errno == EINTR)
{ }
if (fsStatDevRes == -1) return 0;

if (strcmp(info.fsh_name, "bfs") == 0)
{
// Haiku names its own BFS filesystem "bfs", but on Linux and some other UNIXes
// it is called "befs" to avoid confusion with Boot File System.
strncpy(info.fsh_name, "befs", sizeof(info.fsh_name) - 1);
}

return MapFileSystemNameToEnum(info.fsh_name);
#elif defined(TARGET_WASI)
return EINTR;
#elif !HAVE_NON_LEGACY_STATFS
#elif !HAVE_NON_LEGACY_STATFS && HAVE_STATVFS_BASETYPE
int statfsRes;
struct statvfs statfsArgs;
while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;
Expand Down
2 changes: 1 addition & 1 deletion src/native/libs/System.Native/pal_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#elif HAVE_MALLOC_USABLE_SIZE_NP
#include <malloc_np.h>
#define MALLOC_SIZE(s) malloc_usable_size(s)
#elif defined(TARGET_SUNOS)
#elif defined(TARGET_SUNOS) || defined(TARGET_HAIKU)
#define MALLOC_SIZE(s) (*((size_t*)(s)-1))
#else
#error "Platform doesn't support malloc_usable_size or malloc_size"
Expand Down
60 changes: 57 additions & 3 deletions src/native/libs/System.Native/pal_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,24 @@
#if HAVE_MNTINFO
#include <sys/mount.h>
#else
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if HAVE_SYS_MNTENT_H
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <sys/statvfs.h>
#else
#elif HAVE_MNTENT_H
#include <mntent.h>
#endif
#include <sys/statvfs.h>
#define STRING_BUFFER_SIZE 8192

#ifdef __HAIKU__
#include <dirent.h>
#include <fs_info.h>
#include <fs_query.h>
#endif // __HAIKU__

// Android does not define MNTOPT_RO
#ifndef MNTOPT_RO
#define MNTOPT_RO "r"
Expand Down Expand Up @@ -68,7 +76,7 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context)
return result;
}

#else
#elif HAVE_MNTENT_H
int result = -1;
FILE* fp = setmntent("/proc/mounts", MNTOPT_RO);
if (fp != NULL)
Expand All @@ -91,6 +99,38 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context)
return result;
}

#elif defined(__HAIKU__)
int32 cookie = 0;
dev_t currentDev;

while ((long)(currentDev = next_dev(&cookie)) >= 0)
{
struct fs_info info;
if (fs_stat_dev(currentDev, &info) != B_OK)
{
continue;
}

char name[STRING_BUFFER_SIZE];
// Two bytes for the name as we're storing "."
char buf[sizeof(struct dirent) + 2];
struct dirent *entry = (struct dirent *)&buf;
strncpy(entry->d_name, ".", 2);
entry->d_pdev = currentDev;
entry->d_pino = info.root;

if (get_path_for_dirent(entry, name, sizeof(name)) != B_OK)
{
continue;
}

onFound(context, name);
}

return 0;
}
#else
#error "Don't know how to enumerate mount points on this platform"
#endif

int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInformation* mpi)
Expand Down Expand Up @@ -140,6 +180,9 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer
#if HAVE_NON_LEGACY_STATFS
struct statfs stats;
int result = statfs(name, &stats);
#elif defined(__HAIKU__)
struct fs_info stats;
int result = fs_stat_dev(dev_for_path(name), &stats);
#else
struct statvfs stats;
int result = statvfs(name, &stats);
Expand All @@ -166,6 +209,17 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer
assert(formatType != NULL);
*formatType = (int64_t)(stats.f_type);
SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), "");
#elif defined(__HAIKU__)
if (bufferLength < B_OS_NAME_LENGTH)
{
result = ERANGE;
*formatType = 0;
}
else
{
SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), stats.fsh_name);
*formatType = -1;
}
#else
*formatType = 0;
#endif
Expand Down
Loading
Loading