diff options
Diffstat (limited to 'cpu/sysdeps/unix/sysv/linux')
45 files changed, 2117 insertions, 0 deletions
diff --git a/cpu/sysdeps/unix/sysv/linux/i386/i686/README b/cpu/sysdeps/unix/sysv/linux/i386/i686/README new file mode 100644 index 0000000..f00b0cb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/i386/i686/README @@ -0,0 +1,2 @@ +This directory is part of the LibMCPU HOST sysdeps inheritance tree. +HOST-dependent syscall wrappers will be added here in later releases. diff --git a/cpu/sysdeps/unix/sysv/linux/i386/i786/Implies b/cpu/sysdeps/unix/sysv/linux/i386/i786/Implies new file mode 100644 index 0000000..7cb7d9a --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/i386/i786/Implies @@ -0,0 +1,2 @@ +# The PPro and PII cores are mostly the same. +unix/sysv/linux/i386/i686 diff --git a/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc32/README b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc32/README new file mode 100644 index 0000000..f00b0cb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc32/README @@ -0,0 +1,2 @@ +This directory is part of the LibMCPU HOST sysdeps inheritance tree. +HOST-dependent syscall wrappers will be added here in later releases. diff --git a/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64/README b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64/README new file mode 100644 index 0000000..f00b0cb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64/README @@ -0,0 +1,2 @@ +This directory is part of the LibMCPU HOST sysdeps inheritance tree. +HOST-dependent syscall wrappers will be added here in later releases. diff --git a/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64le/README b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64le/README new file mode 100644 index 0000000..f00b0cb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/powerpc/powerpc64le/README @@ -0,0 +1,2 @@ +This directory is part of the LibMCPU HOST sysdeps inheritance tree. +HOST-dependent syscall wrappers will be added here in later releases. diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/README b/cpu/sysdeps/unix/sysv/linux/x86_64/64/README new file mode 100644 index 0000000..c28377c --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/README @@ -0,0 +1,8 @@ +Linux/x86_64/LP64 HOST sysdeps +============================== + +This directory contains the selected low-level syscall adapters for the +currently supported Linux/x86_64 LP64 HOST profile. The common UNIX errno +translator is inherited from `cpu/sysdeps/unix/sys-errno.c`; all real HOST +failures are translated to stable MCPU errno values before control returns to +the common CPU layer. diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-chown-linux.h b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-chown-linux.h new file mode 100644 index 0000000..7b39ae4 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-chown-linux.h @@ -0,0 +1,66 @@ +/*************************************************************** + CPU-CHOWN-LINUX.H + + This file contains Linux/x86_64/LP64 conversion helpers + for MCPU uid/gid values -> HOST uid_t/gid_t. + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifndef __CPU_CHOWN_LINUX_H +#define __CPU_CHOWN_LINUX_H + +#include <errno.h> +#include <sys/types.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_uid_to_host( __mpu_uint64_t uid, uid_t *host_uid ) +{ + uid_t u; + + if( !host_uid ) return( __MCPU_EINVAL ); + if( uid == __CPU_ID_NO_CHANGE ) + { + *host_uid = (uid_t)-1; + return( 0 ); + } + + u = (uid_t)uid; + if( (__mpu_uint64_t)u != uid ) return( __MCPU_EOVERFLOW ); + + *host_uid = u; + return( 0 ); + +} /* End of __cpu_uid_to_host() */ + + +static int +__cpu_gid_to_host( __mpu_uint64_t gid, gid_t *host_gid ) +{ + gid_t g; + + if( !host_gid ) return( __MCPU_EINVAL ); + if( gid == __CPU_ID_NO_CHANGE ) + { + *host_gid = (gid_t)-1; + return( 0 ); + } + + g = (gid_t)gid; + if( (__mpu_uint64_t)g != gid ) return( __MCPU_EOVERFLOW ); + + *host_gid = g; + return( 0 ); + +} /* End of __cpu_gid_to_host() */ + +#endif /* __CPU_CHOWN_LINUX_H */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-mode-linux.h b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-mode-linux.h new file mode 100644 index 0000000..a68e50c --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-mode-linux.h @@ -0,0 +1,53 @@ +/*************************************************************** + CPU-MODE-LINUX.H + + This file contains Linux/x86_64/LP64 conversion helper + for MCPU permission bits -> HOST mode_t. + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifndef __CPU_MODE_LINUX_H +#define __CPU_MODE_LINUX_H + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_mode_to_host( __mpu_uint64_t mode, mode_t *host_mode ) +{ + mode_t m = 0; + + if( !host_mode ) return( __MCPU_EINVAL ); + if( mode & ~(__mpu_uint64_t)__CPU_S_SUPPORTED ) return( __MCPU_EINVAL ); + + if( mode & __CPU_S_ISUID ) m |= S_ISUID; + if( mode & __CPU_S_ISGID ) m |= S_ISGID; +#ifdef S_ISVTX + if( mode & __CPU_S_ISVTX ) m |= S_ISVTX; +#endif + if( mode & __CPU_S_IRUSR ) m |= S_IRUSR; + if( mode & __CPU_S_IWUSR ) m |= S_IWUSR; + if( mode & __CPU_S_IXUSR ) m |= S_IXUSR; + if( mode & __CPU_S_IRGRP ) m |= S_IRGRP; + if( mode & __CPU_S_IWGRP ) m |= S_IWGRP; + if( mode & __CPU_S_IXGRP ) m |= S_IXGRP; + if( mode & __CPU_S_IROTH ) m |= S_IROTH; + if( mode & __CPU_S_IWOTH ) m |= S_IWOTH; + if( mode & __CPU_S_IXOTH ) m |= S_IXOTH; + + *host_mode = m; + return( 0 ); + +} /* End of __cpu_mode_to_host() */ + +#endif /* __CPU_MODE_LINUX_H */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-stat-linux.h b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-stat-linux.h new file mode 100644 index 0000000..58ac956 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-stat-linux.h @@ -0,0 +1,124 @@ +/*************************************************************** + CPU-STAT-LINUX.H + + This file contains Linux/x86_64/LP64 conversion helpers + for the HOST struct stat -> MCPU struct __cpu_stat ABI. + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifndef __CPU_STAT_LINUX_H +#define __CPU_STAT_LINUX_H + +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_stat_mode( mode_t mode, __mpu_uint64_t *out ) +{ + __mpu_uint64_t m = 0; + + if( !out ) return( __MCPU_EFAULT ); + + switch( mode & S_IFMT ) + { + case S_IFIFO: m |= __CPU_S_IFIFO; break; + case S_IFCHR: m |= __CPU_S_IFCHR; break; + case S_IFDIR: m |= __CPU_S_IFDIR; break; + case S_IFBLK: m |= __CPU_S_IFBLK; break; + case S_IFREG: m |= __CPU_S_IFREG; break; + case S_IFLNK: m |= __CPU_S_IFLNK; break; +#ifdef S_IFSOCK + case S_IFSOCK: m |= __CPU_S_IFSOCK; break; +#endif + default: return( __MCPU_EOVERFLOW ); + } + + if( mode & S_ISUID ) m |= __CPU_S_ISUID; + if( mode & S_ISGID ) m |= __CPU_S_ISGID; +#ifdef S_ISVTX + if( mode & S_ISVTX ) m |= __CPU_S_ISVTX; +#endif + if( mode & S_IRUSR ) m |= __CPU_S_IRUSR; + if( mode & S_IWUSR ) m |= __CPU_S_IWUSR; + if( mode & S_IXUSR ) m |= __CPU_S_IXUSR; + if( mode & S_IRGRP ) m |= __CPU_S_IRGRP; + if( mode & S_IWGRP ) m |= __CPU_S_IWGRP; + if( mode & S_IXGRP ) m |= __CPU_S_IXGRP; + if( mode & S_IROTH ) m |= __CPU_S_IROTH; + if( mode & S_IWOTH ) m |= __CPU_S_IWOTH; + if( mode & S_IXOTH ) m |= __CPU_S_IXOTH; + + *out = m; + return( 0 ); + +} /* End of __cpu_stat_mode() */ + + +static int +__cpu_stat_from_host( struct __cpu_stat *dst, const struct stat *src ) +{ + int error; + + if( !dst || !src ) return( __MCPU_EFAULT ); + + dst->st_dev = (__mpu_uint64_t)src->st_dev; + if( (dev_t)dst->st_dev != src->st_dev ) return( __MCPU_EOVERFLOW ); + + dst->st_ino = (__mpu_uint64_t)src->st_ino; + if( (ino_t)dst->st_ino != src->st_ino ) return( __MCPU_EOVERFLOW ); + + error = __cpu_stat_mode( src->st_mode, &dst->st_mode ); + if( error ) return( error ); + + dst->st_nlink = (__mpu_uint64_t)src->st_nlink; + if( (nlink_t)dst->st_nlink != src->st_nlink ) return( __MCPU_EOVERFLOW ); + + dst->st_uid = (__mpu_uint64_t)src->st_uid; + if( (uid_t)dst->st_uid != src->st_uid ) return( __MCPU_EOVERFLOW ); + + dst->st_gid = (__mpu_uint64_t)src->st_gid; + if( (gid_t)dst->st_gid != src->st_gid ) return( __MCPU_EOVERFLOW ); + + dst->st_rdev = (__mpu_uint64_t)src->st_rdev; + if( (dev_t)dst->st_rdev != src->st_rdev ) return( __MCPU_EOVERFLOW ); + + dst->st_size = (__mpu_int64_t)src->st_size; + if( (off_t)dst->st_size != src->st_size ) return( __MCPU_EOVERFLOW ); + + dst->st_blksize = (__mpu_int64_t)src->st_blksize; + if( (blksize_t)dst->st_blksize != src->st_blksize ) return( __MCPU_EOVERFLOW ); + + dst->st_blocks = (__mpu_int64_t)src->st_blocks; + if( (blkcnt_t)dst->st_blocks != src->st_blocks ) return( __MCPU_EOVERFLOW ); + + dst->st_atime_sec = (__mpu_int64_t)src->st_atim.tv_sec; + if( (time_t)dst->st_atime_sec != src->st_atim.tv_sec ) return( __MCPU_EOVERFLOW ); + if( src->st_atim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW ); + dst->st_atime_nsec = (__mpu_uint64_t)src->st_atim.tv_nsec; + + dst->st_mtime_sec = (__mpu_int64_t)src->st_mtim.tv_sec; + if( (time_t)dst->st_mtime_sec != src->st_mtim.tv_sec ) return( __MCPU_EOVERFLOW ); + if( src->st_mtim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW ); + dst->st_mtime_nsec = (__mpu_uint64_t)src->st_mtim.tv_nsec; + + dst->st_ctime_sec = (__mpu_int64_t)src->st_ctim.tv_sec; + if( (time_t)dst->st_ctime_sec != src->st_ctim.tv_sec ) return( __MCPU_EOVERFLOW ); + if( src->st_ctim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW ); + dst->st_ctime_nsec = (__mpu_uint64_t)src->st_ctim.tv_nsec; + + return( 0 ); + +} /* End of __cpu_stat_from_host() */ + +#endif /* __CPU_STAT_LINUX_H */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-time-linux.h b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-time-linux.h new file mode 100644 index 0000000..8bdda84 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/cpu-time-linux.h @@ -0,0 +1,64 @@ +/*************************************************************** + CPU-TIME-LINUX.H + + Linux/x86_64/LP64 conversion helpers for the MCPU time ABI. + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifndef __CPU_TIME_LINUX_H +#define __CPU_TIME_LINUX_H + +#include <errno.h> +#include <time.h> + + +static int +__cpu_clockid_to_host( __mpu_uint64_t clockid, clockid_t *host_clockid ) +{ + if( !host_clockid ) return( __MCPU_EFAULT ); + + switch( clockid ) + { + case __CPU_CLOCK_REALTIME: + *host_clockid = CLOCK_REALTIME; + return( 0 ); + case __CPU_CLOCK_MONOTONIC: + *host_clockid = CLOCK_MONOTONIC; + return( 0 ); + default: + return( __MCPU_EINVAL ); + } + +} /* End of __cpu_clockid_to_host() */ + + +static int +__cpu_timespec_from_host( struct __cpu_timespec *dst, + const struct timespec *src ) +{ + __mpu_int64_t sec; + __mpu_int64_t nsec; + + if( !dst || !src ) return( __MCPU_EFAULT ); + + sec = (__mpu_int64_t)src->tv_sec; + if( (time_t)sec != src->tv_sec ) return( __MCPU_EOVERFLOW ); + + nsec = (__mpu_int64_t)src->tv_nsec; + if( (long)nsec != src->tv_nsec ) return( __MCPU_EOVERFLOW ); + if( nsec < 0 || nsec > 999999999 ) return( __MCPU_EOVERFLOW ); + + dst->tv_sec = sec; + dst->tv_nsec = nsec; + + return( 0 ); + +} /* End of __cpu_timespec_from_host() */ + +#endif /* __CPU_TIME_LINUX_H */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-access.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-access.c new file mode 100644 index 0000000..5bb9a45 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-access.c @@ -0,0 +1,42 @@ +/*************************************************************** + SYS-ACCESS.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_access(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_access( int dirfd, const char *path, __mpu_uint64_t mode ) +{ + int host_mode = 0; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + if( mode & ~(__mpu_uint64_t)__CPU_ACCESS_SUPPORTED ) + return( -(__mpu_int64_t)__MCPU_EINVAL ); + + if( mode & __CPU_R_OK ) host_mode |= R_OK; + if( mode & __CPU_W_OK ) host_mode |= W_OK; + if( mode & __CPU_X_OK ) host_mode |= X_OK; + + if( faccessat( dirfd, path, host_mode, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_access() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chdir.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chdir.c new file mode 100644 index 0000000..c6da354 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chdir.c @@ -0,0 +1,53 @@ +/*************************************************************** + SYS-CHDIR.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_cwd_init() and __cpu_sys_chdir(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static __mpu_int64_t +__cpu_open_directory( int dirfd, const char *path ) +{ + int fd; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + fd = openat( dirfd, path, O_PATH | O_DIRECTORY | O_CLOEXEC ); + if( fd < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)fd ); + +} /* End of __cpu_open_directory() */ + + +__mpu_int64_t +__cpu_sys_cwd_init( void ) +{ + return( __cpu_open_directory( AT_FDCWD, "." ) ); + +} /* End of __cpu_sys_cwd_init() */ + + +__mpu_int64_t +__cpu_sys_chdir( int dirfd, const char *path ) +{ + return( __cpu_open_directory( dirfd, path ) ); + +} /* End of __cpu_sys_chdir() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chmod.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chmod.c new file mode 100644 index 0000000..6719bf7 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chmod.c @@ -0,0 +1,41 @@ +/*************************************************************** + SYS-CHMOD.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_chmod(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-mode-linux.h" + + +__mpu_int64_t +__cpu_sys_chmod( int dirfd, const char *path, __mpu_uint64_t mode ) +{ + mode_t host_mode; + int error; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_mode_to_host( mode, &host_mode ); + if( error ) return( -(__mpu_int64_t)error ); + + if( fchmodat( dirfd, path, host_mode, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_chmod() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chown.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chown.c new file mode 100644 index 0000000..42e748e --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-chown.c @@ -0,0 +1,45 @@ +/*************************************************************** + SYS-CHOWN.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_chown(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-chown-linux.h" + + +__mpu_int64_t +__cpu_sys_chown( int dirfd, const char *path, __mpu_uint64_t uid, + __mpu_uint64_t gid ) +{ + uid_t host_uid; + gid_t host_gid; + int error; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_uid_to_host( uid, &host_uid ); + if( error ) return( -(__mpu_int64_t)error ); + error = __cpu_gid_to_host( gid, &host_gid ); + if( error ) return( -(__mpu_int64_t)error ); + + if( fchownat( dirfd, path, host_uid, host_gid, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_chown() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_getres.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_getres.c new file mode 100644 index 0000000..d156d61 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_getres.c @@ -0,0 +1,48 @@ +/*************************************************************** + SYS-CLOCK_GETRES.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_clock_getres(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <time.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-time-linux.h" + + +__mpu_int64_t +__cpu_sys_clock_getres( __mpu_uint64_t clockid, struct __cpu_timespec *res ) +{ + struct timespec ts; + clockid_t host_clockid; + int error; + + error = __cpu_clockid_to_host( clockid, &host_clockid ); + if( error ) return( -(__mpu_int64_t)error ); + + if( clock_getres( host_clockid, res ? &ts : (struct timespec *)0 ) < 0 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + if( res ) + { + error = __cpu_timespec_from_host( res, &ts ); + if( error ) return( -(__mpu_int64_t)error ); + } + + return( 0 ); + +} /* End of __cpu_sys_clock_getres() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_gettime.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_gettime.c new file mode 100644 index 0000000..6e017fc --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_gettime.c @@ -0,0 +1,47 @@ +/*************************************************************** + SYS-CLOCK_GETTIME.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_clock_gettime(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <time.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-time-linux.h" + + +__mpu_int64_t +__cpu_sys_clock_gettime( __mpu_uint64_t clockid, struct __cpu_timespec *tp ) +{ + struct timespec ts; + clockid_t host_clockid; + int error; + + if( !tp ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_clockid_to_host( clockid, &host_clockid ); + if( error ) return( -(__mpu_int64_t)error ); + + if( clock_gettime( host_clockid, &ts ) < 0 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + error = __cpu_timespec_from_host( tp, &ts ); + if( error ) return( -(__mpu_int64_t)error ); + + return( 0 ); + +} /* End of __cpu_sys_clock_gettime() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_nanosleep.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_nanosleep.c new file mode 100644 index 0000000..8659441 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-clock_nanosleep.c @@ -0,0 +1,93 @@ +/*************************************************************** + SYS-CLOCK_NANOSLEEP.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_clock_nanosleep(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <time.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-time-linux.h" + + +static int +__cpu_timespec_to_host( struct timespec *dst, + const struct __cpu_timespec *src ) +{ + time_t sec; + long nsec; + + if( !dst || !src ) return( __MCPU_EFAULT ); + if( src->tv_sec < 0 || src->tv_nsec < 0 || src->tv_nsec > 999999999 ) + return( __MCPU_EINVAL ); + + sec = (time_t)src->tv_sec; + if( (__mpu_int64_t)sec != src->tv_sec ) return( __MCPU_EOVERFLOW ); + + nsec = (long)src->tv_nsec; + if( (__mpu_int64_t)nsec != src->tv_nsec ) return( __MCPU_EOVERFLOW ); + + dst->tv_sec = sec; + dst->tv_nsec = nsec; + + return( 0 ); + +} /* End of __cpu_timespec_to_host() */ + + +__mpu_int64_t +__cpu_sys_clock_nanosleep( __mpu_uint64_t clockid, __mpu_uint64_t flags, + const struct __cpu_timespec *req, + struct __cpu_timespec *rem ) +{ + struct timespec host_req; + struct timespec host_rem; + struct timespec *host_prem = (struct timespec *)0; + clockid_t host_clockid; + int host_flags = 0; + int ret; + int error; + + if( !req ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_clockid_to_host( clockid, &host_clockid ); + if( error ) return( -(__mpu_int64_t)error ); + + if( flags == __CPU_TIMER_ABSTIME ) + host_flags = TIMER_ABSTIME; + else if( flags != 0 ) + return( -(__mpu_int64_t)__MCPU_EINVAL ); + + error = __cpu_timespec_to_host( &host_req, req ); + if( error ) return( -(__mpu_int64_t)error ); + + if( !host_flags && rem ) host_prem = &host_rem; + + ret = clock_nanosleep( host_clockid, host_flags, &host_req, host_prem ); + if( ret != 0 ) + { + if( ret == EINTR && host_prem ) + { + error = __cpu_timespec_from_host( rem, &host_rem ); + if( error ) return( -(__mpu_int64_t)error ); + } + return( -(__mpu_int64_t)__cpu_errno_from_host( ret ) ); + } + + return( 0 ); + +} /* End of __cpu_sys_clock_nanosleep() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-close.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-close.c new file mode 100644 index 0000000..48aceed --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-close.c @@ -0,0 +1,16 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + +__mpu_int64_t +__cpu_sys_close( int fd ) +{ + if( close( fd ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); +} diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-creat.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-creat.c new file mode 100644 index 0000000..9bbccce --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-creat.c @@ -0,0 +1,30 @@ +/*************************************************************** + SYS-CREAT.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_creat(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_creat( int dirfd, const char *path, __mpu_uint64_t mode ) +{ + return( __cpu_sys_open( dirfd, path, + __CPU_O_WRONLY | __CPU_O_CREAT | __CPU_O_TRUNC, + mode ) ); + +} /* End of __cpu_sys_creat() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-dup.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-dup.c new file mode 100644 index 0000000..f140b69 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-dup.c @@ -0,0 +1,36 @@ +/*************************************************************** + SYS-DUP.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_dup(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_dup( int fd ) +{ + int ret; + + ret = dup( fd ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + return( (__mpu_int64_t)ret ); + +} /* End of __cpu_sys_dup() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchdir.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchdir.c new file mode 100644 index 0000000..3323975 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchdir.c @@ -0,0 +1,35 @@ +/*************************************************************** + SYS-FCHDIR.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fchdir(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_fchdir( int fd ) +{ + int cwd_fd; + + cwd_fd = openat( fd, ".", O_PATH | O_DIRECTORY | O_CLOEXEC ); + if( cwd_fd < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)cwd_fd ); + +} /* End of __cpu_sys_fchdir() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchmod.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchmod.c new file mode 100644 index 0000000..a4f90be --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchmod.c @@ -0,0 +1,39 @@ +/*************************************************************** + SYS-FCHMOD.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fchmod(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-mode-linux.h" + + +__mpu_int64_t +__cpu_sys_fchmod( int fd, __mpu_uint64_t mode ) +{ + mode_t host_mode; + int error; + + error = __cpu_mode_to_host( mode, &host_mode ); + if( error ) return( -(__mpu_int64_t)error ); + + if( fchmod( fd, host_mode ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_fchmod() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchown.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchown.c new file mode 100644 index 0000000..a3e793b --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fchown.c @@ -0,0 +1,42 @@ +/*************************************************************** + SYS-FCHOWN.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fchown(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-chown-linux.h" + + +__mpu_int64_t +__cpu_sys_fchown( int fd, __mpu_uint64_t uid, __mpu_uint64_t gid ) +{ + uid_t host_uid; + gid_t host_gid; + int error; + + error = __cpu_uid_to_host( uid, &host_uid ); + if( error ) return( -(__mpu_int64_t)error ); + error = __cpu_gid_to_host( gid, &host_gid ); + if( error ) return( -(__mpu_int64_t)error ); + + if( fchown( fd, host_uid, host_gid ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_fchown() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fcntl.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fcntl.c new file mode 100644 index 0000000..d04074e --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fcntl.c @@ -0,0 +1,115 @@ +/*************************************************************** + SYS-FCNTL.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fcntl(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_fcntl_getfl( int host_flags, __mpu_uint64_t *guest_flags ) +{ + __mpu_uint64_t flags = 0; + + if( !guest_flags ) return( __MCPU_EINVAL ); + + switch( host_flags & O_ACCMODE ) + { + case O_RDONLY: flags |= __CPU_O_RDONLY; break; + case O_WRONLY: flags |= __CPU_O_WRONLY; break; + case O_RDWR: flags |= __CPU_O_RDWR; break; + default: return( __MCPU_EINVAL ); + } + + if( host_flags & O_APPEND ) flags |= __CPU_O_APPEND; + if( host_flags & O_NONBLOCK ) flags |= __CPU_O_NONBLOCK; + + *guest_flags = flags; + return( 0 ); + +} /* End of __cpu_fcntl_getfl() */ + + +static int +__cpu_fcntl_setfl( __mpu_uint64_t guest_flags, int *host_flags ) +{ + int flags = 0; + + if( !host_flags ) return( __MCPU_EINVAL ); + if( guest_flags & ~(__mpu_uint64_t)__CPU_F_SETFL_SUPPORTED ) + return( __MCPU_EINVAL ); + + switch( guest_flags & __CPU_O_ACCMODE ) + { + case __CPU_O_RDONLY: + case __CPU_O_WRONLY: + case __CPU_O_RDWR: + break; + default: + return( __MCPU_EINVAL ); + } + + if( guest_flags & __CPU_O_APPEND ) flags |= O_APPEND; + if( guest_flags & __CPU_O_NONBLOCK ) flags |= O_NONBLOCK; + + *host_flags = flags; + return( 0 ); + +} /* End of __cpu_fcntl_setfl() */ + + +__mpu_int64_t +__cpu_sys_fcntl( int fd, __mpu_uint64_t cmd, __mpu_uint64_t arg ) +{ + __mpu_uint64_t guest_flags; + int host_flags; + int error; + int ret; + + switch( cmd ) + { + case __CPU_F_DUPFD: + if( arg != 0 ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + ret = fcntl( fd, F_DUPFD, 0 ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)ret ); + + case __CPU_F_GETFL: + if( arg != 0 ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + ret = fcntl( fd, F_GETFL ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + error = __cpu_fcntl_getfl( ret, &guest_flags ); + if( error ) return( -(__mpu_int64_t)error ); + return( (__mpu_int64_t)guest_flags ); + + case __CPU_F_SETFL: + error = __cpu_fcntl_setfl( arg, &host_flags ); + if( error ) return( -(__mpu_int64_t)error ); + + ret = fcntl( fd, F_SETFL, host_flags ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + + default: + return( -(__mpu_int64_t)__MCPU_EINVAL ); + } + +} /* End of __cpu_sys_fcntl() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fstat.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fstat.c new file mode 100644 index 0000000..53b0309 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fstat.c @@ -0,0 +1,43 @@ +/*************************************************************** + SYS-FSTAT.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fstat(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-stat-linux.h" + + +__mpu_int64_t +__cpu_sys_fstat( int fd, struct __cpu_stat *st ) +{ + struct stat host_st; + int error; + + if( fd < 0 ) return( -(__mpu_int64_t)__MCPU_EBADF ); + if( !st ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( fstat( fd, &host_st ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + error = __cpu_stat_from_host( st, &host_st ); + if( error ) return( -(__mpu_int64_t)error ); + + return( 0 ); + +} /* End of __cpu_sys_fstat() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fsync.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fsync.c new file mode 100644 index 0000000..3ba7e11 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-fsync.c @@ -0,0 +1,32 @@ +/*************************************************************** + SYS-FSYNC.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_fsync(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_fsync( int fd ) +{ + if( fsync( fd ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_fsync() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-ftruncate.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-ftruncate.c new file mode 100644 index 0000000..f5e55ad --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-ftruncate.c @@ -0,0 +1,39 @@ +/*************************************************************** + SYS-FTRUNCATE.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_ftruncate(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_ftruncate( int fd, __mpu_int64_t length ) +{ + off_t host_length; + + host_length = (off_t)length; + if( (__mpu_int64_t)host_length != length ) + return( -(__mpu_int64_t)__MCPU_EOVERFLOW ); + + if( ftruncate( fd, host_length ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_ftruncate() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-getdents.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-getdents.c new file mode 100644 index 0000000..6b8928c --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-getdents.c @@ -0,0 +1,227 @@ +/*************************************************************** + SYS-GETDENTS.C + + Linux/x86_64/LP64 implementation of __cpu_sys_getdents(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <dirent.h> +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + +#define __CPU_HOST_DIRENT_BUFFER 4096U + +struct __cpu_linux_dirent64 +{ + uint64_t d_ino; + int64_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[]; +}; + +static int +__cpu_dirent_utf8_valid( const unsigned char *s, size_t n ) +{ + size_t i = 0; + + while( i < n ) + { + unsigned int c = s[i++]; + + if( c < 0x80U ) continue; + if( c >= 0xc2U && c <= 0xdfU ) + { + if( i >= n || ( s[i] & 0xc0U ) != 0x80U ) return( 0 ); + ++i; continue; + } + if( c == 0xe0U ) + { + if( i + 1 >= n || s[i] < 0xa0U || s[i] > 0xbfU || + ( s[i + 1] & 0xc0U ) != 0x80U ) return( 0 ); + i += 2; continue; + } + if( c >= 0xe1U && c <= 0xecU ) + { + if( i + 1 >= n || ( s[i] & 0xc0U ) != 0x80U || + ( s[i + 1] & 0xc0U ) != 0x80U ) return( 0 ); + i += 2; continue; + } + if( c == 0xedU ) + { + if( i + 1 >= n || s[i] < 0x80U || s[i] > 0x9fU || + ( s[i + 1] & 0xc0U ) != 0x80U ) return( 0 ); + i += 2; continue; + } + if( c >= 0xeeU && c <= 0xefU ) + { + if( i + 1 >= n || ( s[i] & 0xc0U ) != 0x80U || + ( s[i + 1] & 0xc0U ) != 0x80U ) return( 0 ); + i += 2; continue; + } + if( c == 0xf0U ) + { + if( i + 2 >= n || s[i] < 0x90U || s[i] > 0xbfU || + ( s[i + 1] & 0xc0U ) != 0x80U || + ( s[i + 2] & 0xc0U ) != 0x80U ) return( 0 ); + i += 3; continue; + } + if( c >= 0xf1U && c <= 0xf3U ) + { + if( i + 2 >= n || ( s[i] & 0xc0U ) != 0x80U || + ( s[i + 1] & 0xc0U ) != 0x80U || + ( s[i + 2] & 0xc0U ) != 0x80U ) return( 0 ); + i += 3; continue; + } + if( c == 0xf4U ) + { + if( i + 2 >= n || s[i] < 0x80U || s[i] > 0x8fU || + ( s[i + 1] & 0xc0U ) != 0x80U || + ( s[i + 2] & 0xc0U ) != 0x80U ) return( 0 ); + i += 3; continue; + } + return( 0 ); + } + return( 1 ); +} + +static __mpu_uint64_t +__cpu_dirent_type( unsigned char type ) +{ + switch( type ) + { +#ifdef DT_FIFO + case DT_FIFO: return( __CPU_DT_FIFO ); +#endif +#ifdef DT_CHR + case DT_CHR: return( __CPU_DT_CHR ); +#endif +#ifdef DT_DIR + case DT_DIR: return( __CPU_DT_DIR ); +#endif +#ifdef DT_BLK + case DT_BLK: return( __CPU_DT_BLK ); +#endif +#ifdef DT_REG + case DT_REG: return( __CPU_DT_REG ); +#endif +#ifdef DT_LNK + case DT_LNK: return( __CPU_DT_LNK ); +#endif +#ifdef DT_SOCK + case DT_SOCK: return( __CPU_DT_SOCK ); +#endif + default: return( __CPU_DT_UNKNOWN ); + } +} + +__mpu_int64_t +__cpu_sys_getdents( int fd, struct __cpu_dirent *dirp, __mpu_uint64_t count ) +{ + unsigned char hostbuf[__CPU_HOST_DIRENT_BUFFER]; + struct stat st; + off_t start; + off_t resume; + ssize_t nread; + size_t pos = 0; + size_t nrecords = 0; + size_t maxrecords; + + if( !dirp ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + if( count < __CPU_DIRENT_SIZE ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + + maxrecords = (size_t)( count / __CPU_DIRENT_SIZE ); + + if( fstat( fd, &st ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + if( !S_ISDIR( st.st_mode ) ) return( -(__mpu_int64_t)__MCPU_ENOTDIR ); + + start = lseek( fd, (off_t)0, SEEK_CUR ); + if( start == (off_t)-1 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + resume = start; + + nread = syscall( SYS_getdents64, fd, hostbuf, sizeof( hostbuf ) ); + if( nread < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + if( nread == 0 ) return( 0 ); + + while( pos < (size_t)nread ) + { + struct __cpu_linux_dirent64 *de; + const char *nul; + size_t namespace; + size_t namelen; + + if( (size_t)nread - pos < offsetof( struct __cpu_linux_dirent64, d_name ) + 1U ) + goto malformed; + + de = (struct __cpu_linux_dirent64 *)( hostbuf + pos ); + if( de->d_reclen < offsetof( struct __cpu_linux_dirent64, d_name ) + 1U || + de->d_reclen > (size_t)nread - pos ) goto malformed; + + if( nrecords >= maxrecords ) break; + + namespace = de->d_reclen - offsetof( struct __cpu_linux_dirent64, d_name ); + nul = (const char *)memchr( de->d_name, '\0', namespace ); + if( !nul ) goto malformed; + namelen = (size_t)( nul - de->d_name ); + + if( namelen >= __CPU_DIRENT_NAME_SIZE ) + { + if( lseek( fd, resume, SEEK_SET ) == (off_t)-1 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( nrecords ? (__mpu_int64_t)( nrecords * __CPU_DIRENT_SIZE ) + : -(__mpu_int64_t)__MCPU_ENAMETOOLONG ); + } + + if( !__cpu_dirent_utf8_valid( (const unsigned char *)de->d_name, namelen ) ) + { + if( lseek( fd, resume, SEEK_SET ) == (off_t)-1 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( nrecords ? (__mpu_int64_t)( nrecords * __CPU_DIRENT_SIZE ) + : -(__mpu_int64_t)__MCPU_EILSEQ ); + } + + dirp[nrecords].d_ino = (__mpu_uint64_t)de->d_ino; + dirp[nrecords].d_off = (__mpu_int64_t)de->d_off; + dirp[nrecords].d_reclen = __CPU_DIRENT_SIZE; + dirp[nrecords].d_type = __cpu_dirent_type( de->d_type ); + memset( dirp[nrecords].d_name, 0, __CPU_DIRENT_NAME_SIZE ); + memcpy( dirp[nrecords].d_name, de->d_name, namelen ); + + resume = (off_t)de->d_off; + ++nrecords; + pos += de->d_reclen; + } + + if( pos < (size_t)nread ) + { + if( lseek( fd, resume, SEEK_SET ) == (off_t)-1 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + } + + return( (__mpu_int64_t)( nrecords * __CPU_DIRENT_SIZE ) ); + +malformed: + if( lseek( fd, start, SEEK_SET ) == (off_t)-1 ) + return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( -(__mpu_int64_t)__MCPU_EIO ); + +} /* End of __cpu_sys_getdents() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-link.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-link.c new file mode 100644 index 0000000..fd19f0d --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-link.c @@ -0,0 +1,34 @@ +/*************************************************************** + SYS-LINK.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_link(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_link( int dirfd, const char *oldpath, const char *newpath ) +{ + if( !oldpath || !newpath ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( linkat( dirfd, oldpath, dirfd, newpath, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_link() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lseek.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lseek.c new file mode 100644 index 0000000..0de650e --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lseek.c @@ -0,0 +1,35 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <limits.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + +__mpu_int64_t +__cpu_sys_lseek( int fd, __mpu_int64_t offset, __mpu_uint64_t whence ) +{ + off_t host_offset; + off_t ret; + int host_whence; + + switch( whence ) + { + case __CPU_SEEK_SET: host_whence = SEEK_SET; break; + case __CPU_SEEK_CUR: host_whence = SEEK_CUR; break; + case __CPU_SEEK_END: host_whence = SEEK_END; break; + default: return( -(__mpu_int64_t)__MCPU_EINVAL ); + } + + host_offset = (off_t)offset; + if( (__mpu_int64_t)host_offset != offset ) return( -(__mpu_int64_t)__MCPU_EOVERFLOW ); + + ret = lseek( fd, host_offset, host_whence ); + if( ret == (off_t)-1 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + if( (off_t)(__mpu_int64_t)ret != ret ) return( -(__mpu_int64_t)__MCPU_EOVERFLOW ); + return( (__mpu_int64_t)ret ); +} diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lstat.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lstat.c new file mode 100644 index 0000000..3ea9353 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-lstat.c @@ -0,0 +1,43 @@ +/*************************************************************** + SYS-LSTAT.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_lstat(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-stat-linux.h" + + +__mpu_int64_t +__cpu_sys_lstat( int dirfd, const char *path, struct __cpu_stat *st ) +{ + struct stat host_st; + int error; + + if( !path || !st ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( fstatat( dirfd, path, &host_st, AT_SYMLINK_NOFOLLOW ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + error = __cpu_stat_from_host( st, &host_st ); + if( error ) return( -(__mpu_int64_t)error ); + + return( 0 ); + +} /* End of __cpu_sys_lstat() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-mkdir.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-mkdir.c new file mode 100644 index 0000000..76ced3a --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-mkdir.c @@ -0,0 +1,69 @@ +/*************************************************************** + SYS-MKDIR.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_mkdir(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_mkdir_mode( __mpu_uint64_t mode, mode_t *host_mode ) +{ + mode_t m = 0; + + if( !host_mode ) return( __MCPU_EINVAL ); + if( mode & ~(__mpu_uint64_t)__CPU_S_SUPPORTED ) return( __MCPU_EINVAL ); + + if( mode & __CPU_S_ISUID ) m |= S_ISUID; + if( mode & __CPU_S_ISGID ) m |= S_ISGID; +#ifdef S_ISVTX + if( mode & __CPU_S_ISVTX ) m |= S_ISVTX; +#endif + if( mode & __CPU_S_IRUSR ) m |= S_IRUSR; + if( mode & __CPU_S_IWUSR ) m |= S_IWUSR; + if( mode & __CPU_S_IXUSR ) m |= S_IXUSR; + if( mode & __CPU_S_IRGRP ) m |= S_IRGRP; + if( mode & __CPU_S_IWGRP ) m |= S_IWGRP; + if( mode & __CPU_S_IXGRP ) m |= S_IXGRP; + if( mode & __CPU_S_IROTH ) m |= S_IROTH; + if( mode & __CPU_S_IWOTH ) m |= S_IWOTH; + if( mode & __CPU_S_IXOTH ) m |= S_IXOTH; + + *host_mode = m; + return( 0 ); + +} /* End of __cpu_mkdir_mode() */ + + +__mpu_int64_t +__cpu_sys_mkdir( int dirfd, const char *path, __mpu_uint64_t mode ) +{ + mode_t host_mode; + int error; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_mkdir_mode( mode, &host_mode ); + if( error ) return( -(__mpu_int64_t)error ); + + if( mkdirat( dirfd, path, host_mode ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_mkdir() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-open.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-open.c new file mode 100644 index 0000000..36a9994 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-open.c @@ -0,0 +1,114 @@ +/*************************************************************** + SYS-OPEN.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_open(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +static int +__cpu_open_flags( __mpu_uint64_t flags, int *host_flags ) +{ + int f = 0; + + if( !host_flags ) return( __MCPU_EINVAL ); + if( flags & ~(__mpu_uint64_t)__CPU_O_SUPPORTED ) return( __MCPU_EINVAL ); + + switch( flags & __CPU_O_ACCMODE ) + { + case __CPU_O_RDONLY: f |= O_RDONLY; break; + case __CPU_O_WRONLY: f |= O_WRONLY; break; + case __CPU_O_RDWR: f |= O_RDWR; break; + default: return( __MCPU_EINVAL ); + } + + if( flags & __CPU_O_CREAT ) f |= O_CREAT; + if( flags & __CPU_O_EXCL ) f |= O_EXCL; + if( flags & __CPU_O_NOCTTY ) f |= O_NOCTTY; + if( flags & __CPU_O_TRUNC ) f |= O_TRUNC; + if( flags & __CPU_O_APPEND ) f |= O_APPEND; + if( flags & __CPU_O_NONBLOCK ) f |= O_NONBLOCK; + + *host_flags = f; + return( 0 ); + +} /* End of __cpu_open_flags() */ + + +static int +__cpu_open_mode( __mpu_uint64_t mode, mode_t *host_mode ) +{ + mode_t m = 0; + + if( !host_mode ) return( __MCPU_EINVAL ); + if( mode & ~(__mpu_uint64_t)__CPU_S_SUPPORTED ) return( __MCPU_EINVAL ); + + if( mode & __CPU_S_ISUID ) m |= S_ISUID; + if( mode & __CPU_S_ISGID ) m |= S_ISGID; +#ifdef S_ISVTX + if( mode & __CPU_S_ISVTX ) m |= S_ISVTX; +#endif + if( mode & __CPU_S_IRUSR ) m |= S_IRUSR; + if( mode & __CPU_S_IWUSR ) m |= S_IWUSR; + if( mode & __CPU_S_IXUSR ) m |= S_IXUSR; + if( mode & __CPU_S_IRGRP ) m |= S_IRGRP; + if( mode & __CPU_S_IWGRP ) m |= S_IWGRP; + if( mode & __CPU_S_IXGRP ) m |= S_IXGRP; + if( mode & __CPU_S_IROTH ) m |= S_IROTH; + if( mode & __CPU_S_IWOTH ) m |= S_IWOTH; + if( mode & __CPU_S_IXOTH ) m |= S_IXOTH; + + *host_mode = m; + return( 0 ); + +} /* End of __cpu_open_mode() */ + + +__mpu_int64_t +__cpu_sys_open( int dirfd, const char *path, __mpu_uint64_t flags, + __mpu_uint64_t mode ) +{ + mode_t host_mode = 0; + int host_flags; + int error; + int fd; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + error = __cpu_open_flags( flags, &host_flags ); + if( error ) return( -(__mpu_int64_t)error ); + + if( flags & __CPU_O_CREAT ) + { + error = __cpu_open_mode( mode, &host_mode ); + if( error ) return( -(__mpu_int64_t)error ); + fd = openat( dirfd, path, host_flags, host_mode ); + } + else + { + if( mode != 0 ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + fd = openat( dirfd, path, host_flags ); + } + + if( fd < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)fd ); + +} /* End of __cpu_sys_open() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-pipe2.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-pipe2.c new file mode 100644 index 0000000..bb211a2 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-pipe2.c @@ -0,0 +1,44 @@ +/*************************************************************** + SYS-PIPE2.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_pipe2(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_pipe2( int pipefd[2], __mpu_uint64_t flags ) +{ + int host_flags = 0; + int ret; + + if( !pipefd ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + if( flags & ~(__mpu_uint64_t)__CPU_O_NONBLOCK ) + return( -(__mpu_int64_t)__MCPU_EINVAL ); + + if( flags & __CPU_O_NONBLOCK ) host_flags |= O_NONBLOCK; + + ret = pipe2( pipefd, host_flags ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + return( 0 ); + +} /* End of __cpu_sys_pipe2() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-read.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-read.c new file mode 100644 index 0000000..4816d37 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-read.c @@ -0,0 +1,21 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + +__mpu_int64_t +__cpu_sys_read( int fd, void *buf, __mpu_uint64_t count ) +{ + ssize_t ret; + + if( count > (__mpu_uint64_t)SIZE_MAX ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + ret = read( fd, buf, (size_t)count ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)ret ); +} diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-readlink.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-readlink.c new file mode 100644 index 0000000..bda2a47 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-readlink.c @@ -0,0 +1,40 @@ +/*************************************************************** + SYS-READLINK.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_readlink(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_readlink( int dirfd, const char *path, void *buf, + __mpu_uint64_t count ) +{ + ssize_t ret; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + if( count > (__mpu_uint64_t)SIZE_MAX ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + + ret = readlinkat( dirfd, path, (char *)buf, (size_t)count ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)ret ); + +} /* End of __cpu_sys_readlink() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rename.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rename.c new file mode 100644 index 0000000..d79b3fb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rename.c @@ -0,0 +1,34 @@ +/*************************************************************** + SYS-RENAME.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_rename(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdio.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_rename( int dirfd, const char *oldpath, const char *newpath ) +{ + if( !oldpath || !newpath ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( renameat( dirfd, oldpath, dirfd, newpath ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_rename() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rmdir.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rmdir.c new file mode 100644 index 0000000..41ee0c2 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-rmdir.c @@ -0,0 +1,35 @@ +/*************************************************************** + SYS-RMDIR.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_rmdir(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_rmdir( int dirfd, const char *path ) +{ + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( unlinkat( dirfd, path, AT_REMOVEDIR ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_rmdir() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-select.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-select.c new file mode 100644 index 0000000..a87d138 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-select.c @@ -0,0 +1,109 @@ +/*************************************************************** + SYS-SELECT.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_select(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <poll.h> +#include <signal.h> +#include <stdlib.h> +#include <time.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_select( struct __cpu_select_entry *entries, __mpu_uint64_t count, + const struct __cpu_timeval *timeout ) +{ + struct pollfd *pfds = (struct pollfd *)0; + struct timespec ts; + struct timespec *pts = (struct timespec *)0; + __mpu_uint64_t i; + time_t sec; + int ret; + + if( count && !entries ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + if( count > (__mpu_uint64_t)(size_t)-1 / sizeof( *pfds ) ) + return( -(__mpu_int64_t)__MCPU_EINVAL ); + + if( timeout ) + { + if( timeout->tv_sec < 0 || timeout->tv_usec < 0 || timeout->tv_usec > 999999 ) + return( -(__mpu_int64_t)__MCPU_EINVAL ); + + sec = (time_t)timeout->tv_sec; + if( (__mpu_int64_t)sec != timeout->tv_sec ) + return( -(__mpu_int64_t)__MCPU_EOVERFLOW ); + + ts.tv_sec = sec; + ts.tv_nsec = (long)( timeout->tv_usec * 1000 ); + pts = &ts; + } + + if( count ) + { + pfds = (struct pollfd *)calloc( (size_t)count, sizeof( *pfds ) ); + if( !pfds ) return( -(__mpu_int64_t)__MCPU_ENOMEM ); + } + + for( i = 0; i < count; ++i ) + { + pfds[i].fd = entries[i].host_fd; + pfds[i].events = 0; + pfds[i].revents = 0; + entries[i].revents = 0; + + if( entries[i].events & __CPU_SELECT_READ ) pfds[i].events |= POLLIN; + if( entries[i].events & __CPU_SELECT_WRITE ) pfds[i].events |= POLLOUT; + if( entries[i].events & __CPU_SELECT_EXCEPT ) pfds[i].events |= POLLPRI; + } + + ret = ppoll( pfds, (nfds_t)count, pts, (const sigset_t *)0 ); + if( ret < 0 ) + { + ret = -(__mpu_int64_t)__cpu_errno_from_host( errno ); + free( pfds ); + return( (__mpu_int64_t)ret ); + } + + for( i = 0; i < count; ++i ) + { + short revents = pfds[i].revents; + + if( revents & POLLNVAL ) + { + free( pfds ); + return( -(__mpu_int64_t)__MCPU_EBADF ); + } + + if( ( entries[i].events & __CPU_SELECT_READ ) && + ( revents & ( POLLIN | POLLHUP | POLLERR ) ) ) + entries[i].revents |= __CPU_SELECT_READ; + + if( ( entries[i].events & __CPU_SELECT_WRITE ) && + ( revents & ( POLLOUT | POLLERR ) ) ) + entries[i].revents |= __CPU_SELECT_WRITE; + + if( ( entries[i].events & __CPU_SELECT_EXCEPT ) && ( revents & POLLPRI ) ) + entries[i].revents |= __CPU_SELECT_EXCEPT; + } + + free( pfds ); + return( 0 ); + +} /* End of __cpu_sys_select() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-stat.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-stat.c new file mode 100644 index 0000000..bb3a154 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-stat.c @@ -0,0 +1,42 @@ +/*************************************************************** + SYS-STAT.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_stat(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/stat.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> +#include "cpu-stat-linux.h" + + +__mpu_int64_t +__cpu_sys_stat( int dirfd, const char *path, struct __cpu_stat *st ) +{ + struct stat host_st; + int error; + + if( !path || !st ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( fstatat( dirfd, path, &host_st, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + error = __cpu_stat_from_host( st, &host_st ); + if( error ) return( -(__mpu_int64_t)error ); + + return( 0 ); + +} /* End of __cpu_sys_stat() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-symlink.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-symlink.c new file mode 100644 index 0000000..276a277 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-symlink.c @@ -0,0 +1,34 @@ +/*************************************************************** + SYS-SYMLINK.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_symlink(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_symlink( int dirfd, const char *target, const char *linkpath ) +{ + if( !target || !linkpath ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( symlinkat( target, dirfd, linkpath ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_symlink() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-truncate.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-truncate.c new file mode 100644 index 0000000..4a34b44 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-truncate.c @@ -0,0 +1,58 @@ +/*************************************************************** + SYS-TRUNCATE.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_truncate(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_truncate( int dirfd, const char *path, __mpu_int64_t length ) +{ + off_t host_length; + + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + host_length = (off_t)length; + if( (__mpu_int64_t)host_length != length ) + return( -(__mpu_int64_t)__MCPU_EOVERFLOW ); + + { + int fd; + int error; + + fd = openat( dirfd, path, O_WRONLY | O_CLOEXEC ); + if( fd < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + + if( ftruncate( fd, host_length ) < 0 ) + { + error = errno; + (void)close( fd ); + return( -(__mpu_int64_t)__cpu_errno_from_host( error ) ); + } + + (void)close( fd ); + } + + return( 0 ); + +} /* End of __cpu_sys_truncate() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-unlink.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-unlink.c new file mode 100644 index 0000000..155dc79 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-unlink.c @@ -0,0 +1,34 @@ +/*************************************************************** + SYS-UNLINK.C + + This file contains Linux/x86_64/LP64 implementation of + __cpu_sys_unlink(). + + PART OF : CPU - library . + + USAGE : Internal only . + + Copyright (C) 2026 by Andrew V.Kosteltsev. + All Rights Reserved. + ***************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + + +__mpu_int64_t +__cpu_sys_unlink( int dirfd, const char *path ) +{ + if( !path ) return( -(__mpu_int64_t)__MCPU_EFAULT ); + + if( unlinkat( dirfd, path, 0 ) < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( 0 ); + +} /* End of __cpu_sys_unlink() */ diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-write.c b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-write.c new file mode 100644 index 0000000..e5398c7 --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/64/sys-write.c @@ -0,0 +1,21 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <unistd.h> + +#include <libmcpu.h> +#include <cpu-sysdeps.h> + +__mpu_int64_t +__cpu_sys_write( int fd, const void *buf, __mpu_uint64_t count ) +{ + ssize_t ret; + + if( count > (__mpu_uint64_t)SIZE_MAX ) return( -(__mpu_int64_t)__MCPU_EINVAL ); + ret = write( fd, buf, (size_t)count ); + if( ret < 0 ) return( -(__mpu_int64_t)__cpu_errno_from_host( errno ) ); + return( (__mpu_int64_t)ret ); +} diff --git a/cpu/sysdeps/unix/sysv/linux/x86_64/x32/README b/cpu/sysdeps/unix/sysv/linux/x86_64/x32/README new file mode 100644 index 0000000..f00b0cb --- /dev/null +++ b/cpu/sysdeps/unix/sysv/linux/x86_64/x32/README @@ -0,0 +1,2 @@ +This directory is part of the LibMCPU HOST sysdeps inheritance tree. +HOST-dependent syscall wrappers will be added here in later releases. |
