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 = uint32 # File mode/permission bits pid_t: t.CTypedef = int32 # Process ID off_t: t.CTypedef = int64 # File offset (Linux x86_64) dev_t: t.CTypedef = uint64 # Device number ino_t: t.CTypedef = uint64 # inode number nlink_t: t.CTypedef = uint64 # Hard link count uid_t: t.CTypedef = uint32 # User ID gid_t: t.CTypedef = uint32 # Group ID blksize_t: t.CTypedef = int64 # File I/O block size blkcnt_t: t.CTypedef = int64 # Allocated block count time_t: t.CTypedef = int64 # Calendar time seconds # ============================================================================= # open() Flags # ============================================================================= define O_RDONLY = 0 define O_WRONLY = 1 define O_RDWR = 2 define O_CREAT = 0o100 define O_EXCL = 0o200 define O_TRUNC = 0o1000 define O_APPEND = 0o2000 define O_NONBLOCK = 0o4000 define O_CLOEXEC = 0o2000000 # ============================================================================= # access() Test Flags # ============================================================================= define F_OK = 0 # File exists define R_OK = 4 # Read permission define W_OK = 2 # Write permission define X_OK = 1 # Execute permission # ============================================================================= # stat struct st_mode Mask and Type Bits # ============================================================================= define S_IFMT = 0o170000 # Type mask bits define S_IFSOCK = 0o140000 # Socket define S_IFLNK = 0o120000 # Symbolic link define S_IFREG = 0o100000 # Regular file define S_IFBLK = 0o060000 # Block device define S_IFDIR = 0o040000 # Directory define S_IFCHR = 0o020000 # Character device define S_IFIFO = 0o010000 # FIFO/pipe # Permission Bits define S_ISUID = 0o4000 # Set-user-ID define S_ISGID = 0o2000 # Set-group-ID define S_ISVTX = 0o1000 # Sticky bit define S_IRWXU = 0o700 # Read/write/execute permission define S_IRUSR = 0o400 # User read permission define S_IWUSR = 0o200 # User write permission define S_IXUSR = 0o100 # User execute permission define S_IRWXG = 0o070 # Read/write/execute permission define S_IRGRP = 0o040 # Read permission define S_IWGRP = 0o020 # Write define S_IXGRP = 0o010 # Execute define S_IRWXO = 0o007 # Read/write/execute permission define S_IROTH = 0o004 # Other read permission define S_IWOTH = 0o002 # Other write permission define S_IXOTH = 0o001 # Other execute permission # ============================================================================= # lseek() whence values # ============================================================================= define SEEK_SET = 0 define SEEK_CUR = 1 define SEEK_END = 2 # ============================================================================= # Path/name length limits # ============================================================================= define PATH_MAX = 4096 define NAME_MAX = 255 # ============================================================================= # sysconf() parameters # ============================================================================= define _SC_NPROCESSORS_ONLN = 84 define _SC_PAGESIZE = 30 define _SC_CLK_TCK = 2 # ============================================================================= # dirent struct d_type values # ============================================================================= define DT_UNKNOWN = 0 define DT_FIFO = 1 define DT_CHR = 2 define DT_DIR = 4 define DT_BLK = 6 define DT_REG = 8 define DT_LNK = 10 define DT_SOCK = 12 define DT_WHT = 14 # ============================================================================= # waitpid() options # ============================================================================= define WNOHANG = 1 define WUNTRACED = 2 define WCONTINUED = 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: const str, oflag: INT, *args) -> INT extern def close(fd: INT) -> INT extern def read(fd: INT, buf: bytes, count: sizet) -> ssize_t extern def write(fd: INT, buf: const bytes, count: sizet) -> ssize_t extern def lseek(fd: INT, offset: off_t, whence: INT) -> off_t extern def unlink(path: const str) -> INT extern def access(path: const str, amode: INT) -> INT extern def realpath(path: const str, resolved: CHARPTR) -> CHARPTR extern def rename(oldpath: const str, newpath: const str) -> INT extern def chmod(path: const str, mode: mode_t) -> INT # ============================================================================= # stat series (2) # ============================================================================= extern def stat(path: const str, buf: Stat*) -> INT extern def fstat(fd: INT, buf: Stat*) -> INT # ============================================================================= # Directory operations (6) # ============================================================================= extern def opendir(name: const str) -> DIR extern def readdir(dirp: DIR) -> Dirent* extern def closedir(dirp: DIR) -> INT extern def mkdir(path: const str, mode: mode_t) -> INT extern def rmdir(path: const str) -> INT extern def getcwd(buf: CHARPTR, size: sizet) -> CHARPTR extern def chdir(path: const str) -> INT # ============================================================================= # Process operations (8) # ============================================================================= extern def fork() -> pid_t extern def execvp(file: const str, argv: CHARPTR*) -> INT extern def execv(path: const str, argv: CHARPTR*) -> INT extern def waitpid(pid: pid_t, status: INT*, options: INT) -> pid_t extern def pipe(fds: INT*) -> 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: const str) -> CHARPTR extern def setenv(name: const str, value: const 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