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.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