Files
Viper_VRTE/posix.vp
T
2026-09-16 16:07:35 +08:00

265 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import t, c
from stdint import *
# =============================================================================
# POSIX Type Alias
# Note: ssize_t has already been defined as t.CPtrDiffT in stdint.py, so we won’t repeat it here.
# =============================================================================
DIR: t.CTypedef = t.CPtr # Opaque directory stream handle
mode_t: t.CTypedef = t.CUInt32T # File mode/permission bits
pid_t: t.CTypedef = t.CInt32T # Process ID
off_t: t.CTypedef = t.CInt64T # File offset (Linux x86_64)
dev_t: t.CTypedef = t.CUInt64T # Device number
ino_t: t.CTypedef = t.CUInt64T # inode number
nlink_t: t.CTypedef = t.CUInt64T # Hard link count
uid_t: t.CTypedef = t.CUInt32T # User ID
gid_t: t.CTypedef = t.CUInt32T # Group ID
blksize_t: t.CTypedef = t.CInt64T # File I/O block size
blkcnt_t: t.CTypedef = t.CInt64T # Allocated block count
time_t: t.CTypedef = t.CInt64T # Calendar time seconds
# =============================================================================
# open() Flags
# =============================================================================
O_RDONLY: t.CDefine = 0
O_WRONLY: t.CDefine = 1
O_RDWR: t.CDefine = 2
O_CREAT: t.CDefine = 0o100
O_EXCL: t.CDefine = 0o200
O_TRUNC: t.CDefine = 0o1000
O_APPEND: t.CDefine = 0o2000
O_NONBLOCK: t.CDefine = 0o4000
O_CLOEXEC: t.CDefine = 0o2000000
# =============================================================================
# access() Test Flags
# =============================================================================
F_OK: t.CDefine = 0 # File exists
R_OK: t.CDefine = 4 # Read permission
W_OK: t.CDefine = 2 # Write permission
X_OK: t.CDefine = 1 # Execute permission
# =============================================================================
# stat struct st_mode Mask and Type Bits
# =============================================================================
S_IFMT: t.CDefine = 0o170000 # Type mask bits
S_IFSOCK: t.CDefine = 0o140000 # Socket
S_IFLNK: t.CDefine = 0o120000 # Symbolic link
S_IFREG: t.CDefine = 0o100000 # Regular file
S_IFBLK: t.CDefine = 0o060000 # Block device
S_IFDIR: t.CDefine = 0o040000 # Directory
S_IFCHR: t.CDefine = 0o020000 # Character device
S_IFIFO: t.CDefine = 0o010000 # FIFO/pipe
# Permission Bits
S_ISUID: t.CDefine = 0o4000 # Set-user-ID
S_ISGID: t.CDefine = 0o2000 # Set-group-ID
S_ISVTX: t.CDefine = 0o1000 # Sticky bit
S_IRWXU: t.CDefine = 0o700 # Read/write/execute permission
S_IRUSR: t.CDefine = 0o400 # User read permission
S_IWUSR: t.CDefine = 0o200 # User write permission
S_IXUSR: t.CDefine = 0o100 # User execute permission
S_IRWXG: t.CDefine = 0o070 # Read/write/execute permission
S_IRGRP: t.CDefine = 0o040 # Read permission
S_IWGRP: t.CDefine = 0o020 # Write
S_IXGRP: t.CDefine = 0o010 # Execute
S_IRWXO: t.CDefine = 0o007 # Read/write/execute permission
S_IROTH: t.CDefine = 0o004 # Other read permission
S_IWOTH: t.CDefine = 0o002 # Other write permission
S_IXOTH: t.CDefine = 0o001 # Other execute permission
# =============================================================================
# lseek() whence values
# =============================================================================
SEEK_SET: t.CDefine = 0
SEEK_CUR: t.CDefine = 1
SEEK_END: t.CDefine = 2
# =============================================================================
# Path/name length limits
# =============================================================================
PATH_MAX: t.CDefine = 4096
NAME_MAX: t.CDefine = 255
# =============================================================================
# sysconf() parameters
# =============================================================================
_SC_NPROCESSORS_ONLN: t.CDefine = 84
_SC_PAGESIZE: t.CDefine = 30
_SC_CLK_TCK: t.CDefine = 2
# =============================================================================
# dirent struct d_type values
# =============================================================================
DT_UNKNOWN: t.CDefine = 0
DT_FIFO: t.CDefine = 1
DT_CHR: t.CDefine = 2
DT_DIR: t.CDefine = 4
DT_BLK: t.CDefine = 6
DT_REG: t.CDefine = 8
DT_LNK: t.CDefine = 10
DT_SOCK: t.CDefine = 12
DT_WHT: t.CDefine = 14
# =============================================================================
# waitpid() options
# =============================================================================
WNOHANG: t.CDefine = 1
WUNTRACED: t.CDefine = 2
WCONTINUED: t.CDefine = 8
# =============================================================================
# Struct: Linux x86_64 Layout
# =============================================================================
# struct stat (144 bytes, Linux x86_64 glibc layout)
# Note: st_atim/st_mtim/st_ctim in C are struct timespec { tv_sec; tv_nsec; }
# Here split into _sec/_nsec two LONGLONG fields to maintain binary compatibility
class Stat():
st_dev: dev_t # @ 0
st_ino: ino_t # @ 8
st_nlink: nlink_t # @ 16
st_mode: mode_t # @ 24
st_uid: uid_t # @ 28
st_gid: gid_t # @ 32
__pad0: INT # @ 36
st_rdev: dev_t # @ 40
st_size: off_t # @ 48
st_blksize: blksize_t # @ 56
st_blocks: blkcnt_t # @ 64
st_atim_sec: time_t # @ 72
st_atim_nsec: LONGLONG # @ 80
st_mtim_sec: time_t # @ 88
st_mtim_nsec: LONGLONG # @ 96
st_ctim_sec: time_t # @ 104
st_ctim_nsec: LONGLONG # @ 112
__unused0: LONGLONG # @ 120
__unused1: LONGLONG # @ 128
__unused2: LONGLONG # @ 136
# struct dirent (Linux x86_64, d_name is char[256])
# Note: d_name is actually a fixed-length char[256], TransPyC uses CHARPTR as a placeholder (8 bytes).
# Users usually access it via the read-only pointer returned by readdir, not by directly allocating a Dirent structure.
class Dirent():
d_ino: ino_t # @ 0
d_off: off_t # @ 8
d_reclen: USHORT # @ 16
d_type: BYTE # @ 18
d_name: CHARPTR # @ 19 (actually char[256], this is a placeholder)
# =============================================================================
# File operations (10)
# =============================================================================
extern def open(path: t.CConst | str, oflag: INT, *args) -> INT
extern def close(fd: INT) -> INT
extern def read(fd: INT, buf: bytes, count: t.CSizeT) -> ssize_t
extern def write(fd: INT, buf: t.CConst | bytes, count: t.CSizeT) -> ssize_t
extern def lseek(fd: INT, offset: off_t, whence: INT) -> off_t
extern def unlink(path: t.CConst | str) -> INT
extern def access(path: t.CConst | str, amode: INT) -> INT
extern def realpath(path: t.CConst | str, resolved: CHARPTR) -> CHARPTR
extern def rename(oldpath: t.CConst | str, newpath: t.CConst | str) -> INT
extern def chmod(path: t.CConst | str, mode: mode_t) -> INT
# =============================================================================
# stat series (2)
# =============================================================================
extern def stat(path: t.CConst | str, buf: Stat | t.CPtr) -> INT
extern def fstat(fd: INT, buf: Stat | t.CPtr) -> INT
# =============================================================================
# Directory operations (6)
# =============================================================================
extern def opendir(name: t.CConst | str) -> DIR | t.CPtr
extern def readdir(dirp: DIR | t.CPtr) -> Dirent | t.CPtr
extern def closedir(dirp: DIR | t.CPtr) -> INT
extern def mkdir(path: t.CConst | str, mode: mode_t) -> INT
extern def rmdir(path: t.CConst | str) -> INT
extern def getcwd(buf: CHARPTR, size: t.CSizeT) -> CHARPTR
extern def chdir(path: t.CConst | str) -> INT
# =============================================================================
# Process operations (8)
# =============================================================================
extern def fork() -> pid_t
extern def execvp(file: t.CConst | str, argv: CHARPTR | t.CPtr) -> INT
extern def execv(path: t.CConst | str, argv: CHARPTR | t.CPtr) -> INT
extern def waitpid(pid: pid_t, status: INT | t.CPtr, options: INT) -> pid_t
extern def pipe(fds: INT | t.CPtr) -> INT
extern def dup2(oldfd: INT, newfd: INT) -> INT
extern def _exit(status: INT)
extern def getpid() -> pid_t
# =============================================================================
# Environment operations (4)
# =============================================================================
extern def getenv(name: t.CConst | str) -> CHARPTR
extern def setenv(name: t.CConst | str, value: t.CConst | str, overwrite: INT) -> INT
extern def sysconf(name: INT) -> LONG
extern def isatty(fd: INT) -> INT
# =============================================================================
# Inline macros (C macros, implemented as normal functions, not marked as extern)
# =============================================================================
# st_mode type determination
def S_ISREG(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFREG
def S_ISDIR(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFDIR
def S_ISLNK(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFLNK
def S_ISCHR(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFCHR
def S_ISBLK(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFBLK
def S_ISFIFO(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFIFO
def S_ISSOCK(mode: mode_t) -> bool:
return (mode & S_IFMT) == S_IFSOCK
# waitpid status parsing
def WIFEXITED(status: INT) -> bool:
return (status & 0x7F) == 0
def WEXITSTATUS(status: INT) -> INT:
return (status >> 8) & 0xFF
def WIFSIGNALED(status: INT) -> bool:
return ((status & 0x7F) != 0) and ((status & 0x7F) != 0x7F)
def WTERMSIG(status: INT) -> INT:
return status & 0x7F