Compare commits
10 Commits
1d9041f2aa
...
dbba9128a4
Author | SHA1 | Date |
---|---|---|
Bananymous | dbba9128a4 | |
Bananymous | 352c1ddc16 | |
Bananymous | 4d96ae56ac | |
Bananymous | adadb10b15 | |
Bananymous | a749b9806e | |
Bananymous | 615d9d4abe | |
Bananymous | aa03274093 | |
Bananymous | e7a06979ec | |
Bananymous | 3651306f57 | |
Bananymous | 5dce4e6aea |
|
@ -1 +1,3 @@
|
|||
installed
|
||||
*/*
|
||||
!*/patches/
|
||||
!*/build.sh
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $(dirname $(realpath $0))
|
||||
|
||||
if [ ! -f installed ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while read port; do
|
||||
${port}/build.sh
|
||||
done < installed
|
|
@ -1 +0,0 @@
|
|||
curl-*
|
|
@ -1,58 +1,11 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
if [ -z $BANAN_ARCH ]; then
|
||||
echo "You must set the BANAN_ARCH environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $BANAN_SYSROOT ]; then
|
||||
echo "You must set the BANAN_ARCH environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $BANAN_TOOLCHAIN_PREFIX ]; then
|
||||
echo "You must set the BANAN_TOOLCHAIN_PREFIX environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURL_VERSION="curl-8.8.0"
|
||||
CURL_TAR="$CURL_VERSION.tar.gz"
|
||||
CURL_URL="https://curl.se/download/$CURL_TAR"
|
||||
|
||||
cd $(dirname $(realpath $0))
|
||||
|
||||
if [ ! -d $CURL_VERSION ]; then
|
||||
if [ ! -f $CURL_TAR ]; then
|
||||
wget $CURL_URL
|
||||
fi
|
||||
tar xf $CURL_TAR
|
||||
|
||||
for patch in ./patches/*; do
|
||||
patch -ruN -d $CURL_VERSION < "$patch"
|
||||
done
|
||||
|
||||
grep -qxF curl ../installed || echo curl >> ../installed
|
||||
fi
|
||||
|
||||
cd $CURL_VERSION
|
||||
|
||||
export PATH="$BANAN_TOOLCHAIN_PREFIX/bin:$PATH"
|
||||
|
||||
if [ ! -d "build-${BANAN_ARCH}" ]; then
|
||||
mkdir -p "build-${BANAN_ARCH}"
|
||||
cd "build-${BANAN_ARCH}"
|
||||
|
||||
../configure \
|
||||
--host=x86_64-banan_os \
|
||||
--prefix=$BANAN_SYSROOT/usr \
|
||||
--without-ssl \
|
||||
--disable-threaded-resolver \
|
||||
--disable-ipv6 \
|
||||
--disable-docs
|
||||
|
||||
cd ..
|
||||
fi
|
||||
|
||||
cd "build-${BANAN_ARCH}"
|
||||
|
||||
make -j $(nproc) && make install
|
||||
NAME='curl'
|
||||
VERSION='8.8.0'
|
||||
DOWNLOAD_URL="https://curl.se/download/curl-$VERSION.tar.gz#77c0e1cd35ab5b45b659645a93b46d660224d0024f1185e8a95cdb27ae3d787d"
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--without-ssl'
|
||||
'--disable-threaded-resolver'
|
||||
'--disable-ipv6'
|
||||
'--disable-docs'
|
||||
)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
doomgeneric/
|
||||
doom1.wad
|
|
@ -1 +0,0 @@
|
|||
This is a port of doomgeneric. You will need doom wad to play. Copy the wad file into sysroot and use the -iwad argument to specify wad location.
|
|
@ -1,33 +1,17 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
if [ -z $BANAN_ARCH ]; then
|
||||
echo "You must set the BANAN_ARCH environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $BANAN_SYSROOT ]; then
|
||||
echo "You must set the BANAN_ARCH environment variable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $(dirname $(realpath $0))
|
||||
|
||||
if [ ! -d "doomgeneric" ]; then
|
||||
git clone https://github.com/ozkl/doomgeneric.git
|
||||
cd doomgeneric
|
||||
git checkout 613f870b6fa83ede448a247de5a2571092fa729d
|
||||
for patch in ../patches/*; do
|
||||
git am "$patch"
|
||||
done
|
||||
cd ..
|
||||
|
||||
grep -qxF doom ../installed || echo doom >> ../installed
|
||||
fi
|
||||
NAME='doom'
|
||||
VERSION='git'
|
||||
DOWNLOAD_URL="https://github.com/ozkl/doomgeneric.git#613f870b6fa83ede448a247de5a2571092fa729d"
|
||||
|
||||
build() {
|
||||
if [ ! -f doom1.wad ]; then
|
||||
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
|
||||
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad || exit 1
|
||||
fi
|
||||
make --directory doomgeneric --file Makefile.banan_os -j$(nproc) || exit 1
|
||||
}
|
||||
|
||||
make --directory doomgeneric/doomgeneric --file Makefile.banan_os -j $(nproc)
|
||||
cp "doomgeneric/doomgeneric/build-${BANAN_ARCH}/doomgeneric" "${BANAN_SYSROOT}/bin/doom"
|
||||
cp doom1.wad $BANAN_SYSROOT/home/user/
|
||||
install() {
|
||||
cp doomgeneric/build/doom "${BANAN_SYSROOT}/bin/" || exit 1
|
||||
cp ./doom1.wad "$BANAN_SYSROOT/home/user/" || exit 1
|
||||
}
|
||||
|
|
|
@ -29,16 +29,16 @@ index 0000000..0878148
|
|||
+ VB=@
|
||||
+endif
|
||||
+
|
||||
+CC=$(BANAN_TOOLCHAIN_PREFIX)/bin/$(BANAN_ARCH)-banan_os-gcc
|
||||
+CXX=$(BANAN_TOOLCHAIN_PREFIX)/bin/$(BANAN_ARCH)-banan_os-g++
|
||||
+CC=$(BANAN_ARCH)-banan_os-gcc
|
||||
+CXX=$(BANAN_ARCH)-banan_os-g++
|
||||
+CFLAGS+=-O3 -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE
|
||||
+CXXFLAGS+=$(CFLAGS) --std=c++20
|
||||
+LDFLAGS+=
|
||||
+LIBS+=-lgui -linput -lstdc++
|
||||
+
|
||||
+# subdirectory for objects
|
||||
+OBJDIR=build-$(BANAN_ARCH)
|
||||
+OUTPUT=$(OBJDIR)/doomgeneric
|
||||
+OBJDIR=build
|
||||
+OUTPUT=$(OBJDIR)/doom
|
||||
+
|
||||
+SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_banan_os.o
|
||||
+OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM))
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
#!/bin/bash
|
||||
|
||||
if (( $# != 1 )); then
|
||||
echo "No arguments given for $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BANAN_ROOT_DIR="$(dirname $(realpath $0))/.."
|
||||
source "$BANAN_ROOT_DIR/script/config.sh"
|
||||
export PATH="$BANAN_TOOLCHAIN_PREFIX/bin:$PATH"
|
||||
|
||||
if [ ! -f "$BANAN_SYSROOT/usr/lib/libc.a" ]; then
|
||||
pushd "$BANAN_ROOT_DIR" >/dev/null
|
||||
./bos libc || exit 1
|
||||
./bos install || exit 1
|
||||
popd >/dev/null
|
||||
fi
|
||||
|
||||
clean() {
|
||||
find . -mindepth 1 -maxdepth 1 -not -name 'patches' -not -name 'build.sh' -exec rm -rf {} +
|
||||
}
|
||||
|
||||
build() {
|
||||
configure_options=("--host=$BANAN_ARCH-banan_os" "--prefix=/usr" )
|
||||
configure_options+=(${CONFIGURE_OPTIONS[*]})
|
||||
|
||||
./configure ${configure_options[*]} || exit 1
|
||||
make -j$(nproc) || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
make install "DESTDIR=$BANAN_SYSROOT" || exit 1
|
||||
}
|
||||
|
||||
source $1
|
||||
|
||||
if [ -z $NAME ] || [ -z $VERSION ] || [ -z $DOWNLOAD_URL ]; then
|
||||
echo "Port does not set needed environment variables" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for dependency in "${DEPENDENCIES[@]}"; do
|
||||
pushd "../$dependency" >/dev/null
|
||||
pwd
|
||||
if ! ./build.sh; then
|
||||
echo "Failed to install dependency '$dependency' of port '$NAME'"
|
||||
exit 1
|
||||
fi
|
||||
popd >/dev/null
|
||||
done
|
||||
|
||||
build_dir="$NAME-$VERSION-$BANAN_ARCH"
|
||||
|
||||
if [ "$VERSION" = "git" ]; then
|
||||
regex="(.*/.*\.git)#(.*)"
|
||||
|
||||
if [[ $DOWNLOAD_URL =~ $regex ]]; then
|
||||
REPO_URL="${BASH_REMATCH[1]}"
|
||||
COMMIT="${BASH_REMATCH[2]}"
|
||||
|
||||
if [ -d "$build_dir" ]; then
|
||||
pushd $build_dir >/dev/null
|
||||
if [ ! "$(git rev-parse HEAD)" = "$COMMIT" ]; then
|
||||
clean
|
||||
fi
|
||||
popd >/dev/null
|
||||
fi
|
||||
|
||||
if [ ! -d "$build_dir" ]; then
|
||||
git clone "$REPO_URL" "$build_dir" || exit 1
|
||||
|
||||
pushd "$build_dir" >/dev/null
|
||||
git checkout "$COMMIT" || exit 1
|
||||
if [ -d patches ]; then
|
||||
for patch in ../patches/*; do
|
||||
git apply "$patch" || exit 1
|
||||
done
|
||||
fi
|
||||
popd >/dev/null
|
||||
fi
|
||||
else
|
||||
echo "Invalid format in DOWNLOAD_URL" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
regex=".*/(.*\.tar\..*)#(.*)"
|
||||
if [[ $DOWNLOAD_URL =~ $regex ]]; then
|
||||
TAR_NAME="${BASH_REMATCH[1]}"
|
||||
TAR_HASH="${BASH_REMATCH[2]}"
|
||||
|
||||
if [ -f "$TAR_NAME" ]; then
|
||||
if ! echo "$TAR_HASH $TAR_NAME" | sha256sum --check >/dev/null; then
|
||||
clean
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$TAR_NAME" ]; then
|
||||
wget "$DOWNLOAD_URL" || exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$TAR_HASH $TAR_NAME" | sha256sum --check >/dev/null; then
|
||||
echo "Tar hash does not match" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$build_dir" ]; then
|
||||
tar xf "$TAR_NAME" || exit 1
|
||||
|
||||
: "${TAR_CONTENT:=$NAME-$VERSION}"
|
||||
mv "$TAR_CONTENT" "$build_dir" || exit 1
|
||||
|
||||
if [ -d patches ]; then
|
||||
for patch in ./patches/*; do
|
||||
patch -ruN -d "$build_dir" < "$patch" || exit 1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Invalid format in DOWNLOAD_URL" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
needs_compile=1
|
||||
if [ -f ".compile_hash-$BANAN_ARCH" ]; then
|
||||
cat ".compile_hash-$BANAN_ARCH" | sha256sum --check >/dev/null
|
||||
needs_compile=$?
|
||||
fi
|
||||
|
||||
cd "$build_dir"
|
||||
|
||||
if (( $needs_compile )); then
|
||||
build
|
||||
sha256sum "$BANAN_SYSROOT/usr/lib/libc.a" > "../.compile_hash-$BANAN_ARCH"
|
||||
fi
|
||||
|
||||
install
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='ncurses'
|
||||
VERSION='6.5'
|
||||
DOWNLOAD_URL="https://invisible-island.net/archives/ncurses/ncurses-$VERSION.tar.gz#136d91bc269a9a5785e5f9e980bc76ab57428f604ce3e5a5a90cebc767971cc6"
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-db-intall'
|
||||
'--disable-widec'
|
||||
'--without-ada'
|
||||
'--without-manpages'
|
||||
'--without-dlsym'
|
||||
'--without-cxx-binding'
|
||||
)
|
|
@ -0,0 +1,122 @@
|
|||
diff -ruN ncurses-6.5/config.log ncurses-6.5-banan_os/config.log
|
||||
--- ncurses-6.5/config.log 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ ncurses-6.5-banan_os/config.log 2024-08-05 12:15:48.028466613 +0300
|
||||
@@ -0,0 +1,106 @@
|
||||
+This file contains any messages produced by compilers while
|
||||
+running configure, to aid debugging if configure makes a mistake.
|
||||
+
|
||||
+It was created by configure, which was
|
||||
+generated by GNU Autoconf 2.52.20231210. Invocation command line was
|
||||
+
|
||||
+ $ ./configure --host=x86_64-pc-banan_os --prefix=/usr/local --disable-db-intall --disable-widec --without-ada --without-manpages --without-dlsym --without-cxx-binding
|
||||
+
|
||||
+## ---------- ##
|
||||
+## Platform. ##
|
||||
+## ---------- ##
|
||||
+
|
||||
+hostname = arch
|
||||
+uname -m = x86_64
|
||||
+uname -r = 6.10.2-arch1-2
|
||||
+uname -s = Linux
|
||||
+uname -v = #1 SMP PREEMPT_DYNAMIC Sat, 03 Aug 2024 17:56:17 +0000
|
||||
+
|
||||
+/usr/bin/uname -p = unknown
|
||||
+/bin/uname -X = unknown
|
||||
+
|
||||
+/bin/arch = unknown
|
||||
+/usr/bin/arch -k = unknown
|
||||
+/usr/convex/getsysinfo = unknown
|
||||
+hostinfo = unknown
|
||||
+/bin/machine = unknown
|
||||
+/usr/bin/oslevel = unknown
|
||||
+/bin/universe = unknown
|
||||
+
|
||||
+PATH = /home/oskari/dev/banan-os/ports/../toolchain/local/bin:/home/oskari/.wasmer/bin:/home/oskari/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/rustup/bin
|
||||
+
|
||||
+## ------------ ##
|
||||
+## Core tests. ##
|
||||
+## ------------ ##
|
||||
+
|
||||
+configure:1175: PATH=".;."; conftest.sh
|
||||
+./configure: line 1176: conftest.sh: command not found
|
||||
+configure:1178: $? = 127
|
||||
+configure:1195: checking for ggrep
|
||||
+configure:1221: result: no
|
||||
+configure:1195: checking for grep
|
||||
+configure:1210: found /usr/bin/grep
|
||||
+configure:1218: result: grep
|
||||
+configure:1229: checking for egrep
|
||||
+configure:1285: result: grep -E
|
||||
+configure:1296: result: Configuring NCURSES 6.5 ABI 6 (Mon Aug 5 12:15:47 EEST 2024)
|
||||
+configure:1300: checking for package version
|
||||
+configure:1321: result: 6.5
|
||||
+configure:1324: checking for package patch date
|
||||
+configure:1341: result: 20240427
|
||||
+configure:1352: testing ABI VERSION 5:0:10 ...
|
||||
+configure:1356: testing VERSION_MAJOR 6 ...
|
||||
+configure:1360: testing VERSION_MINOR 5 ...
|
||||
+configure:1364: testing VERSION_PATCH 20240427 ...
|
||||
+configure:1509: checking build system type
|
||||
+configure:1527: result: x86_64-pc-linux-gnu
|
||||
+configure:1534: checking host system type
|
||||
+configure:1543: error: /bin/sh ./config.sub x86_64-pc-banan_os failed
|
||||
+
|
||||
+## ----------------- ##
|
||||
+## Cache variables. ##
|
||||
+## ----------------- ##
|
||||
+
|
||||
+ac_cv_build=x86_64-pc-linux-gnu
|
||||
+ac_cv_build_alias=x86_64-pc-linux-gnu
|
||||
+ac_cv_env_CC_set=
|
||||
+ac_cv_env_CC_value=
|
||||
+ac_cv_env_CFLAGS_set=
|
||||
+ac_cv_env_CFLAGS_value=
|
||||
+ac_cv_env_CPPFLAGS_set=
|
||||
+ac_cv_env_CPPFLAGS_value=
|
||||
+ac_cv_env_CPP_set=
|
||||
+ac_cv_env_CPP_value=
|
||||
+ac_cv_env_CXXCPP_set=
|
||||
+ac_cv_env_CXXCPP_value=
|
||||
+ac_cv_env_CXXFLAGS_set=
|
||||
+ac_cv_env_CXXFLAGS_value=
|
||||
+ac_cv_env_CXX_set=
|
||||
+ac_cv_env_CXX_value=
|
||||
+ac_cv_env_LDFLAGS_set=
|
||||
+ac_cv_env_LDFLAGS_value=
|
||||
+ac_cv_env_build_alias_set=
|
||||
+ac_cv_env_build_alias_value=
|
||||
+ac_cv_env_host_alias_set=set
|
||||
+ac_cv_env_host_alias_value=x86_64-pc-banan_os
|
||||
+ac_cv_env_target_alias_set=
|
||||
+ac_cv_env_target_alias_value=
|
||||
+ac_cv_host=
|
||||
+ac_cv_host_alias=x86_64-pc-banan_os
|
||||
+ac_cv_path_EGREP='grep -E'
|
||||
+ac_cv_prog_GREP=grep
|
||||
+cf_cv_abi_default=6
|
||||
+cf_cv_abi_version=6
|
||||
+cf_cv_rel_version=6.5
|
||||
+cf_cv_timestamp='Mon Aug 5 12:15:47 EEST 2024'
|
||||
+
|
||||
+## ------------ ##
|
||||
+## confdefs.h. ##
|
||||
+## ------------ ##
|
||||
+
|
||||
+#define PACKAGE "ncurses"
|
||||
+#define NCURSES_VERSION "6.5"
|
||||
+#define NCURSES_PATCHDATE 20240427
|
||||
+
|
||||
+
|
||||
+configure: exit 1
|
||||
diff -ruN ncurses-6.5/config.sub ncurses-6.5-banan_os/config.sub
|
||||
--- ncurses-6.5/config.sub 2023-12-27 16:41:27.000000000 +0200
|
||||
+++ ncurses-6.5-banan_os/config.sub 2024-08-05 12:17:03.025286556 +0300
|
||||
@@ -1768,7 +1768,7 @@
|
||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
||||
- | fiwix* | mlibc* | cos* | mbr* | ironclad* )
|
||||
+ | fiwix* | mlibc* | cos* | mbr* | ironclad* | banan_os* )
|
||||
;;
|
||||
# This one is extra strict with allowed versions
|
||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $(dirname $(realpath $0))
|
||||
|
||||
for port in ./*/.compile_hash*; do
|
||||
pushd $(dirname "$port") >/dev/null
|
||||
./build.sh
|
||||
popd >/dev/null
|
||||
done
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='vim'
|
||||
VERSION='9.0'
|
||||
DOWNLOAD_URL="ftp://ftp.vim.org/pub/vim/unix/vim-$VERSION.tar.bz2#a6456bc154999d83d0c20d968ac7ba6e7df0d02f3cb6427fb248660bacfb336e"
|
||||
TAR_CONTENT='vim90'
|
||||
DEPENDENCIES=( 'ncurses' )
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--with-tlib=ncurses'
|
||||
'--disable-nls'
|
||||
'--disable-sysmouse'
|
||||
'--disable-channel'
|
||||
'vim_cv_toupper_broken=no'
|
||||
'vim_cv_terminfo=yes'
|
||||
'vim_cv_tgetent=yes'
|
||||
'vim_cv_getcwd_broken=no'
|
||||
'vim_cv_stat_ignores_slash=yes'
|
||||
'vim_cv_memmove_handles_overlap=yes'
|
||||
)
|
|
@ -49,7 +49,7 @@ create_image () {
|
|||
build_target all
|
||||
build_target install
|
||||
|
||||
$BANAN_ROOT_DIR/ports/build.sh
|
||||
$BANAN_ROOT_DIR/ports/update.sh
|
||||
|
||||
pushd $BANAN_SYSROOT >/dev/null
|
||||
run_fakeroot tar cf ${BANAN_SYSROOT_TAR} *
|
||||
|
@ -121,6 +121,7 @@ case $1 in
|
|||
;;
|
||||
distclean)
|
||||
rm -rf $BANAN_BUILD_DIR
|
||||
rm $BANAN_ROOT_DIR/ports/*/.compile_hash*
|
||||
;;
|
||||
*)
|
||||
build_target $1
|
||||
|
|
|
@ -5,6 +5,7 @@ set(LIBC_SOURCES
|
|||
dirent.cpp
|
||||
fcntl.cpp
|
||||
grp.cpp
|
||||
inttypes.cpp
|
||||
locale.cpp
|
||||
malloc.cpp
|
||||
math.cpp
|
||||
|
|
|
@ -55,7 +55,7 @@ DIR* fdopendir(int fd)
|
|||
|
||||
DIR* opendir(const char* dirname)
|
||||
{
|
||||
int fd = open(dirname, O_RDONLY | O_DIRECTORY);
|
||||
int fd = open(dirname, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return nullptr;
|
||||
return fdopendir(fd);
|
||||
|
|
|
@ -26,7 +26,8 @@ __BEGIN_DECLS
|
|||
#define IPV6_V6ONLY 7
|
||||
|
||||
#define INADDR_ANY 0
|
||||
#define INADDR_BROADCAST UINT32_MAX
|
||||
#define INADDR_BROADCAST 0xFFFFFFFF
|
||||
#define INADDR_LOOPBACK 0x7F000001
|
||||
|
||||
#define INET_ADDRSTRLEN 16
|
||||
#define INET6_ADDRSTRLEN 46
|
||||
|
|
|
@ -185,6 +185,12 @@ __BEGIN_DECLS
|
|||
#endif
|
||||
#undef __need_uid_t
|
||||
|
||||
#if !defined(__useconds_t_defined) && (defined(__need_all_types) || defined(__need_useconds_t))
|
||||
#define __useconds_t_defined 1
|
||||
typedef unsigned long useconds_t;
|
||||
#endif
|
||||
#undef __need_useconds_t
|
||||
|
||||
#ifdef __need_all_types
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
|
|
@ -101,6 +101,7 @@ __BEGIN_DECLS
|
|||
#define __need_gid_t
|
||||
#define __need_off_t
|
||||
#define __need_pid_t
|
||||
#define __need_useconds_t
|
||||
#include <sys/types.h>
|
||||
|
||||
// FIXME: _CS prefixed definitions
|
||||
|
@ -206,6 +207,7 @@ char* ttyname(int fildes);
|
|||
int ttyname_r(int fildes, char* name, size_t namesize);
|
||||
int unlink(const char* path);
|
||||
int unlinkat(int fd, const char* path, int flag);
|
||||
int usleep(useconds_t usec);
|
||||
ssize_t write(int fildes, const void* buf, size_t nbyte);
|
||||
|
||||
extern char* optarg;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
intmax_t strtoimax(const char* __restrict nptr, char** __restrict endptr, int base)
|
||||
{
|
||||
static_assert(sizeof(intmax_t) == sizeof(long long));
|
||||
return strtoll(nptr, endptr, base);
|
||||
}
|
||||
|
||||
uintmax_t strtoumax(const char* __restrict nptr, char** __restrict endptr, int base)
|
||||
{
|
||||
static_assert(sizeof(uintmax_t) == sizeof(unsigned long long));
|
||||
return strtoull(nptr, endptr, base);
|
||||
}
|
|
@ -9,6 +9,8 @@
|
|||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int h_errno = 0;
|
||||
|
||||
struct hostent* gethostbyname(const char* name)
|
||||
{
|
||||
static char name_buffer[HOST_NAME_MAX + 1];
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <BAN/Assert.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -10,6 +11,14 @@ int kill(pid_t pid, int sig)
|
|||
return syscall(SYS_KILL, pid, sig);
|
||||
}
|
||||
|
||||
void psignal(int signum, const char* message)
|
||||
{
|
||||
if (message && *message)
|
||||
fprintf(stderr, "%s: %s\n", message, strsignal(signum));
|
||||
else
|
||||
fprintf(stderr, "%s\n", strsignal(signum));
|
||||
}
|
||||
|
||||
int raise(int sig)
|
||||
{
|
||||
// FIXME: won't work after multithreaded
|
||||
|
|
|
@ -705,8 +705,11 @@ char* tmpnam(char* storage)
|
|||
return storage;
|
||||
}
|
||||
|
||||
// TODO
|
||||
int ungetc(int, FILE*);
|
||||
int ungetc(int c, FILE* stream)
|
||||
{
|
||||
dwarnln("FIXME: ungetc({}, {})", c, stream);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
int vfprintf(FILE* file, const char* format, va_list arguments)
|
||||
{
|
||||
|
|
|
@ -317,34 +317,34 @@ char* strsignal(int signum)
|
|||
static char buffer[128];
|
||||
switch (signum)
|
||||
{
|
||||
case SIGABRT: strcpy(buffer, "SIGABRT"); break;
|
||||
case SIGALRM: strcpy(buffer, "SIGALRM"); break;
|
||||
case SIGBUS: strcpy(buffer, "SIGBUS"); break;
|
||||
case SIGCHLD: strcpy(buffer, "SIGCHLD"); break;
|
||||
case SIGCONT: strcpy(buffer, "SIGCONT"); break;
|
||||
case SIGFPE: strcpy(buffer, "SIGFPE"); break;
|
||||
case SIGHUP: strcpy(buffer, "SIGHUP"); break;
|
||||
case SIGILL: strcpy(buffer, "SIGILL"); break;
|
||||
case SIGINT: strcpy(buffer, "SIGINT"); break;
|
||||
case SIGKILL: strcpy(buffer, "SIGKILL"); break;
|
||||
case SIGPIPE: strcpy(buffer, "SIGPIPE"); break;
|
||||
case SIGQUIT: strcpy(buffer, "SIGQUIT"); break;
|
||||
case SIGSEGV: strcpy(buffer, "SIGSEGV"); break;
|
||||
case SIGSTOP: strcpy(buffer, "SIGSTOP"); break;
|
||||
case SIGTERM: strcpy(buffer, "SIGTERM"); break;
|
||||
case SIGTSTP: strcpy(buffer, "SIGTSTP"); break;
|
||||
case SIGTTIN: strcpy(buffer, "SIGTTIN"); break;
|
||||
case SIGTTOU: strcpy(buffer, "SIGTTOU"); break;
|
||||
case SIGUSR1: strcpy(buffer, "SIGUSR1"); break;
|
||||
case SIGUSR2: strcpy(buffer, "SIGUSR2"); break;
|
||||
case SIGPOLL: strcpy(buffer, "SIGPOLL"); break;
|
||||
case SIGPROF: strcpy(buffer, "SIGPROF"); break;
|
||||
case SIGSYS: strcpy(buffer, "SIGSYS"); break;
|
||||
case SIGTRAP: strcpy(buffer, "SIGTRAP"); break;
|
||||
case SIGURG: strcpy(buffer, "SIGURG"); break;
|
||||
case SIGVTALRM: strcpy(buffer, "SIGVTALRM"); break;
|
||||
case SIGXCPU: strcpy(buffer, "SIGXCPU"); break;
|
||||
case SIGXFSZ: strcpy(buffer, "SIGXFSZ"); break;
|
||||
case SIGABRT: strcpy(buffer, "Process abort signal."); break;
|
||||
case SIGALRM: strcpy(buffer, "Alarm clock."); break;
|
||||
case SIGBUS: strcpy(buffer, "Access to an undefined portion of a memory object."); break;
|
||||
case SIGCHLD: strcpy(buffer, "Child process terminated, stopped, or continued."); break;
|
||||
case SIGCONT: strcpy(buffer, "Continue executing, if stopped."); break;
|
||||
case SIGFPE: strcpy(buffer, "Erroneous arithmetic operation."); break;
|
||||
case SIGHUP: strcpy(buffer, "Hangup."); break;
|
||||
case SIGILL: strcpy(buffer, "Illegal instruction."); break;
|
||||
case SIGINT: strcpy(buffer, "Terminal interrupt signal."); break;
|
||||
case SIGKILL: strcpy(buffer, "Kill (cannot be caught or ignored)."); break;
|
||||
case SIGPIPE: strcpy(buffer, "Write on a pipe with no one to read it."); break;
|
||||
case SIGQUIT: strcpy(buffer, "Terminal quit signal."); break;
|
||||
case SIGSEGV: strcpy(buffer, "Invalid memory reference."); break;
|
||||
case SIGSTOP: strcpy(buffer, "Stop executing (cannot be caught or ignored)."); break;
|
||||
case SIGTERM: strcpy(buffer, "Termination signal."); break;
|
||||
case SIGTSTP: strcpy(buffer, "Terminal stop signal."); break;
|
||||
case SIGTTIN: strcpy(buffer, "Background process attempting read."); break;
|
||||
case SIGTTOU: strcpy(buffer, "Background process attempting write."); break;
|
||||
case SIGUSR1: strcpy(buffer, "User-defined signal 1."); break;
|
||||
case SIGUSR2: strcpy(buffer, "User-defined signal 2."); break;
|
||||
case SIGPOLL: strcpy(buffer, "Pollable event."); break;
|
||||
case SIGPROF: strcpy(buffer, "Profiling timer expired."); break;
|
||||
case SIGSYS: strcpy(buffer, "Bad system call."); break;
|
||||
case SIGTRAP: strcpy(buffer, "Trace/breakpoint trap."); break;
|
||||
case SIGURG: strcpy(buffer, "High bandwidth data is available at a socket."); break;
|
||||
case SIGVTALRM: strcpy(buffer, "Virtual timer expired."); break;
|
||||
case SIGXCPU: strcpy(buffer, "CPU time limit exceeded."); break;
|
||||
case SIGXFSZ: strcpy(buffer, "File size limit exceeded."); break;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#include <BAN/Assert.h>
|
||||
#include <BAN/Debug.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <termios.h>
|
||||
|
@ -65,7 +68,11 @@ int tcdrain(int);
|
|||
|
||||
int tcflow(int, int);
|
||||
|
||||
int tcflush(int, int);
|
||||
int tcflush(int fd, int queue_selector)
|
||||
{
|
||||
dwarnln("FIXME: tcflush({}, {})", fd, queue_selector);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
int tcgetattr(int fildes, struct termios* termios)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <BAN/Assert.h>
|
||||
#include <BAN/Debug.h>
|
||||
#include <BAN/Math.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
@ -107,6 +109,346 @@ struct tm* localtime(const time_t* timer)
|
|||
|
||||
size_t strftime(char* __restrict s, size_t maxsize, const char* __restrict format, const struct tm* __restrict timeptr)
|
||||
{
|
||||
dwarnln("strftime({}, {}, {}, {})", s, maxsize, format, timeptr);
|
||||
ASSERT_NOT_REACHED();
|
||||
size_t len = 0;
|
||||
|
||||
struct conversion_t
|
||||
{
|
||||
char flag = '\0';
|
||||
int width = -1;
|
||||
char modifier = '\0';
|
||||
};
|
||||
|
||||
static constexpr const char* abbr_wday[] {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
static constexpr const char* full_wday[] {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
|
||||
};
|
||||
|
||||
static constexpr const char* abbr_mon[] {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
static constexpr const char* full_mon[] {
|
||||
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
||||
};
|
||||
|
||||
const auto append_string =
|
||||
[&](const char* string) -> bool
|
||||
{
|
||||
size_t string_len = strlen(string);
|
||||
if (len + string_len >= maxsize)
|
||||
return false;
|
||||
strcpy(s + len, string);
|
||||
len += string_len;
|
||||
return true;
|
||||
};
|
||||
|
||||
const auto append_string_from_list =
|
||||
[&]<size_t LIST_SIZE>(int index, const char* const (&list)[LIST_SIZE]) -> bool
|
||||
{
|
||||
const char* string = "INVALID";
|
||||
if (index >= 0 && index < (int)LIST_SIZE)
|
||||
string = list[index];
|
||||
return append_string(string);
|
||||
};
|
||||
|
||||
const auto append_value =
|
||||
[&](const char* format, int value) -> bool
|
||||
{
|
||||
int written = snprintf(s + len, maxsize - len, format, value);
|
||||
if (len + written >= maxsize)
|
||||
return false;
|
||||
len += written;
|
||||
return true;
|
||||
};
|
||||
|
||||
while (*format && len < maxsize)
|
||||
{
|
||||
if (*format != '%')
|
||||
{
|
||||
s[len++] = *format++;
|
||||
continue;
|
||||
}
|
||||
|
||||
format++;
|
||||
|
||||
conversion_t conversion;
|
||||
switch (*format)
|
||||
{
|
||||
case '+':
|
||||
case '0':
|
||||
conversion.flag = *format;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
if (isdigit(*format))
|
||||
{
|
||||
conversion.width = 0;
|
||||
while (isdigit(*format))
|
||||
{
|
||||
conversion.width = (conversion.width * 10) + (*format + '0');
|
||||
format++;
|
||||
}
|
||||
}
|
||||
switch (*format)
|
||||
{
|
||||
case 'E':
|
||||
case 'O':
|
||||
dwarnln("TODO: strftime moodifiers");
|
||||
conversion.modifier = *format;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*format)
|
||||
{
|
||||
case 'a':
|
||||
if (!append_string_from_list(timeptr->tm_wday, abbr_wday))
|
||||
return 0;
|
||||
break;
|
||||
case 'A':
|
||||
if (!append_string_from_list(timeptr->tm_wday, full_wday))
|
||||
return 0;
|
||||
break;
|
||||
case 'b':
|
||||
case 'h':
|
||||
if (!append_string_from_list(timeptr->tm_mon, abbr_mon))
|
||||
return 0;
|
||||
break;
|
||||
case 'B':
|
||||
if (!append_string_from_list(timeptr->tm_mon, full_mon))
|
||||
return 0;
|
||||
break;
|
||||
case 'c':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%a %b %e %H:%M:%S %Y", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'C':
|
||||
{
|
||||
if (conversion.flag == '\0')
|
||||
conversion.flag = ' ';
|
||||
if (conversion.flag == '+' && conversion.width <= 2)
|
||||
conversion.flag = '0';
|
||||
if (conversion.width < 2)
|
||||
conversion.width = 2;
|
||||
|
||||
char new_format[32];
|
||||
sprintf(new_format, "%%%c%dd", conversion.flag, conversion.width);
|
||||
if (!append_value(new_format, timeptr->tm_year % 100))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
if (!append_value("%02d", timeptr->tm_mday))
|
||||
return 0;
|
||||
break;
|
||||
case 'D':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%m/%d/%y", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'e':
|
||||
if (!append_value("% 2d", timeptr->tm_mday))
|
||||
return 0;
|
||||
break;
|
||||
case 'F':
|
||||
{
|
||||
if (conversion.flag == '\0')
|
||||
conversion.flag = '+';
|
||||
if (conversion.width == -1)
|
||||
conversion.width = 10;
|
||||
if (conversion.width < 6)
|
||||
conversion.width = 6;
|
||||
|
||||
char new_format[32];
|
||||
sprintf(new_format, "%%%c%dY-%%m-%%d", conversion.flag, conversion.width - 6);
|
||||
|
||||
if (size_t ret = strftime(s + len, maxsize - len, new_format, timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
}
|
||||
case 'H':
|
||||
if (!append_value("%02d", timeptr->tm_hour))
|
||||
return 0;
|
||||
break;
|
||||
case 'I':
|
||||
if (!append_value("%02d", ((timeptr->tm_hour + 11) % 12) + 1))
|
||||
return 0;
|
||||
break;
|
||||
case 'j':
|
||||
if (!append_value("%03d", timeptr->tm_yday + 1))
|
||||
return 0;
|
||||
break;
|
||||
case 'm':
|
||||
if (!append_value("%02d", timeptr->tm_mon + 1))
|
||||
return 0;
|
||||
break;
|
||||
case 'M':
|
||||
if (!append_value("%02d", timeptr->tm_min))
|
||||
return 0;
|
||||
break;
|
||||
case 'n':
|
||||
s[len++] = '\n';
|
||||
break;
|
||||
case 'p':
|
||||
if (!append_string(timeptr->tm_hour < 12 ? "AM" : "PM"))
|
||||
return 0;
|
||||
break;
|
||||
case 'r':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%I:%M:%S %p", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'R':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%H:%M", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'S':
|
||||
if (!append_value("%02d", timeptr->tm_sec))
|
||||
return 0;
|
||||
break;
|
||||
case 't':
|
||||
s[len++] = '\t';
|
||||
break;
|
||||
case 'T':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%H:%M:%S", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'u':
|
||||
if (!append_value("%d", ((timeptr->tm_wday + 6) % 7) + 1))
|
||||
return 0;
|
||||
break;
|
||||
case 'U':
|
||||
if (!append_value("%02d", (timeptr->tm_yday - timeptr->tm_wday + 7) / 7))
|
||||
return 0;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'V':
|
||||
{
|
||||
// Adapted from GNU libc implementation
|
||||
|
||||
constexpr auto is_leap_year =
|
||||
[](int year) -> bool
|
||||
{
|
||||
if (year % 400 == 0)
|
||||
return true;
|
||||
if (year % 100 == 0)
|
||||
return false;
|
||||
if (year % 4 == 0)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
constexpr auto iso_week_days =
|
||||
[](int yday, int wday) -> int
|
||||
{
|
||||
return yday - (wday + 382) % 7 + 3;
|
||||
};
|
||||
|
||||
int year = timeptr->tm_year + 1900;
|
||||
int days = iso_week_days(timeptr->tm_yday, timeptr->tm_wday);
|
||||
|
||||
if (days < 0)
|
||||
{
|
||||
year--;
|
||||
days = iso_week_days(timeptr->tm_yday + (365 + is_leap_year(year)), timeptr->tm_wday);
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = iso_week_days(timeptr->tm_yday - (365 + is_leap_year(year)), timeptr->tm_wday);
|
||||
if (d >= 0)
|
||||
{
|
||||
year++;
|
||||
days = d;
|
||||
}
|
||||
}
|
||||
|
||||
switch (*format)
|
||||
{
|
||||
case 'g':
|
||||
if (!append_value("%02d", ((year % 100) + 100) % 100))
|
||||
return 0;
|
||||
break;
|
||||
case 'G':
|
||||
{
|
||||
if (conversion.flag == '\0')
|
||||
conversion.flag = ' ';
|
||||
if (conversion.flag == '+' && conversion.width <= 4)
|
||||
conversion.flag = '0';
|
||||
if (conversion.width == -1)
|
||||
conversion.width = 0;
|
||||
|
||||
char new_format[32];
|
||||
sprintf(new_format, "%%%c%dd", conversion.flag, conversion.width);
|
||||
if (!append_value(new_format, year))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case 'V':
|
||||
if (!append_value("%02d", days / 7 + 1))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w':
|
||||
if (!append_value("%d", timeptr->tm_wday))
|
||||
return 0;
|
||||
break;
|
||||
case 'W':
|
||||
if (!append_value("%02d", (timeptr->tm_yday - (timeptr->tm_wday - 1 + 7) % 7 + 7) / 7))
|
||||
return 0;
|
||||
break;
|
||||
case 'x':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%m/%d/%y", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'X':
|
||||
if (size_t ret = strftime(s + len, maxsize - len, "%H:%M:%S", timeptr))
|
||||
len += ret;
|
||||
else return 0;
|
||||
break;
|
||||
case 'y':
|
||||
if (!append_value("%d", timeptr->tm_yday % 100))
|
||||
return 0;
|
||||
break;
|
||||
case 'Y':
|
||||
{
|
||||
if (conversion.flag == '\0')
|
||||
conversion.flag = ' ';
|
||||
if (conversion.flag == '+' && conversion.width <= 4)
|
||||
conversion.flag = '0';
|
||||
if (conversion.width == -1)
|
||||
conversion.width = 0;
|
||||
|
||||
char new_format[32];
|
||||
sprintf(new_format, "%%%c%dd", conversion.flag, conversion.width);
|
||||
if (!append_value(new_format, 1900 + timeptr->tm_year))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case 'z':
|
||||
// FIXME: support timezones
|
||||
break;
|
||||
case 'Z':
|
||||
// FIXME: support timezones
|
||||
break;
|
||||
case '%':
|
||||
s[len++] = '%';
|
||||
break;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
|
||||
if (*format != '\0')
|
||||
return 0;
|
||||
s[len++] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <BAN/Assert.h>
|
||||
#include <BAN/Debug.h>
|
||||
#include <kernel/Syscall.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -280,6 +282,14 @@ unsigned int sleep(unsigned int seconds)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int usleep(useconds_t usec)
|
||||
{
|
||||
timespec ts;
|
||||
ts.tv_sec = usec / 1'000'000;
|
||||
ts.tv_nsec = (usec % 1'000'000) * 1000;
|
||||
return nanosleep(&ts, nullptr);
|
||||
}
|
||||
|
||||
char* getcwd(char* buf, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
|
@ -526,3 +536,9 @@ unsigned alarm(unsigned seconds)
|
|||
setitimer(ITIMER_REAL, &value, &ovalue);
|
||||
return ovalue.it_value.tv_sec;
|
||||
}
|
||||
|
||||
int symlink(const char* path1, const char* path2)
|
||||
{
|
||||
dwarnln("FIXME: symlink({}, {})", path1, path2);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue