Skip to content

Commit d01d5cf

Browse files
committed
Haiku: Add native library IO support
Adds detection for non-portable filesystem and mount APIs and equivalent implementations using the Haiku API.
1 parent 8f8dad0 commit d01d5cf

File tree

4 files changed

+125
-7
lines changed

4 files changed

+125
-7
lines changed

src/native/libs/Common/pal_config.h.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#cmakedefine01 HAVE_MNTINFO
3333
#cmakedefine01 HAVE_STATFS_FSTYPENAME
3434
#cmakedefine01 HAVE_STATVFS_FSTYPENAME
35+
#cmakedefine01 HAVE_STATVFS_BASETYPE
3536
#cmakedefine01 HAVE_NON_LEGACY_STATFS
3637
#cmakedefine01 HAVE_STRCPY_S
3738
#cmakedefine01 HAVE_STRLCPY
@@ -88,6 +89,7 @@
8889
#cmakedefine01 HAVE_NETPACKET_PACKET_H
8990
#cmakedefine01 HAVE_NET_IF_ARP_H
9091
#cmakedefine01 HAVE_SYS_MNTENT_H
92+
#cmakedefine01 HAVE_MNTENT_H
9193
#cmakedefine01 HAVE_NET_IFMEDIA_H
9294
#cmakedefine01 HAVE_IOS_NET_IFMEDIA_H
9395
#cmakedefine01 HAVE_LINUX_RTNETLINK_H
@@ -128,6 +130,7 @@
128130
#cmakedefine01 HAVE_TERMIOS_H
129131
#cmakedefine01 HAVE_DLFCN_H
130132
#cmakedefine01 HAVE_PTHREAD_H
133+
#cmakedefine01 HAVE_SYS_STATFS_H
131134
#cmakedefine01 HAVE_SYS_STATVFS_H
132135
#cmakedefine01 HAVE_NET_IF_H
133136
#cmakedefine01 HAVE_SYS_PROCINFO_H
@@ -141,6 +144,8 @@
141144
#cmakedefine01 HAVE_MAKEDEV_SYSMACROSH
142145
#cmakedefine01 HAVE_GETGRGID_R
143146
#cmakedefine01 HAVE_TERMIOS2
147+
#cmakedefine01 HAVE_DIRENT_NAME_SIZE
148+
#cmakedefine01 DIRENT_NAME_SIZE
144149

145150
#ifndef HOST_WASI
146151
#cmakedefine01 HAVE_GETRUSAGE

src/native/libs/System.Native/pal_io.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#include <sys/vfs.h>
4747
#elif HAVE_STATFS_MOUNT // BSD
4848
#include <sys/mount.h>
49-
#elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS // SunOS
49+
#elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS && HAVE_STATVFS_BASETYPE // SunOS
5050
#include <sys/types.h>
5151
#include <sys/statvfs.h>
5252
#if HAVE_STATFS_VFS
@@ -58,6 +58,10 @@
5858
#include <sys/param.h>
5959
#endif
6060

61+
#ifdef TARGET_HAIKU
62+
#include <fs_info.h>
63+
#endif // TARGET_HAIKU
64+
6165
#ifdef _AIX
6266
#include <alloca.h>
6367
// Somehow, AIX mangles the definition for this behind a C++ def
@@ -399,7 +403,7 @@ int32_t SystemNative_IsMemfdSupported(void)
399403
}
400404
#endif
401405

402-
// Note that the name has no affect on file descriptor behavior. From linux manpage:
406+
// Note that the name has no affect on file descriptor behavior. From linux manpage:
403407
// Names do not affect the behavior of the file descriptor, and as such multiple files can have the same name without any side effects.
404408
int32_t fd = (int32_t)syscall(__NR_memfd_create, "test", MFD_CLOEXEC | MFD_ALLOW_SEALING);
405409
if (fd < 0) return 0;
@@ -515,8 +519,13 @@ int32_t SystemNative_GetReadDirRBufferSize(void)
515519
#endif
516520
// dirent should be under 2k in size
517521
assert(result < 2048);
522+
#if HAVE_DIRENT_NAME_SIZE
518523
// add some extra space so we can align the buffer to dirent.
519524
return (int32_t)(result + dirent_alignment - 1);
525+
#else
526+
// add some extra space for the name.
527+
return sizeof(struct dirent) + NAME_MAX + dirent_alignment - 1;
528+
#endif // HAVE_DIRENT_NAME_SIZE
520529
#else
521530
return 0;
522531
#endif
@@ -882,8 +891,14 @@ void SystemNative_GetDeviceIdentifiers(uint64_t dev, uint32_t* majorNumber, uint
882891
{
883892
#if !defined(TARGET_WASI)
884893
dev_t castedDev = (dev_t)dev;
894+
#if !defined(TARGET_HAIKU)
885895
*majorNumber = (uint32_t)major(castedDev);
886896
*minorNumber = (uint32_t)minor(castedDev);
897+
#else
898+
// Haiku has no concept of major/minor numbers, but it does have device IDs.
899+
*majorNumber = 0;
900+
*minorNumber = (uint32_t)dev;
901+
#endif // TARGET_HAIKU
887902
#else /* TARGET_WASI */
888903
dev_t castedDev = (dev_t)dev;
889904
*majorNumber = 0;
@@ -894,7 +909,12 @@ void SystemNative_GetDeviceIdentifiers(uint64_t dev, uint32_t* majorNumber, uint
894909
int32_t SystemNative_MkNod(const char* pathName, uint32_t mode, uint32_t major, uint32_t minor)
895910
{
896911
#if !defined(TARGET_WASI)
912+
#if !defined(TARGET_HAIKU)
897913
dev_t dev = (dev_t)makedev(major, minor);
914+
#else
915+
(void)major;
916+
dev_t dev = (dev_t)minor;
917+
#endif // !TARGET_HAIKU
898918

899919
int32_t result;
900920
while ((result = mknod(pathName, (mode_t)mode, dev)) < 0 && errno == EINTR);
@@ -1641,7 +1661,7 @@ static int16_t ConvertLockType(int16_t managedLockType)
16411661
}
16421662
}
16431663

1644-
#if !HAVE_NON_LEGACY_STATFS || defined(TARGET_APPLE) || defined(TARGET_FREEBSD)
1664+
#if !HAVE_NON_LEGACY_STATFS || defined(TARGET_APPLE) || defined(TARGET_FREEBSD) || defined(TARGET_HAIKU)
16451665
static uint32_t MapFileSystemNameToEnum(const char* fileSystemName)
16461666
{
16471667
uint32_t result = 0;
@@ -1800,9 +1820,30 @@ uint32_t SystemNative_GetFileSystemType(intptr_t fd)
18001820
uint32_t result = (uint32_t)statfsArgs.f_type;
18011821
return result;
18021822
#endif
1823+
#elif defined(TARGET_HAIKU)
1824+
struct stat st;
1825+
int fstatRes;
1826+
while ((fstatRes = fstat(ToFileDescriptor(fd), &st)) == -1 && errno == EINTR)
1827+
{ }
1828+
if (fstatRes == -1) return 0;
1829+
1830+
struct fs_info info;
1831+
int fsStatDevRes;
1832+
while ((fsStatDevRes = fs_stat_dev(st.st_dev, &info)) == -1 && errno == EINTR)
1833+
{ }
1834+
if (fsStatDevRes == -1) return 0;
1835+
1836+
if (strcmp(info.fsh_name, "bfs") == 0)
1837+
{
1838+
// Haiku names its own BFS filesystem "bfs", but on Linux and some other UNIXes
1839+
// it is called "befs" to avoid confusion with Boot File System.
1840+
strncpy(info.fsh_name, "befs", sizeof(info.fsh_name) - 1);
1841+
}
1842+
1843+
return MapFileSystemNameToEnum(info.fsh_name);
18031844
#elif defined(TARGET_WASI)
18041845
return EINTR;
1805-
#elif !HAVE_NON_LEGACY_STATFS
1846+
#elif !HAVE_NON_LEGACY_STATFS && HAVE_STATVFS_BASETYPE
18061847
int statfsRes;
18071848
struct statvfs statfsArgs;
18081849
while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ;

src/native/libs/System.Native/pal_mount.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@
1313
#if HAVE_MNTINFO
1414
#include <sys/mount.h>
1515
#else
16+
#if HAVE_SYS_STATFS_H
1617
#include <sys/statfs.h>
18+
#endif
1719
#if HAVE_SYS_MNTENT_H
1820
#include <sys/mntent.h>
1921
#include <sys/mnttab.h>
20-
#include <sys/statvfs.h>
21-
#else
22+
#elif HAVE_MNTENT_H
2223
#include <mntent.h>
2324
#endif
25+
#include <sys/statvfs.h>
2426
#define STRING_BUFFER_SIZE 8192
2527

28+
#ifdef __HAIKU__
29+
#include <dirent.h>
30+
#include <fs_info.h>
31+
#include <fs_query.h>
32+
#endif // __HAIKU__
33+
2634
// Android does not define MNTOPT_RO
2735
#ifndef MNTOPT_RO
2836
#define MNTOPT_RO "r"
@@ -68,7 +76,7 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context)
6876
return result;
6977
}
7078

71-
#else
79+
#elif HAVE_MNTENT_H
7280
int result = -1;
7381
FILE* fp = setmntent("/proc/mounts", MNTOPT_RO);
7482
if (fp != NULL)
@@ -91,6 +99,38 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context)
9199
return result;
92100
}
93101

102+
#elif defined(__HAIKU__)
103+
int32 cookie = 0;
104+
dev_t currentDev;
105+
106+
while ((long)(currentDev = next_dev(&cookie)) >= 0)
107+
{
108+
struct fs_info info;
109+
if (fs_stat_dev(currentDev, &info) != B_OK)
110+
{
111+
continue;
112+
}
113+
114+
char name[STRING_BUFFER_SIZE];
115+
// Two bytes for the name as we're storing "."
116+
char buf[sizeof(struct dirent) + 2];
117+
struct dirent *entry = (struct dirent *)&buf;
118+
strncpy(entry->d_name, ".", 2);
119+
entry->d_pdev = currentDev;
120+
entry->d_pino = info.root;
121+
122+
if (get_path_for_dirent(entry, name, sizeof(name)) != B_OK)
123+
{
124+
continue;
125+
}
126+
127+
onFound(context, name);
128+
}
129+
130+
return 0;
131+
}
132+
#else
133+
#error "Don't know how to enumerate mount points on this platform"
94134
#endif
95135

96136
int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInformation* mpi)
@@ -140,6 +180,9 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer
140180
#if HAVE_NON_LEGACY_STATFS
141181
struct statfs stats;
142182
int result = statfs(name, &stats);
183+
#elif defined(__HAIKU__)
184+
struct fs_info stats;
185+
int result = fs_stat_dev(dev_for_path(name), &stats);
143186
#else
144187
struct statvfs stats;
145188
int result = statvfs(name, &stats);
@@ -166,6 +209,17 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer
166209
assert(formatType != NULL);
167210
*formatType = (int64_t)(stats.f_type);
168211
SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), "");
212+
#elif defined(__HAIKU__)
213+
if (bufferLength < B_OS_NAME_LENGTH)
214+
{
215+
result = ERANGE;
216+
*formatType = 0;
217+
}
218+
else
219+
{
220+
SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), stats.fsh_name);
221+
*formatType = -1;
222+
}
169223
#else
170224
*formatType = 0;
171225
#endif

src/native/libs/configure.cmake

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,17 @@ check_struct_has_member(
324324
"sys/mount.h"
325325
HAVE_STATVFS_FSTYPENAME)
326326

327+
check_struct_has_member(
328+
"struct statvfs"
329+
f_basetype
330+
"sys/statvfs.h"
331+
HAVE_STATVFS_BASETYPE)
332+
327333
set(CMAKE_EXTRA_INCLUDE_FILES dirent.h)
334+
check_type_size(
335+
"((struct dirent*)0)->d_name"
336+
DIRENT_NAME_SIZE)
337+
set(CMAKE_EXTRA_INCLUDE_FILES)
328338

329339
# statfs: Find whether this struct exists
330340
if (HAVE_STATFS_FSTYPENAME OR HAVE_STATVFS_FSTYPENAME)
@@ -882,6 +892,10 @@ check_include_files(
882892
"dlfcn.h"
883893
HAVE_DLFCN_H)
884894

895+
check_include_files(
896+
"sys/statfs.h"
897+
HAVE_SYS_STATFS_H)
898+
885899
check_include_files(
886900
"sys/statvfs.h"
887901
HAVE_SYS_STATVFS_H)
@@ -955,6 +969,10 @@ check_include_files(
955969
"sys/mntent.h"
956970
HAVE_SYS_MNTENT_H)
957971

972+
check_include_files(
973+
"mntent.h"
974+
HAVE_MNTENT_H)
975+
958976
check_include_files(
959977
"stdint.h;net/if_media.h"
960978
HAVE_NET_IFMEDIA_H)

0 commit comments

Comments
 (0)