Compare commits
12 Commits
8c569ac7bf
...
b30a79c7fe
Author | SHA1 | Date |
---|---|---|
|
b30a79c7fe | |
|
22374ac8f7 | |
|
17014bb8de | |
|
d1c3d3d5aa | |
|
7fedd94cc5 | |
|
48eca3d031 | |
|
21d3cf91a0 | |
|
5938cc4086 | |
|
7c57d736c6 | |
|
cbe3f2a4ac | |
|
7a10e0e347 | |
|
efb577769e |
|
@ -11,5 +11,8 @@ banan_link_library(ban libc)
|
|||
|
||||
set_target_properties(ban PROPERTIES OUTPUT_NAME libban)
|
||||
|
||||
# set SONAME as cmake doesn't set it for some reason??
|
||||
set_target_properties(ban PROPERTIES LINK_FLAGS "-Wl,-soname,libban.so")
|
||||
|
||||
banan_install_headers(ban)
|
||||
install(TARGETS ban OPTIONAL)
|
||||
|
|
|
@ -27,9 +27,6 @@ set(BUILD_SHARED_LIBS True)
|
|||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
|
||||
# include headers of ${library} to ${target}
|
||||
function(banan_include_headers target library)
|
||||
target_include_directories(${target} PRIVATE $<TARGET_PROPERTY:${library},SOURCE_DIR>/include)
|
||||
|
|
|
@ -245,7 +245,7 @@ endif()
|
|||
|
||||
add_custom_command(
|
||||
OUTPUT font/prefs.psf.o
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && objcopy -O ${ELF_FORMAT} -B i386 -I binary font/prefs.psf ${CMAKE_CURRENT_BINARY_DIR}/font/prefs.psf.o
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/font && objcopy -O ${ELF_FORMAT} -B i386 -I binary font/prefs.psf ${CMAKE_CURRENT_BINARY_DIR}/font/prefs.psf.o
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_COMPILER} <CMAKE_CXX_LINK_FLAGS> <FLAGS> <LINK_FLAGS> -o <TARGET> ${CMAKE_CURRENT_BINARY_DIR}/crti.o ${CMAKE_CURRENT_BINARY_DIR}/crtbegin.o <OBJECTS> ${CMAKE_CURRENT_BINARY_DIR}/crtend.o ${CMAKE_CURRENT_BINARY_DIR}/crtn.o -lgcc ")
|
||||
|
|
|
@ -562,39 +562,86 @@ namespace Kernel
|
|||
new_entry_size += directory_entry_alignment - rem;
|
||||
ASSERT(new_entry_size < (size_t)blksize());
|
||||
|
||||
size_t new_entry_offset = size() % blksize();
|
||||
|
||||
// Target is the last block, or if it doesn't fit the new entry, the next one.
|
||||
size_t target_data_block = size() / blksize();
|
||||
if (blksize() - new_entry_offset < new_entry_size)
|
||||
for (size_t data_block_index = 0; data_block_index * blksize() < (size_t)size(); data_block_index++)
|
||||
{
|
||||
// insert an empty entry at the end of current block
|
||||
m_fs.with_block_buffer(block_index(target_data_block).value(), [&](BAN::ByteSpan bytespan) {
|
||||
auto& empty_entry = bytespan.slice(new_entry_offset).as<TmpDirectoryEntry>();
|
||||
empty_entry.type = DT_UNKNOWN;
|
||||
empty_entry.ino = 0;
|
||||
empty_entry.rec_len = blksize() - new_entry_offset;
|
||||
});
|
||||
m_inode_info.size += blksize() - new_entry_offset;
|
||||
const size_t block_index = this->block_index(data_block_index).value();
|
||||
|
||||
target_data_block++;
|
||||
new_entry_offset = 0;
|
||||
bool done = false;
|
||||
m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
|
||||
bytespan = bytespan.slice(0, blksize());
|
||||
while (bytespan.size() > 0)
|
||||
{
|
||||
auto& entry = bytespan.as<TmpDirectoryEntry>();
|
||||
|
||||
while (entry.ino == 0 && entry.rec_len < bytespan.size())
|
||||
{
|
||||
auto& next_entry = bytespan.slice(entry.rec_len).as<TmpDirectoryEntry>();
|
||||
if (next_entry.ino)
|
||||
break;
|
||||
entry.rec_len += next_entry.rec_len;
|
||||
}
|
||||
|
||||
if (entry.ino != 0 || entry.rec_len < new_entry_size)
|
||||
{
|
||||
bytespan = bytespan.slice(entry.rec_len);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.rec_len <= new_entry_size + sizeof(TmpDirectoryEntry))
|
||||
new_entry_size = entry.rec_len;
|
||||
else
|
||||
{
|
||||
auto& new_entry = bytespan.slice(new_entry_size).as<TmpDirectoryEntry>();
|
||||
new_entry.type = DT_UNKNOWN;
|
||||
new_entry.ino = 0;
|
||||
new_entry.rec_len = entry.rec_len - new_entry_size;
|
||||
}
|
||||
|
||||
ASSERT(entry.type == DT_UNKNOWN);
|
||||
entry.type = inode_mode_to_dt_type(inode.mode());
|
||||
entry.ino = inode.ino();
|
||||
entry.name_len = name.size();
|
||||
entry.rec_len = new_entry_size;
|
||||
memcpy(entry.name, name.data(), name.size());
|
||||
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (done)
|
||||
{
|
||||
// add link to linked inode
|
||||
inode.m_inode_info.nlink++;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
size_t block_index = TRY(block_index_with_allocation(target_data_block));
|
||||
const size_t data_block_index = size() / blksize();
|
||||
const size_t block_index = TRY(block_index_with_allocation(data_block_index));
|
||||
|
||||
m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
|
||||
auto& new_entry = bytespan.slice(new_entry_offset).as<TmpDirectoryEntry>();
|
||||
ASSERT(new_entry.type == DT_UNKNOWN);
|
||||
new_entry.type = inode_mode_to_dt_type(inode.mode());
|
||||
new_entry.ino = inode.ino();
|
||||
new_entry.name_len = name.size();
|
||||
new_entry.rec_len = new_entry_size;
|
||||
memcpy(new_entry.name, name.data(), name.size());
|
||||
// insert new inode
|
||||
{
|
||||
auto& entry = bytespan.as<TmpDirectoryEntry>();
|
||||
entry.type = inode_mode_to_dt_type(inode.mode());
|
||||
entry.ino = inode.ino();
|
||||
entry.name_len = name.size();
|
||||
entry.rec_len = new_entry_size;
|
||||
memcpy(entry.name, name.data(), name.size());
|
||||
}
|
||||
|
||||
// insert null entry
|
||||
{
|
||||
auto& entry = bytespan.slice(new_entry_size).as<TmpDirectoryEntry>();
|
||||
entry.type = DT_UNKNOWN;
|
||||
entry.ino = 0;
|
||||
entry.rec_len = blksize() - new_entry_size;
|
||||
}
|
||||
});
|
||||
|
||||
// increase current size
|
||||
m_inode_info.size += new_entry_size;
|
||||
m_inode_info.size += blksize();
|
||||
|
||||
// add link to linked inode
|
||||
inode.m_inode_info.nlink++;
|
||||
|
@ -616,7 +663,7 @@ namespace Kernel
|
|||
while (bytespan.size() > 0)
|
||||
{
|
||||
auto& entry = bytespan.as<TmpDirectoryEntry>();
|
||||
if (entry.type != DT_UNKNOWN)
|
||||
if (entry.ino != 0)
|
||||
{
|
||||
switch (callback(entry))
|
||||
{
|
||||
|
|
|
@ -330,8 +330,11 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EACCES);
|
||||
for (;;)
|
||||
{
|
||||
auto ret = open_file.inode()->list_next_inodes(open_file.offset()++, list, list_len);
|
||||
if (ret.is_error() && ret.error().get_error_code() == ENODATA)
|
||||
auto ret = open_file.inode()->list_next_inodes(open_file.offset(), list, list_len);
|
||||
if (ret.is_error() && ret.error().get_error_code() != ENODATA)
|
||||
return ret;
|
||||
open_file.offset()++;
|
||||
if (ret.is_error())
|
||||
continue;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1379,8 +1379,10 @@ namespace Kernel
|
|||
if (arguments->sigmask)
|
||||
TRY(validate_pointer_access(arguments->sigmask, sizeof(sigset_t), false));
|
||||
|
||||
const auto old_sigmask = Thread::current().m_signal_block_mask;
|
||||
if (arguments->sigmask)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
Thread::current().m_signal_block_mask = *arguments->sigmask;
|
||||
BAN::ScopeGuard sigmask_restore([old_sigmask] { Thread::current().m_signal_block_mask = old_sigmask; });
|
||||
|
||||
uint64_t timedout_ns = SystemTimer::get().ns_since_boot();
|
||||
if (arguments->timeout)
|
||||
|
@ -1737,16 +1739,29 @@ namespace Kernel
|
|||
if (len == 0)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
vaddr_t vaddr = (vaddr_t)addr;
|
||||
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
|
||||
if (vaddr % PAGE_SIZE != 0)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
if (auto rem = len % PAGE_SIZE)
|
||||
len += PAGE_SIZE - rem;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
// FIXME: We should only map partial regions
|
||||
// FIXME: We should unmap partial regions.
|
||||
// This is a hack to only unmap if the whole mmap region
|
||||
// is contained within [addr, addr + len]
|
||||
for (size_t i = 0; i < m_mapped_regions.size(); i++)
|
||||
if (m_mapped_regions[i]->overlaps(vaddr, len))
|
||||
m_mapped_regions.remove(i);
|
||||
{
|
||||
auto& region = m_mapped_regions[i];
|
||||
|
||||
const vaddr_t region_s = region->vaddr();
|
||||
const vaddr_t region_e = region->vaddr() + region->size();
|
||||
if (vaddr <= region_s && region_e <= vaddr + len)
|
||||
m_mapped_regions.remove(i--);
|
||||
else if (region->overlaps(vaddr, len))
|
||||
dwarnln("TODO: partial region munmap");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -269,8 +269,8 @@ namespace Kernel
|
|||
for (uint32_t row = m_height; row > m_row; row--)
|
||||
{
|
||||
const uint32_t dst_y = row - 1;
|
||||
const uint32_t src_y = dst_y - m_ansi_state.nums[0];
|
||||
memcpy(&m_buffer[dst_y * m_width], &m_buffer[src_y * m_width], m_width * sizeof(Cell));
|
||||
if (const uint32_t src_y = dst_y - m_ansi_state.nums[0]; src_y < dst_y)
|
||||
memcpy(&m_buffer[dst_y * m_width], &m_buffer[src_y * m_width], m_width * sizeof(Cell));
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, dst_y);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='make'
|
||||
VERSION='4.4.1'
|
||||
DOWNLOAD_URL="https://ftp.gnu.org/gnu/make/make-$VERSION.tar.gz#dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3"
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--with-sysroot=/'
|
||||
'--disable-nls'
|
||||
'--disable-posix-spawn'
|
||||
'--enable-year2038'
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
diff -ruN make-4.4.1/build-aux/config.sub make-4.4.1-banan_os/build-aux/config.sub
|
||||
--- make-4.4.1/build-aux/config.sub 2023-02-18 17:38:13.000000000 +0200
|
||||
+++ make-4.4.1-banan_os/build-aux/config.sub 2024-12-04 23:15:11.865989888 +0200
|
||||
@@ -1758,7 +1758,7 @@
|
||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
||||
- | fiwix* | mlibc* )
|
||||
+ | fiwix* | mlibc* | banan_os* )
|
||||
;;
|
||||
# This one is extra strict with allowed versions
|
||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
|
@ -0,0 +1,12 @@
|
|||
diff -ruN make-4.4.1/src/arscan.c make-4.4.1-banan_os/src/arscan.c
|
||||
--- make-4.4.1/src/arscan.c 2023-01-08 17:45:38.000000000 +0200
|
||||
+++ make-4.4.1-banan_os/src/arscan.c 2024-12-04 23:49:39.898722479 +0200
|
||||
@@ -331,7 +331,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef WINDOWS32
|
||||
-# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(MK_OS_ZOS)
|
||||
+# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(MK_OS_ZOS) && !defined(__banan_os__)
|
||||
# include <ar.h>
|
||||
# else
|
||||
/* These platforms don't have <ar.h> but have archives in the same format
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='nasm'
|
||||
VERSION='2.16.03'
|
||||
DOWNLOAD_URL="https://www.nasm.us/pub/nasm/releasebuilds/$VERSION/nasm-$VERSION.tar.gz#5bc940dd8a4245686976a8f7e96ba9340a0915f2d5b88356874890e207bdb581"
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-gdb'
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
diff -ruN nasm-2.16.03/autoconf/helpers/config.sub nasm-2.16.03-banan_os/autoconf/helpers/config.sub
|
||||
--- nasm-2.16.03/autoconf/helpers/config.sub 2024-04-17 20:04:08.000000000 +0300
|
||||
+++ nasm-2.16.03-banan_os/autoconf/helpers/config.sub 2024-08-18 18:47:13.768447183 +0300
|
||||
@@ -1754,7 +1754,7 @@
|
||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
||||
- | fiwix* )
|
||||
+ | fiwix* | banan_os* )
|
||||
;;
|
||||
# This one is extra strict with allowed versions
|
||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
|
@ -0,0 +1,50 @@
|
|||
diff -ruN nasm-2.16.03/nasmlib/file.c nasm-2.16.03-banan_os/nasmlib/file.c
|
||||
--- nasm-2.16.03/nasmlib/file.c 2024-04-17 20:04:08.000000000 +0300
|
||||
+++ nasm-2.16.03-banan_os/nasmlib/file.c 2025-01-25 23:07:51.415526537 +0200
|
||||
@@ -160,30 +160,7 @@
|
||||
|
||||
osfname = os_mangle_filename(filename);
|
||||
if (osfname) {
|
||||
- os_fopenflag fopen_flags[4];
|
||||
- memset(fopen_flags, 0, sizeof fopen_flags);
|
||||
-
|
||||
- fopen_flags[0] = 'r';
|
||||
- fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b';
|
||||
-
|
||||
-#if defined(__GLIBC__) || defined(__linux__)
|
||||
- /*
|
||||
- * Try to open this file with memory mapping for speed, unless we are
|
||||
- * going to do it "manually" with nasm_map_file()
|
||||
- */
|
||||
- if (!(flags & NF_FORMAP))
|
||||
- fopen_flags[2] = 'm';
|
||||
-#endif
|
||||
-
|
||||
- while (true) {
|
||||
- f = os_fopen(osfname, fopen_flags);
|
||||
- if (f || errno != EINVAL || !fopen_flags[2])
|
||||
- break;
|
||||
-
|
||||
- /* We got EINVAL but with 'm'; try again without 'm' */
|
||||
- fopen_flags[2] = '\0';
|
||||
- }
|
||||
-
|
||||
+ f = os_fopen(osfname, "r");
|
||||
os_free_filename(osfname);
|
||||
}
|
||||
|
||||
@@ -201,13 +178,7 @@
|
||||
|
||||
osfname = os_mangle_filename(filename);
|
||||
if (osfname) {
|
||||
- os_fopenflag fopen_flags[3];
|
||||
-
|
||||
- fopen_flags[0] = 'w';
|
||||
- fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b';
|
||||
- fopen_flags[2] = '\0';
|
||||
-
|
||||
- f = os_fopen(osfname, fopen_flags);
|
||||
+ f = os_fopen(osfname, "w");
|
||||
os_free_filename(osfname);
|
||||
}
|
||||
|
|
@ -21,5 +21,8 @@ foreach(library ${USERSPACE_LIBRARIES})
|
|||
target_link_options(${library_lower} PRIVATE -nolibc)
|
||||
# Default compile options
|
||||
target_compile_options(${library_lower} PRIVATE -g -O2 -Wall -Wextra -Werror)
|
||||
|
||||
# set SONAME as cmake doesn't set it for some reason??
|
||||
set_target_properties(${library_lower} PROPERTIES LINK_FLAGS "-Wl,-soname,${library_lower}.so")
|
||||
endif()
|
||||
endforeach()
|
||||
|
|
|
@ -76,7 +76,10 @@ add_library(libc-static STATIC $<TARGET_OBJECTS:objlibc>)
|
|||
add_library(libc-shared SHARED $<TARGET_OBJECTS:objlibc>)
|
||||
|
||||
target_link_options(libc-static PRIVATE -nostdlib)
|
||||
target_link_libraries(libc-static PRIVATE -lgcc)
|
||||
|
||||
target_link_options(libc-shared PRIVATE -nostdlib)
|
||||
target_link_libraries(libc-shared PRIVATE -lgcc)
|
||||
|
||||
install(TARGETS libc-static OPTIONAL)
|
||||
install(TARGETS libc-shared OPTIONAL)
|
||||
|
@ -84,6 +87,9 @@ install(TARGETS libc-shared OPTIONAL)
|
|||
set_target_properties(libc-static PROPERTIES OUTPUT_NAME libc)
|
||||
set_target_properties(libc-shared PROPERTIES OUTPUT_NAME libc)
|
||||
|
||||
# set SONAME as cmake doesn't set it for some reason??
|
||||
set_target_properties(libc-shared PROPERTIES LINK_FLAGS "-Wl,-soname,libc.so")
|
||||
|
||||
add_library(libc ALIAS libc-shared)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libgcc_s.so OUTPUT_VARIABLE LIBGCC_S_LINK OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
|
|
@ -10,9 +10,10 @@ struct __DIR
|
|||
int fd { -1 };
|
||||
size_t entry_count { 0 };
|
||||
size_t entry_index { 0 };
|
||||
// FIXME: we should probably allocate entries dynamically
|
||||
// based if syscall returns ENOBUFS
|
||||
dirent entries[128];
|
||||
size_t entries_size { 0 };
|
||||
dirent* entries { nullptr };
|
||||
|
||||
static constexpr size_t default_entries_size { 128 };
|
||||
};
|
||||
|
||||
int closedir(DIR* dirp)
|
||||
|
@ -42,10 +43,18 @@ int dirfd(DIR* dirp)
|
|||
|
||||
DIR* fdopendir(int fd)
|
||||
{
|
||||
DIR* dirp = (DIR*)malloc(sizeof(DIR));
|
||||
DIR* dirp = static_cast<DIR*>(malloc(sizeof(DIR)));
|
||||
if (dirp == nullptr)
|
||||
return nullptr;
|
||||
|
||||
dirp->entries = static_cast<dirent*>(malloc(DIR::default_entries_size * sizeof(dirent)));
|
||||
dirp->entries_size = DIR::default_entries_size;
|
||||
if (dirp->entries == nullptr)
|
||||
{
|
||||
free(dirp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dirp->fd = fd;
|
||||
dirp->entry_count = 0;
|
||||
dirp->entry_index = 0;
|
||||
|
@ -73,7 +82,18 @@ struct dirent* readdir(DIR* dirp)
|
|||
if (dirp->entry_index < dirp->entry_count)
|
||||
return &dirp->entries[dirp->entry_index];
|
||||
|
||||
long entry_count = syscall(SYS_READ_DIR, dirp->fd, dirp->entries, sizeof(dirp->entries) / sizeof(dirp->entries[0]));
|
||||
readdir_do_syscall:
|
||||
long entry_count = syscall(SYS_READ_DIR, dirp->fd, dirp->entries, dirp->entries_size);
|
||||
if (entry_count == -1 && errno == ENOBUFS)
|
||||
{
|
||||
const size_t new_entries_size = dirp->entries_size * 2;
|
||||
dirent* new_entries = static_cast<dirent*>(malloc(new_entries_size * sizeof(dirent)));
|
||||
if (new_entries == nullptr)
|
||||
return nullptr;
|
||||
dirp->entries = new_entries;
|
||||
dirp->entries_size = new_entries_size;
|
||||
goto readdir_do_syscall;
|
||||
}
|
||||
if (entry_count <= 0)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
__BEGIN_DECLS
|
||||
|
||||
[[noreturn]] void __assert_fail(const char*, const char*, int, const char*);
|
||||
__attribute__((noreturn))
|
||||
void __assert_fail(const char*, const char*, int, const char*);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#ifdef __TINYC__
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include_next <stdint.h>
|
||||
#endif
|
|
@ -1,4 +1,5 @@
|
|||
#include <BAN/Assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
|
@ -6,11 +7,29 @@
|
|||
|
||||
static_assert(sizeof(sigset_t) * 8 >= _SIGMAX);
|
||||
|
||||
static int validate_signal(int sig)
|
||||
{
|
||||
if (_SIGMIN <= sig && sig <= _SIGMAX)
|
||||
return 0;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int kill(pid_t pid, int sig)
|
||||
{
|
||||
return syscall(SYS_KILL, pid, sig);
|
||||
}
|
||||
|
||||
int killpg(pid_t pgrp, int sig)
|
||||
{
|
||||
if (pgrp <= 1)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return kill(-pgrp, sig);
|
||||
}
|
||||
|
||||
void psignal(int signum, const char* message)
|
||||
{
|
||||
if (message && *message)
|
||||
|
@ -37,10 +56,20 @@ int sigaction(int sig, const struct sigaction* __restrict act, struct sigaction*
|
|||
|
||||
int sigaddset(sigset_t* set, int signo)
|
||||
{
|
||||
if (validate_signal(signo) == -1)
|
||||
return -1;
|
||||
*set |= 1ull << signo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigdelset(sigset_t* set, int signo)
|
||||
{
|
||||
if (validate_signal(signo) == -1)
|
||||
return -1;
|
||||
*set &= ~(1ull << signo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigemptyset(sigset_t* set)
|
||||
{
|
||||
*set = 0;
|
||||
|
@ -53,8 +82,40 @@ int sigfillset(sigset_t* set)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sighold(int sig)
|
||||
{
|
||||
if (validate_signal(sig) == -1)
|
||||
return -1;
|
||||
sigset_t set;
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, sig);
|
||||
return sigprocmask(SIG_BLOCK, &set, nullptr);
|
||||
}
|
||||
|
||||
int sigignore(int sig)
|
||||
{
|
||||
if (signal(sig, SIG_IGN) == SIG_ERR)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int siginterrupt(int sig, int flag)
|
||||
{
|
||||
if (validate_signal(sig) == -1)
|
||||
return -1;
|
||||
struct sigaction act;
|
||||
(void)sigaction(sig, nullptr, &act);
|
||||
if (flag)
|
||||
act.sa_flags &= ~SA_RESTART;
|
||||
else
|
||||
act.sa_flags |= SA_RESTART;
|
||||
return sigaction(sig, &act, nullptr);
|
||||
}
|
||||
|
||||
int sigismember(const sigset_t* set, int signo)
|
||||
{
|
||||
if (validate_signal(signo) == -1)
|
||||
return -1;
|
||||
return (*set >> signo) & 1;
|
||||
}
|
||||
|
||||
|
@ -79,3 +140,13 @@ int sigprocmask(int how, const sigset_t* __restrict set, sigset_t* __restrict os
|
|||
{
|
||||
return pthread_sigmask(how, set, oset);
|
||||
}
|
||||
|
||||
int sigrelse(int sig)
|
||||
{
|
||||
if (validate_signal(sig) == -1)
|
||||
return -1;
|
||||
sigset_t set;
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, sig);
|
||||
return sigprocmask(SIG_UNBLOCK, &set, nullptr);
|
||||
}
|
||||
|
|
|
@ -189,27 +189,28 @@ int strcoll(const char* s1, const char* s2)
|
|||
|
||||
char* strdup(const char* str)
|
||||
{
|
||||
const size_t size = strlen(str) + 1;
|
||||
const size_t size = strlen(str);
|
||||
|
||||
char* new_str = (char*)malloc(size);
|
||||
char* new_str = (char*)malloc(size + 1);
|
||||
if (new_str == nullptr)
|
||||
return nullptr;
|
||||
|
||||
memcpy(new_str, str, size);
|
||||
new_str[size] = '\0';
|
||||
return new_str;
|
||||
}
|
||||
|
||||
char* strndup(const char* str, size_t size)
|
||||
{
|
||||
if (strlen(str) < size)
|
||||
size = strlen(str);
|
||||
size += 1;
|
||||
if (size_t len = strlen(str); len < size)
|
||||
size = len;
|
||||
|
||||
char* new_str = (char*)malloc(size);
|
||||
char* new_str = (char*)malloc(size + 1);
|
||||
if (new_str == nullptr)
|
||||
return nullptr;
|
||||
|
||||
memcpy(new_str, str, size);
|
||||
new_str[size] = '\0';
|
||||
return new_str;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ int main(int argc, const char* argv[])
|
|||
const char* target = argv[i++];
|
||||
|
||||
struct stat st;
|
||||
if (stat(target, &st) == -1)
|
||||
if (!do_symlink && stat(target, &st) == -1)
|
||||
{
|
||||
perror("stat");
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue