Compare commits

..

10 Commits

Author SHA1 Message Date
132b75c2d0 ports/bash: Fix compilation with moved winsize 2026-07-07 16:59:20 +03:00
bc8f0f373e ports: Add tar port 2026-07-07 16:59:20 +03:00
e352bfbb23 mkdir: Don't fail the target exists and -p was given 2026-07-07 16:59:20 +03:00
3ee6240806 Kernel: Prioritize EEXISTS sys_mkdir
This fixes `mkdir -p ...` failing to create existing parents which are
not writable
2026-07-07 16:59:20 +03:00
304f94f3b1 LibC: Implement __fpending
Some gnu programs want this and I don't want to make FILE non-opaque
2026-07-07 16:59:20 +03:00
89fa957297 BuildSystem: Fix keymap in base sysroot 2026-07-07 16:59:20 +03:00
7348511ed3 ports/llvm: Add support for pthread_setname_np and cpu count
Also package the llvm into the format mesa expects. This was kinda
tedious to always do manually
2026-07-07 10:30:07 +03:00
20392c6cc1 LibC: Add malloc.h with some GNU extension
This adds `reallocarray`, `malloc_usable_size`, `mallinfo`, `mallinfo2`
2026-07-07 10:30:07 +03:00
0843b8989d Kernel: Fix timer deadline issues in scheduler
Don't wake up threads when getting the next timer deadline.
If we are idling this can: remove thread from block list, get the
deadline for the next blocked thread, return to idle thread. This will
end up sleeping until the next wake up condition which in the worst
case would be rebalance, or indefinitely when not running SMP.

Make sure we always set the next timer deadline. I was not doing that if
the timer interrupt did not lead to a yield
2026-07-07 10:30:07 +03:00
1c8112f1a7 ports: Update xbanan 2026-07-07 05:07:36 +03:00
17 changed files with 268 additions and 40 deletions

Binary file not shown.

View File

@@ -1527,7 +1527,11 @@ namespace Kernel
uid_gid_t { m_credentials.euid(), m_credentials.egid() }; uid_gid_t { m_credentials.euid(), m_credentials.egid() };
}); });
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_WRONLY)); auto [parent, file_name] = TRY(find_parent_file(fd, path, O_SEARCH));
if (!parent.inode->find_inode(file_name).is_error())
return BAN::Error::from_errno(EEXIST);
if (!parent.inode->can_access(m_credentials, O_WRONLY))
return BAN::Error::from_errno(EACCES);
TRY(parent.inode->create_directory(file_name, (mode & 0777) | Inode::Mode::IFDIR, uid, gid)); TRY(parent.inode->create_directory(file_name, (mode & 0777) | Inode::Mode::IFDIR, uid, gid));
return 0; return 0;

View File

@@ -326,8 +326,6 @@ namespace Kernel
if (!interrupt_controller.is_using_apic()) if (!interrupt_controller.is_using_apic())
return; return;
wake_up_sleeping_threads();
uint64_t deadline_ns = m_next_reschedule_ns; uint64_t deadline_ns = m_next_reschedule_ns;
if (!m_block_queue.empty()) if (!m_block_queue.empty())
deadline_ns = BAN::Math::min(deadline_ns, m_block_queue.front()->wake_time_ns); deadline_ns = BAN::Math::min(deadline_ns, m_block_queue.front()->wake_time_ns);
@@ -368,8 +366,12 @@ namespace Kernel
wake_up_sleeping_threads(); wake_up_sleeping_threads();
// NOTE: yield will update the timer deadline, but if we do not yield make sure
// we set the next deadline or we won't get another timer interrupt
if (is_idle() || SystemTimer::get().ns_since_boot() >= m_next_reschedule_ns) if (is_idle() || SystemTimer::get().ns_since_boot() >= m_next_reschedule_ns)
Processor::yield(); Processor::yield();
else
update_wake_up_deadline();
} }
void Scheduler::unblock_thread(SchedulerQueue::Node* node) void Scheduler::unblock_thread(SchedulerQueue::Node* node)

View File

@@ -10,8 +10,8 @@ CONFIGURE_OPTIONS=(
'--without-bash-malloc' '--without-bash-malloc'
'--with-curses' '--with-curses'
'bash_cv_unusable_rtsigs=no' 'bash_cv_unusable_rtsigs=no'
'bash_cv_signal_vintage=posix' 'bash_cv_struct_winsize_termios=yes' # configure checks for sys/termios.h? code uses termios.h correctly
'CFLAGS=-std=c17' 'CFLAGS=-std=c17 -Wno-discarded-qualifiers'
'CFLAGS_FOR_BUILD=-std=c17' 'CFLAGS_FOR_BUILD=-std=c17'
) )

View File

@@ -1,12 +0,0 @@
diff -ruN bash-5.2.37/examples/loadables/Makefile.in bash-5.2.37-banan_os/examples/loadables/Makefile.in
--- bash-5.2.37/examples/loadables/Makefile.in 2022-08-19 23:33:30.000000000 +0300
+++ bash-5.2.37-banan_os/examples/loadables/Makefile.in 2025-01-26 02:43:36.121801845 +0200
@@ -104,7 +104,7 @@
ALLPROG = print truefalse sleep finfo logname basename dirname fdflags \
tty pathchk tee head mkdir rmdir mkfifo mktemp printenv id whoami \
uname sync push ln unlink realpath strftime mypid setpgid seq rm \
- accept csv dsv cut stat getconf
+ accept csv dsv stat
OTHERPROG = necho hello cat pushd asort
all: $(SHOBJ_STATUS)

View File

@@ -29,6 +29,17 @@ build() {
install() { install() {
# This port only contains llvm libraries used optionally by # This port only contains llvm libraries used optionally by
# mesa port. There is no need to install and fill the disk :D # mesa port. There is no need to install to sysroot :D
:
local pkg_dir="../llvm-banan_os-$VERSION-$BANAN_ARCH"
rm -rf "$pkg_dir"
mkdir -p "$pkg_dir/include" || exit 1
cp -r 'llvm/include/llvm' "$pkg_dir/include/" || exit 1
cp -r 'llvm/include/llvm-c' "$pkg_dir/include/" || exit 1
cp -r 'build/include/llvm' "$pkg_dir/include/" || exit 1
mkdir -p "$pkg_dir/lib" || exit 1
cp 'build/lib/'*.a "$pkg_dir/lib/" || exit 1
} }

View File

@@ -1,6 +1,6 @@
diff -ruN llvm-22.1.8/llvm/include/llvm/ADT/bit.h llvm-22.1.8-banan_os/llvm/include/llvm/ADT/bit.h diff -ruN llvm-22.1.8/llvm/include/llvm/ADT/bit.h llvm-22.1.8-banan_os/llvm/include/llvm/ADT/bit.h
--- llvm-22.1.8/llvm/include/llvm/ADT/bit.h 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/include/llvm/ADT/bit.h 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/include/llvm/ADT/bit.h 2026-06-26 20:05:01.569826765 +0300 +++ llvm-22.1.8-banan_os/llvm/include/llvm/ADT/bit.h 2026-07-07 10:03:36.848199127 +0300
@@ -30,7 +30,8 @@ @@ -30,7 +30,8 @@
#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
@@ -13,7 +13,7 @@ diff -ruN llvm-22.1.8/llvm/include/llvm/ADT/bit.h llvm-22.1.8-banan_os/llvm/incl
#include <sys/machine.h> #include <sys/machine.h>
diff -ruN llvm-22.1.8/llvm/include/llvm/Support/ExitCodes.h llvm-22.1.8-banan_os/llvm/include/llvm/Support/ExitCodes.h diff -ruN llvm-22.1.8/llvm/include/llvm/Support/ExitCodes.h llvm-22.1.8-banan_os/llvm/include/llvm/Support/ExitCodes.h
--- llvm-22.1.8/llvm/include/llvm/Support/ExitCodes.h 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/include/llvm/Support/ExitCodes.h 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/include/llvm/Support/ExitCodes.h 2026-06-26 20:05:11.472186824 +0300 +++ llvm-22.1.8-banan_os/llvm/include/llvm/Support/ExitCodes.h 2026-07-07 10:03:36.965344890 +0300
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
#if HAVE_SYSEXITS_H #if HAVE_SYSEXITS_H
@@ -25,7 +25,7 @@ diff -ruN llvm-22.1.8/llvm/include/llvm/Support/ExitCodes.h llvm-22.1.8-banan_os
// Define the macro with its usual value from BSD systems, which is chosen to // Define the macro with its usual value from BSD systems, which is chosen to
diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Path.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Path.inc diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Path.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Path.inc
--- llvm-22.1.8/llvm/lib/Support/Unix/Path.inc 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/lib/Support/Unix/Path.inc 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Path.inc 2026-06-26 20:22:57.780776278 +0300 +++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Path.inc 2026-07-07 10:03:36.987545022 +0300
@@ -111,7 +111,7 @@ @@ -111,7 +111,7 @@
#endif #endif
@@ -68,7 +68,7 @@ diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Path.inc llvm-22.1.8-banan_os/llvm/l
// target // target
diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Process.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Process.inc diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Process.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Process.inc
--- llvm-22.1.8/llvm/lib/Support/Unix/Process.inc 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/lib/Support/Unix/Process.inc 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Process.inc 2026-06-26 20:19:55.915545542 +0300 +++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Process.inc 2026-07-07 10:03:37.017664239 +0300
@@ -37,6 +37,9 @@ @@ -37,6 +37,9 @@
#ifdef HAVE_SYS_IOCTL_H #ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -81,7 +81,7 @@ diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Process.inc llvm-22.1.8-banan_os/llv
//=== WARNING: Implementation here must contain only generic UNIX code that //=== WARNING: Implementation here must contain only generic UNIX code that
diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Program.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Program.inc diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Program.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Program.inc
--- llvm-22.1.8/llvm/lib/Support/Unix/Program.inc 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/lib/Support/Unix/Program.inc 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Program.inc 2026-06-26 20:05:22.461478923 +0300 +++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Program.inc 2026-07-07 10:03:37.031901635 +0300
@@ -334,7 +334,7 @@ @@ -334,7 +334,7 @@
namespace llvm { namespace llvm {
namespace sys { namespace sys {
@@ -106,8 +106,19 @@ diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Program.inc llvm-22.1.8-banan_os/llv
ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Threading.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Threading.inc diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Threading.inc llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Threading.inc
--- llvm-22.1.8/llvm/lib/Support/Unix/Threading.inc 2026-06-16 01:33:53.000000000 +0300 --- llvm-22.1.8/llvm/lib/Support/Unix/Threading.inc 2026-06-16 01:33:53.000000000 +0300
+++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Threading.inc 2026-06-26 20:10:24.025022264 +0300 +++ llvm-22.1.8-banan_os/llvm/lib/Support/Unix/Threading.inc 2026-07-07 10:03:37.256828558 +0300
@@ -121,7 +121,7 @@ @@ -70,6 +70,10 @@
#include <OS.h> // For B_OS_NAME_LENGTH
#endif
+#if defined(__banan_os__)
+#include <unistd.h> // For sysconf()
+#endif
+
namespace llvm {
pthread_t
llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg,
@@ -121,7 +125,7 @@
pthread_t llvm_thread_get_id_impl(pthread_t Thread) { return Thread; } pthread_t llvm_thread_get_id_impl(pthread_t Thread) { return Thread; }
@@ -116,3 +127,30 @@ diff -ruN llvm-22.1.8/llvm/lib/Support/Unix/Threading.inc llvm-22.1.8-banan_os/l
} // namespace llvm } // namespace llvm
@@ -148,6 +152,8 @@
return uint64_t(syscall(__NR_gettid));
#elif defined(_AIX)
return uint64_t(thread_self());
+#elif defined(__banan_os__)
+ return uint64_t(pthread_self()->id);
#else
return uint64_t(pthread_self());
#endif
@@ -171,6 +177,8 @@
return 24;
#elif defined(__CYGWIN__)
return 16;
+#elif defined(__banan_os__)
+ return sizeof(uthread::name);
#else
return 0;
#endif
@@ -393,7 +401,7 @@
}
return CPU_COUNT(&Enabled);
}
-#elif (defined(__linux__) && defined(__s390x__)) || defined(_AIX)
+#elif (defined(__linux__) && defined(__s390x__)) || defined(_AIX) || defined(__banan_os__)
static int computeHostNumPhysicalCores() {
return sysconf(_SC_NPROCESSORS_ONLN);
}

10
ports/tar/build.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash ../install.sh
NAME='tar'
VERSION='1.35'
DOWNLOAD_URL="https://ftpmirror.gnu.org/gnu/tar/tar-$VERSION.tar.xz#4d62ff37342ec7aed748535323930c7cf94acf71c3591882b26a7ea50f3edc16"
CONFIG_SUB=('build-aux/config.sub')
pre_configure() {
echo '#include_next <sys/types.h>' > gnu/sys_types.in.h
}

View File

@@ -0,0 +1,21 @@
diff -ruN tar-1.35/gnu/getprogname.c tar-1.35-banan_os/gnu/getprogname.c
--- tar-1.35/gnu/getprogname.c 2023-06-17 09:47:53.000000000 +0300
+++ tar-1.35-banan_os/gnu/getprogname.c 2026-07-07 15:22:32.468592615 +0300
@@ -50,7 +50,7 @@
# include <sys/procfs.h>
#endif
-#if defined __SCO_VERSION__ || defined __sysv5__
+#if defined __SCO_VERSION__ || defined __sysv5__ || defined __banan_os__
# include <fcntl.h>
# include <string.h>
#endif
@@ -265,7 +265,7 @@
}
}
return NULL;
-# elif defined __SCO_VERSION__ || defined __sysv5__ /* SCO OpenServer6/UnixWare */
+# elif defined __SCO_VERSION__ || defined __sysv5__ || defined __banan_os__ /* SCO OpenServer6/UnixWare */
char buf[80];
int fd;
sprintf (buf, "/proc/%d/cmdline", getpid());

View File

@@ -2,7 +2,7 @@
NAME='xbanan' NAME='xbanan'
VERSION='git' VERSION='git'
DOWNLOAD_URL="https://git.bananymous.com/Bananymous/xbanan.git#a02355eb20007e81cca9cad9267b170fba8b7a1f" DOWNLOAD_URL="https://git.bananymous.com/Bananymous/xbanan.git#b03a10d6012fc5504d98b9a5a6cab75779193e79"
DEPENDENCIES=('xorgproto') DEPENDENCIES=('xorgproto')
configure() { configure() {

View File

@@ -0,0 +1,54 @@
#ifndef _MALLOC_H
#define _MALLOC_H 1
#include <sys/cdefs.h>
__BEGIN_DECLS
#define __need_size_t
#include <stddef.h>
struct mallinfo
{
int arena;
int ordblks;
int smblks;
int hblks;
int hblkhd;
int usmblks;
int fsmblks;
int uordblks;
int fordblks;
int keepcost;
};
struct mallinfo2
{
size_t arena;
size_t ordblks;
size_t smblks;
size_t hblks;
size_t hblkhd;
size_t usmblks;
size_t fsmblks;
size_t uordblks;
size_t fordblks;
size_t keepcost;
};
void* malloc(size_t total_size);
void free(void* ptr);
void* realloc(void* ptr, size_t size);
void* calloc(size_t nmemb, size_t size);
void* reallocarray(void* ptr, size_t nmemb, size_t size);
void* aligned_alloc(size_t alignment, size_t size);
int posix_memalign(void** memptr, size_t alignment, size_t size);
size_t malloc_usable_size(void* ptr);
struct mallinfo mallinfo(void);
struct mallinfo2 mallinfo2(void);
__END_DECLS
#endif

View File

@@ -127,6 +127,7 @@ int vsnprintf(char* __restrict s, size_t n, const char* __restrict format, va_l
int vsprintf(char* __restrict s, const char* __restrict format, va_list ap); int vsprintf(char* __restrict s, const char* __restrict format, va_list ap);
int vsscanf(const char* __restrict s, const char* __restrict format, va_list arg); int vsscanf(const char* __restrict s, const char* __restrict format, va_list arg);
size_t __fpending(FILE* stream);
void __fseterr(FILE* stream); void __fseterr(FILE* stream);
__END_DECLS __END_DECLS

View File

@@ -89,6 +89,7 @@ int rand(void);
int rand_r(unsigned* seed); int rand_r(unsigned* seed);
long random(void); long random(void);
void* realloc(void* ptr, size_t size); void* realloc(void* ptr, size_t size);
void* reallocarray(void* ptr, size_t nmemb, size_t size);
char* realpath(const char* __restrict file_name, char* __restrict resolved_name); char* realpath(const char* __restrict file_name, char* __restrict resolved_name);
unsigned short* seed48(unsigned short seed16v[3]); unsigned short* seed48(unsigned short seed16v[3]);
int setenv(const char* envname, const char* envval, int overwrite); int setenv(const char* envname, const char* envval, int overwrite);

View File

@@ -1,7 +1,9 @@
#include <BAN/Atomic.h>
#include <BAN/Math.h> #include <BAN/Math.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <malloc.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -220,6 +222,9 @@ static size_t s_allocator_capacity { 0 };
static BitmapAllocator* s_allocators { nullptr }; static BitmapAllocator* s_allocators { nullptr };
static pthread_mutex_t s_allocator_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_allocator_lock = PTHREAD_MUTEX_INITIALIZER;
static BAN::Atomic<size_t> s_mmap_count { 0 };
static BAN::Atomic<size_t> s_mmap_bytes { 0 };
void* malloc(size_t total_size) void* malloc(size_t total_size)
{ {
if (total_size >= s_mmap_threshold) if (total_size >= s_mmap_threshold)
@@ -230,6 +235,9 @@ void* malloc(size_t total_size)
if (address == MAP_FAILED) if (address == MAP_FAILED)
return nullptr; return nullptr;
s_mmap_count++;
s_mmap_bytes += mmap_size;
auto& header = static_cast<MmapAllocationHeader*>(address)[0]; auto& header = static_cast<MmapAllocationHeader*>(address)[0];
header = { header = {
.mmap_size = mmap_size, .mmap_size = mmap_size,
@@ -294,6 +302,8 @@ void free(void* ptr)
pthread_mutex_unlock(&s_allocator_lock); pthread_mutex_unlock(&s_allocator_lock);
const auto& header = static_cast<MmapAllocationHeader*>(ptr)[-1]; const auto& header = static_cast<MmapAllocationHeader*>(ptr)[-1];
s_mmap_count--;
s_mmap_bytes += header.mmap_size;
munmap(static_cast<uint8_t*>(ptr) - header.offset, header.mmap_size); munmap(static_cast<uint8_t*>(ptr) - header.offset, header.mmap_size);
} }
@@ -311,7 +321,7 @@ static size_t allocation_size(void* ptr)
pthread_mutex_unlock(&s_allocator_lock); pthread_mutex_unlock(&s_allocator_lock);
const auto& header = static_cast<MmapAllocationHeader*>(ptr)[-1]; const auto& header = static_cast<MmapAllocationHeader*>(ptr)[-1];
return header.mmap_size - sizeof(MmapAllocationHeader); return header.mmap_size - header.offset;
} }
void* realloc(void* ptr, size_t size) void* realloc(void* ptr, size_t size)
@@ -346,13 +356,14 @@ void* realloc(void* ptr, size_t size)
void* calloc(size_t nmemb, size_t size) void* calloc(size_t nmemb, size_t size)
{ {
const size_t total = nmemb * size; if (BAN::Math::will_multiplication_overflow(nmemb, size))
if (size != 0 && total / size != nmemb)
{ {
errno = ENOMEM; errno = ENOMEM;
return nullptr; return nullptr;
} }
const size_t total = nmemb * size;
void* ptr = malloc(total); void* ptr = malloc(total);
if (ptr == nullptr) if (ptr == nullptr)
return nullptr; return nullptr;
@@ -361,6 +372,17 @@ void* calloc(size_t nmemb, size_t size)
return ptr; return ptr;
} }
void* reallocarray(void* ptr, size_t nmemb, size_t size)
{
if (BAN::Math::will_multiplication_overflow(nmemb, size))
{
errno = ENOMEM;
return nullptr;
}
return realloc(ptr, nmemb * size);
}
void* aligned_alloc(size_t alignment, size_t size) void* aligned_alloc(size_t alignment, size_t size)
{ {
if (!BAN::Math::is_power_of_two(alignment)) if (!BAN::Math::is_power_of_two(alignment))
@@ -380,6 +402,9 @@ void* aligned_alloc(size_t alignment, size_t size)
if (address == MAP_FAILED) if (address == MAP_FAILED)
return nullptr; return nullptr;
s_mmap_count++;
s_mmap_bytes += mmap_size;
uintptr_t data = reinterpret_cast<uintptr_t>(address) + sizeof(MmapAllocationHeader); uintptr_t data = reinterpret_cast<uintptr_t>(address) + sizeof(MmapAllocationHeader);
if (auto rem = data % alignment) if (auto rem = data % alignment)
data += alignment - rem; data += alignment - rem;
@@ -404,3 +429,55 @@ int posix_memalign(void** memptr, size_t alignment, size_t size)
return (*memptr = aligned_alloc(alignment, size)) ? 0 : -1; return (*memptr = aligned_alloc(alignment, size)) ? 0 : -1;
} }
size_t malloc_usable_size(void* ptr)
{
if (ptr == nullptr)
return 0;
return allocation_size(ptr);
}
struct mallinfo mallinfo(void)
{
constexpr auto saturate = [](size_t value) -> int {
if (value > static_cast<size_t>(BAN::numeric_limits<int>::max()))
return BAN::numeric_limits<int>::max();
return value;
};
const auto info = mallinfo2();
return {
.arena = saturate(info.arena),
.ordblks = saturate(info.ordblks),
.smblks = saturate(info.smblks),
.hblks = saturate(info.hblks),
.hblkhd = saturate(info.hblkhd),
.usmblks = saturate(info.usmblks),
.fsmblks = saturate(info.fsmblks),
.uordblks = saturate(info.uordblks),
.fordblks = saturate(info.fordblks),
.keepcost = saturate(info.keepcost),
};
}
struct mallinfo2 mallinfo2(void)
{
struct mallinfo2 info {};
pthread_mutex_lock(&s_allocator_lock);
info.arena = s_allocator_count * s_allocator_size;
for (size_t i = 0; i < s_allocator_count; i++)
{
const size_t total_mem = s_allocators[i].total_chunks * s_allocator_chunk_size;
const size_t free_mem = s_allocators[i].free_chunks * s_allocator_chunk_size;
info.fordblks += free_mem;
info.uordblks += total_mem - free_mem;
}
pthread_mutex_unlock(&s_allocator_lock);
info.hblks = s_mmap_count.load();
info.hblkhd = s_mmap_bytes.load();
info.uordblks += info.hblkhd;
return info;
}

View File

@@ -134,6 +134,12 @@ void clearerr(FILE* file)
file->error = false; file->error = false;
} }
size_t __fpending(FILE* file)
{
ScopeLock _(file);
return file->buffer_rd_size ? 0 : file->buffer_idx;
}
void __fseterr(FILE* file) void __fseterr(FILE* file)
{ {
ScopeLock _(file); ScopeLock _(file);

View File

@@ -8,7 +8,7 @@
static const char* s_argv0 { nullptr }; static const char* s_argv0 { nullptr };
bool create_parents(const char* path, bool verbose) static bool create_parents(const char* path, bool verbose)
{ {
char buffer[PATH_MAX]; char buffer[PATH_MAX];
for (size_t i = 0; path[i];) for (size_t i = 0; path[i];)
@@ -21,32 +21,47 @@ bool create_parents(const char* path, bool verbose)
break; break;
buffer[i] = '\0'; buffer[i] = '\0';
if (mkdir(buffer, 0) == -1) struct stat st;
if (stat(path, &st) == 0)
{ {
if (errno == EEXIST) if (S_ISDIR(st.st_mode))
continue; continue;
fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(EEXIST));
return false;
}
if (errno != ENOENT || mkdir(path, 0) == -1)
{
fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(errno)); fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(errno));
return false; return false;
} }
const mode_t filemask = umask(0);
umask(filemask);
chmod(buffer, (S_IWUSR | S_IXUSR | ~filemask) & 0777);
if (verbose) if (verbose)
printf("%s: created directory '%s'\n", s_argv0, path); printf("%s: created directory '%s'\n", s_argv0, path);
const mode_t filemask = umask(0);
umask(filemask);
chmod(buffer, (S_IWUSR | S_IXUSR | ~filemask) & 0777);
} }
return true; return true;
} }
bool create_directory(const char* path, mode_t mode, bool verbose, bool parents) static bool create_directory(const char* path, mode_t mode, bool verbose, bool parents)
{ {
if (parents && !create_parents(path, verbose)) if (parents && !create_parents(path, verbose))
return false; return false;
if (mkdir(path, mode) == -1) struct stat st;
if (stat(path, &st) == 0)
{
if (parents && S_ISDIR(st.st_mode))
return true;
fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(EEXIST));
return false;
}
if (errno != ENOENT || mkdir(path, mode) == -1)
{ {
fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(errno)); fprintf(stderr, "%s: cannot create '%s': %s\n", s_argv0, path, strerror(errno));
return false; return false;