Module rsyscall.sys.stat

#include <sys/socket.h>

Expand source code Browse git
"`#include <sys/socket.h>`"
from __future__ import annotations
from dataclasses import dataclass
from rsyscall._raw import lib, ffi # type: ignore
from rsyscall.handle.fd import BaseFileDescriptor
from rsyscall.handle.pointer import Pointer
from rsyscall.near.sysif import SyscallInterface
from rsyscall.struct import Struct, Serializable
from rsyscall.sys.syscall import SYS
from rsyscall.time import Timespec
import enum
import rsyscall.near.types as near
import typing as t

class S_IF(enum.IntEnum):
    SOCK = lib.S_IFSOCK
    LNK = lib.S_IFLNK
    REG = lib.S_IFREG
    BLK = lib.S_IFBLK
    DIR = lib.S_IFDIR
    CHR = lib.S_IFCHR
    IFO = lib.S_IFIFO
    # mask with all set
    MT = lib.S_IFMT

class Mode(int):
    def __repr__(self) -> str:
        return oct(self)

    def __str__(self) -> str:
        return repr(self)

@dataclass
class TypeMode:
    # should change this to DT I guess?
    # maybe have an as_dt?
    type: S_IF
    mode: Mode

    @staticmethod
    def from_int(val: int) -> TypeMode:
        type_bits = val & S_IF.MT
        return TypeMode(S_IF(type_bits), Mode(val ^ type_bits))

    def __int__(self) -> int:
        return self.type | self.mode

@dataclass
class Stat(Struct):
    dev: int
    ino: int
    mode: TypeMode
    nlink: int
    uid: int
    gid: int
    rdev: int
    size: int
    blksize: int
    blocks: int
    atime: Timespec
    mtime: Timespec
    ctime: Timespec

    def to_bytes(self) -> bytes:
        return bytes(ffi.buffer(ffi.new('struct stat const*', {
            "st_dev": self.dev,
            "st_ino": self.ino,
            "st_nlink": self.nlink,
            "st_mode": self.mode,
            "st_uid": self.uid,
            "st_gid": self.gid,
            "st_rdev": self.rdev,
            "st_size": self.size,
            "st_blksize": self.blksize,
            "st_blocks": self.blocks,
            "st_atim": self.atime._to_cffi_dict(),
            "st_mtim": self.mtime._to_cffi_dict(),
            "st_ctim": self.ctime._to_cffi_dict(),
        })))

    @property
    def atim(self) -> Timespec:
        return self.atime

    @property
    def mtim(self) -> Timespec:
        return self.mtime

    @property
    def ctim(self) -> Timespec:
        return self.ctime

    T = t.TypeVar('T', bound='Stat')
    @classmethod
    def from_bytes(cls: t.Type[T], data: bytes) -> T:
        struct = ffi.cast('struct stat*', ffi.from_buffer(data))
        return cls(
            dev=struct.st_dev,
            ino=struct.st_ino,
            mode=struct.st_mode,
            nlink=struct.st_nlink,
            uid=struct.st_uid,
            gid=struct.st_gid,
            rdev=struct.st_rdev,
            size=struct.st_size,
            blksize=struct.st_blksize,
            blocks=struct.st_blocks,
            atime=Timespec.from_cffi(struct.st_atim),
            mtime=Timespec.from_cffi(struct.st_mtim),
            ctime=Timespec.from_cffi(struct.st_ctim),
        )

    @classmethod
    def sizeof(cls) -> int:
        return ffi.sizeof('struct stat')

async def _fstat(sysif: SyscallInterface, fd: near.FileDescriptor, statbuf: near.Address) -> None:
    await sysif.syscall(SYS.fstat, fd, statbuf)

class StatFileDescriptor(BaseFileDescriptor):
    async def fstat(self, statbuf: Pointer[Stat]) -> Pointer[Stat]:
        self._validate()
        with statbuf.borrow(self.task):
            await _fstat(self.task.sysif, self.near, statbuf.near)
        return statbuf
    

#### Tests ####
from unittest import TestCase
class TestStat(TestCase):
    def test_stat(self) -> None:
        initial = Stat(
            dev=0,
            ino=0,
            mode=TypeMode(S_IF.REG, Mode(0o777)),
            nlink=0,
            uid=0,
            gid=0,
            rdev=0,
            size=0,
            blksize=0,
            blocks=0,
            atime=Timespec(sec=0, nsec=0),
            mtime=Timespec(sec=0, nsec=0),
            ctime=Timespec(sec=0, nsec=0),
        )
        output = Stat.from_bytes(initial.to_bytes())
        self.assertEqual(initial, output)

Classes

class S_IF (value, names=None, *, module=None, qualname=None, type=None, start=1)

An enumeration.

Expand source code Browse git
class S_IF(enum.IntEnum):
    SOCK = lib.S_IFSOCK
    LNK = lib.S_IFLNK
    REG = lib.S_IFREG
    BLK = lib.S_IFBLK
    DIR = lib.S_IFDIR
    CHR = lib.S_IFCHR
    IFO = lib.S_IFIFO
    # mask with all set
    MT = lib.S_IFMT

Ancestors

  • enum.IntEnum
  • builtins.int
  • enum.Enum

Class variables

var SOCK
var LNK
var REG
var BLK
var DIR
var CHR
var IFO
var MT
class Mode (...)

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

>>> int('0b100', base=0)
4
Expand source code Browse git
class Mode(int):
    def __repr__(self) -> str:
        return oct(self)

    def __str__(self) -> str:
        return repr(self)

Ancestors

  • builtins.int
class TypeMode (type: S_IF, mode: Mode)

TypeMode(type: 'S_IF', mode: 'Mode')

Expand source code Browse git
@dataclass
class TypeMode:
    # should change this to DT I guess?
    # maybe have an as_dt?
    type: S_IF
    mode: Mode

    @staticmethod
    def from_int(val: int) -> TypeMode:
        type_bits = val & S_IF.MT
        return TypeMode(S_IF(type_bits), Mode(val ^ type_bits))

    def __int__(self) -> int:
        return self.type | self.mode

Class variables

var typeS_IF
var modeMode

Static methods

def from_int(val: int) ‑> TypeMode
Expand source code Browse git
@staticmethod
def from_int(val: int) -> TypeMode:
    type_bits = val & S_IF.MT
    return TypeMode(S_IF(type_bits), Mode(val ^ type_bits))
class Stat (dev: int, ino: int, mode: TypeMode, nlink: int, uid: int, gid: int, rdev: int, size: int, blksize: int, blocks: int, atime: Timespec, mtime: Timespec, ctime: Timespec)

Stat(dev: 'int', ino: 'int', mode: 'TypeMode', nlink: 'int', uid: 'int', gid: 'int', rdev: 'int', size: 'int', blksize: 'int', blocks: 'int', atime: 'Timespec', mtime: 'Timespec', ctime: 'Timespec')

Expand source code Browse git
@dataclass
class Stat(Struct):
    dev: int
    ino: int
    mode: TypeMode
    nlink: int
    uid: int
    gid: int
    rdev: int
    size: int
    blksize: int
    blocks: int
    atime: Timespec
    mtime: Timespec
    ctime: Timespec

    def to_bytes(self) -> bytes:
        return bytes(ffi.buffer(ffi.new('struct stat const*', {
            "st_dev": self.dev,
            "st_ino": self.ino,
            "st_nlink": self.nlink,
            "st_mode": self.mode,
            "st_uid": self.uid,
            "st_gid": self.gid,
            "st_rdev": self.rdev,
            "st_size": self.size,
            "st_blksize": self.blksize,
            "st_blocks": self.blocks,
            "st_atim": self.atime._to_cffi_dict(),
            "st_mtim": self.mtime._to_cffi_dict(),
            "st_ctim": self.ctime._to_cffi_dict(),
        })))

    @property
    def atim(self) -> Timespec:
        return self.atime

    @property
    def mtim(self) -> Timespec:
        return self.mtime

    @property
    def ctim(self) -> Timespec:
        return self.ctime

    T = t.TypeVar('T', bound='Stat')
    @classmethod
    def from_bytes(cls: t.Type[T], data: bytes) -> T:
        struct = ffi.cast('struct stat*', ffi.from_buffer(data))
        return cls(
            dev=struct.st_dev,
            ino=struct.st_ino,
            mode=struct.st_mode,
            nlink=struct.st_nlink,
            uid=struct.st_uid,
            gid=struct.st_gid,
            rdev=struct.st_rdev,
            size=struct.st_size,
            blksize=struct.st_blksize,
            blocks=struct.st_blocks,
            atime=Timespec.from_cffi(struct.st_atim),
            mtime=Timespec.from_cffi(struct.st_mtim),
            ctime=Timespec.from_cffi(struct.st_ctim),
        )

    @classmethod
    def sizeof(cls) -> int:
        return ffi.sizeof('struct stat')

Ancestors

Class variables

var dev : int
var ino : int
var modeTypeMode
var uid : int
var gid : int
var rdev : int
var size : int
var blksize : int
var blocks : int
var atimeTimespec
var mtimeTimespec
var ctimeTimespec
var T

Instance variables

var atimTimespec
Expand source code Browse git
@property
def atim(self) -> Timespec:
    return self.atime
var mtimTimespec
Expand source code Browse git
@property
def mtim(self) -> Timespec:
    return self.mtime
var ctimTimespec
Expand source code Browse git
@property
def ctim(self) -> Timespec:
    return self.ctime

Inherited members

class StatFileDescriptor (task: FileDescriptorTask, near: FileDescriptor, valid: bool)

A file descriptor accessed through some Task

This is an rsyscall-internal base class, which other FileDescriptor objects inherit from for core lifecycle methods. See FileDescriptor for more information.

Expand source code Browse git
class StatFileDescriptor(BaseFileDescriptor):
    async def fstat(self, statbuf: Pointer[Stat]) -> Pointer[Stat]:
        self._validate()
        with statbuf.borrow(self.task):
            await _fstat(self.task.sysif, self.near, statbuf.near)
        return statbuf

Ancestors

Subclasses

Methods

async def fstat(self, statbuf: Pointer[Stat]) ‑> Pointer[Stat]
Expand source code Browse git
async def fstat(self, statbuf: Pointer[Stat]) -> Pointer[Stat]:
    self._validate()
    with statbuf.borrow(self.task):
        await _fstat(self.task.sysif, self.near, statbuf.near)
    return statbuf

Inherited members

class TestStat (methodName='runTest')

A class whose instances are single test cases.

By default, the test code itself should be placed in a method named 'runTest'.

If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, specify in the constructor arguments the name of the test method that the instance is to execute.

Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.

If it is necessary to override the init method, the base class init method must always be called. It is important that subclasses should not change the signature of their init method, since instances of the classes are instantiated automatically by parts of the framework in order to be run.

When subclassing TestCase, you can set these attributes: * failureException: determines which exception will be raised when the instance's assertion methods fail; test methods raising this exception will be deemed to have 'failed' rather than 'errored'. * longMessage: determines whether long messages (including repr of objects used in assert methods) will be printed on failure in addition to any explicit message passed. * maxDiff: sets the maximum length of a diff in failure messages by assert methods using difflib. It is looked up as an instance attribute so can be configured by individual tests if required.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

Expand source code Browse git
class TestStat(TestCase):
    def test_stat(self) -> None:
        initial = Stat(
            dev=0,
            ino=0,
            mode=TypeMode(S_IF.REG, Mode(0o777)),
            nlink=0,
            uid=0,
            gid=0,
            rdev=0,
            size=0,
            blksize=0,
            blocks=0,
            atime=Timespec(sec=0, nsec=0),
            mtime=Timespec(sec=0, nsec=0),
            ctime=Timespec(sec=0, nsec=0),
        )
        output = Stat.from_bytes(initial.to_bytes())
        self.assertEqual(initial, output)

Ancestors

  • unittest.case.TestCase

Methods

def test_stat(self) ‑> NoneType
Expand source code Browse git
def test_stat(self) -> None:
    initial = Stat(
        dev=0,
        ino=0,
        mode=TypeMode(S_IF.REG, Mode(0o777)),
        nlink=0,
        uid=0,
        gid=0,
        rdev=0,
        size=0,
        blksize=0,
        blocks=0,
        atime=Timespec(sec=0, nsec=0),
        mtime=Timespec(sec=0, nsec=0),
        ctime=Timespec(sec=0, nsec=0),
    )
    output = Stat.from_bytes(initial.to_bytes())
    self.assertEqual(initial, output)