Files
TransPyC/includes/posix.py

266 lines
10 KiB
Python
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 wont repeat it here.
# =============================================================================
DIR: t.CTypedef = t.CVoid | 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)
# =============================================================================
def open(path: t.CConst | str, oflag: INT, *args) -> INT | t.State: pass
def close(fd: INT) -> INT | t.State: pass
def read(fd: INT, buf: bytes, count: t.CSizeT) -> ssize_t | t.State: pass
def write(fd: INT, buf: t.CConst | bytes, count: t.CSizeT) -> ssize_t | t.State: pass
def lseek(fd: INT, offset: off_t, whence: INT) -> off_t | t.State: pass
def unlink(path: t.CConst | str) -> INT | t.State: pass
def access(path: t.CConst | str, amode: INT) -> INT | t.State: pass
def realpath(path: t.CConst | str, resolved: CHARPTR) -> CHARPTR | t.State: pass
def rename(oldpath: t.CConst | str, newpath: t.CConst | str) -> INT | t.State: pass
def chmod(path: t.CConst | str, mode: mode_t) -> INT | t.State: pass
# =============================================================================
# stat series (2)
# =============================================================================
def stat(path: t.CConst | str, buf: Stat | t.CPtr) -> INT | t.State: pass
def fstat(fd: INT, buf: Stat | t.CPtr) -> INT | t.State: pass
# =============================================================================
# Directory operations (6)
# =============================================================================
def opendir(name: t.CConst | str) -> DIR | t.CPtr | t.State: pass
def readdir(dirp: DIR | t.CPtr) -> Dirent | t.CPtr | t.State: pass
def closedir(dirp: DIR | t.CPtr) -> INT | t.State: pass
def mkdir(path: t.CConst | str, mode: mode_t) -> INT | t.State: pass
def rmdir(path: t.CConst | str) -> INT | t.State: pass
def getcwd(buf: CHARPTR, size: t.CSizeT) -> CHARPTR | t.State: pass
def chdir(path: t.CConst | str) -> INT | t.State: pass
# =============================================================================
# Process operations (8)
# =============================================================================
def fork() -> pid_t | t.State: pass
def execvp(file: t.CConst | str, argv: CHARPTR | t.CPtr) -> INT | t.State: pass
def execv(path: t.CConst | str, argv: CHARPTR | t.CPtr) -> INT | t.State: pass
def waitpid(pid: pid_t, status: INT | t.CPtr, options: INT) -> pid_t | t.State: pass
def pipe(fds: INT | t.CPtr) -> INT | t.State: pass
def dup2(oldfd: INT, newfd: INT) -> INT | t.State: pass
def _exit(status: INT) -> t.CVoid | t.State: pass
def getpid() -> pid_t | t.State: pass
# =============================================================================
# Environment operations (4)
# =============================================================================
def getenv(name: t.CConst | str) -> CHARPTR | t.State: pass
def setenv(name: t.CConst | str, value: t.CConst | str, overwrite: INT) -> INT | t.State: pass
def sysconf(name: INT) -> LONG | t.State: pass
def isatty(fd: INT) -> INT | t.State: pass
# =============================================================================
# Inline macros (C macros, implemented as normal functions, not marked as t.CExtern)
# =============================================================================
# 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