示例#1
0
文件: socket.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     # As with to_bytes, we can't just cast the bytes to a struct sockaddr_storage and read its data field,
     # because that would pad the data with a bunch of null bytes,
     # and would not preserve the length of the valid data
     family = ffi.cast('sa_family_t*', ffi.from_buffer(data))
     rest = data[ffi.sizeof('sa_family_t'):]
     return cls(family=AF(family[0]), data=rest)
示例#2
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     if len(data) < cls.sizeof():
         raise Exception("data too small", data)
     struct = ffi.cast('struct sockaddr_in*', ffi.from_buffer(data))
     cls.check_family(AF(struct.sin_family))
     return cls(socket.ntohs(struct.sin_port),
                socket.ntohl(struct.sin_addr.s_addr))
示例#3
0
 def from_bytes(self, data: bytes) -> Sockbuf[T]:
     struct = ffi.cast('socklen_t*', ffi.from_buffer(data))
     socklen = struct[0]
     if socklen > self.buf.size():
         raise Exception("not enough buffer space to read socket, need", socklen)
     valid, rest = self.buf.split(socklen)
     return Sockbuf(valid, rest)
示例#4
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T: # type: ignore
     family = ffi.cast('sa_family_t*', ffi.from_buffer(data))
     rest = data[ffi.sizeof('sa_family_t'):]
     return cls(
         family=AF(family[0]),
         data=rest
     )
示例#5
0
文件: socket.py 项目: gc-ss/rsyscall
    def from_bytes(self, data: bytes) -> T_socketpair:
        struct = ffi.cast('struct fdpair const*', ffi.from_buffer(data))

        def make(n: int) -> FileDescriptor:
            return self.task.make_fd_handle(near.FileDescriptor(int(n)))

        return self.cls(make(struct.first), make(struct.second))
示例#6
0
文件: in_.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     if len(data) < cls.sizeof():
         raise Exception("data too small", data)
     struct = ffi.cast('struct sockaddr_in6*', ffi.from_buffer(data))
     cls.check_family(AF(struct.sin6_family))
     return cls(socket.ntohs(struct.sin6_port), ipaddress.IPv6Address(bytes(struct.sin6_addr.s6_addr)),
                struct.sin6_flowinfo, struct.sin6_scope_id)
示例#7
0
文件: if_.py 项目: catern/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     if len(data) != cls.sizeof():
         raise Exception("data length", len(data),
                         "doesn't match actual length of struct ifreq", cls.sizeof())
     cffi = ffi.new('struct ifreq*')
     ffi.memmove(cffi, ffi.from_buffer(data), cls.sizeof())
     return cls(cffi=cffi)
示例#8
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('cpu_set_t*', ffi.from_buffer(data))
     ret: t.List[int] = []
     for i, val in enumerate(getattr(struct, '__bits')):
         inc = (64 * i)
         for bit in bits(val, one_indexed=False):
             ret.append(bit)
     return cls(ret)
示例#9
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_release_in*', ffi.from_buffer(data))
     return cls(
         fh=struct.fh,
         flags=O(struct.flags),
         release_flags=FUSE_RELEASE(struct.release_flags),
         lock_owner=struct.lock_owner,
     )
示例#10
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct siginfo const*', ffi.from_buffer(data))
     return cls(
         code=struct.si_code,
         pid=struct.si_pid,
         uid=struct.si_uid,
         status=struct.si_status,
     )
示例#11
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_getxattr_out*', ffi.from_buffer(data))
     variable = data[ffi.sizeof('struct fuse_getxattr_out'):]
     if len(variable) < struct.size:
         raise Exception("partial fuse_getxattr_out packet, received size",
                         len(variable), "expected size", struct.size)
     # -1 to strip null byte
     return cls(os.fsdecode(variable[:struct.size - 1]))
示例#12
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_out_header*', ffi.from_buffer(data))
     if struct.len > len(data):
         raise Exception(
             "only part of the FUSE out packet was passed to from_bytes",
             "length field in header is", struct.len,
             "but passed buffer is only", len(data))
     msg_data = data[ffi.sizeof('struct fuse_out_header'):struct.len]
     return cls.from_header(FuseOutHeader.from_cffi(struct), msg_data)
示例#13
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_init_in*', ffi.from_buffer(data))
     value = cls(
         major=struct.major,
         minor=struct.minor,
         max_readahead=struct.max_readahead,
         flags=FUSE_INIT(struct.flags),
     )
     return value
示例#14
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct __user_cap_data_struct[2]', ffi.from_buffer(data))
     capset_names = ['effective', 'permitted', 'inheritable']
     capsets: t.List[t.Set[CAP]] = []
     for name in capset_names:
         one, two = getattr(struct[0], name), getattr(struct[1], name)
         capset = from_uint32s(one, two)
         capsets.append(capset)
     return cls(*capsets)
示例#15
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_read_in*', ffi.from_buffer(data))
     return cls(
         fh=struct.fh,
         offset=struct.offset,
         size=struct.size,
         read_flags=FUSE_READ(struct.read_flags),
         flags=O(struct.flags),
     )
示例#16
0
 def from_bytes(self, data: bytes) -> T_cmsg:
     record = ffi.cast('struct cmsghdr*', ffi.from_buffer(data))
     if record.cmsg_level != self.cls.level():
         raise Exception("serializer for level", self.cls.level(),
                         "got message for level", record.cmsg_level)
     if record.cmsg_type != self.cls.type():
         raise Exception("serializer for type", self.cls.type(),
                         "got message for type", record.cmsg_type)
     return self.cls.from_data(self.task, data[ffi.sizeof('struct cmsghdr'):record.cmsg_len])
示例#17
0
文件: inotify.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> t.Tuple[T, int]:
     struct = ffi.cast('struct inotify_event*', ffi.from_buffer(data))
     value = cls(
         wd=WatchDescriptor(struct.wd),
         mask=IN(struct.mask),
         cookie=struct.cookie,
         name=ffi.string(struct.name, struct.len).decode() if struct.len else None,
     )
     size = ffi.sizeof("struct inotify_event") + struct.len
     return value, size
示例#18
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     entries = []
     while len(data) > 0:
         record = ffi.cast('struct linux_dirent64*', ffi.from_buffer(data))
         name_len = record.d_reclen - _d_name_offset
         # the name is padded with null bytes to make the dirent aligned,
         # so we have to use strlen to find the end
         name = ffi.string(record.d_name, name_len).decode()
         entries.append(Dirent(inode=record.d_ino, offset=record.d_off, type=DT(record.d_type), name=name))
         data = data[record.d_reclen:]
     return cls(entries)
示例#19
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_init_out*', ffi.from_buffer(data))
     return cls(
         major=struct.major,
         minor=struct.minor,
         max_readahead=struct.max_readahead,
         flags=FUSE_INIT(struct.flags),
         max_background=struct.max_background,
         congestion_threshold=struct.congestion_threshold,
         max_write=struct.max_write,
         time_gran=struct.time_gran,
     )
示例#20
0
 async def read_cffi(self, name: str) -> t.Any:
     "Read, parse, and return this fixed-size cffi type."
     size = ffi.sizeof(name)
     data = await self.read_length(size)
     if data is None:
         raise EOFException("got EOF while expecting to read a", name)
     nameptr = name + '*'
     dest = ffi.new(nameptr)
     # ffi.cast drops the reference to the backing buffer, so we have to copy it
     src = ffi.cast(nameptr, ffi.from_buffer(data))
     ffi.memmove(dest, src, size)
     return dest[0]
示例#21
0
 def from_bytes(self, data: bytes) -> T_cmsglist:
     entries = []
     while len(data) > 0:
         record = ffi.cast('struct cmsghdr*', ffi.from_buffer(data))
         record_data = data[:record.cmsg_len]
         level = SOL(record.cmsg_level)
         if level == SOL.SOCKET and record.cmsg_type == int(SCM.RIGHTS):
             entries.append(CmsgSCMRights.get_serializer(self.task).from_bytes(record_data))
         else:
             raise Exception("unknown cmsg level/type sorry", level, type)
         data = data[record.cmsg_len:]
     return self.cls(entries)
示例#22
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_header(cls: t.Type[T], hdr: FuseOutHeader, data: bytes) -> T:
     entries = []
     while len(data) > 0:
         # We do the work of from_bytes in this class instead of in Dirent because we need the
         # raw length field from the struct; merely doing len(name) will exclude padding.
         struct = ffi.cast('struct fuse_dirent*', ffi.from_buffer(data))
         record_length = ffi.sizeof('struct fuse_dirent') + struct.namelen
         if len(data) < record_length:
             raise Exception(
                 "partial packet passed to FuseDirent.from_bytes")
         entries.append(FuseDirent.from_cffi(struct))
         data = data[record_length:]
     return cls(hdr=hdr, msg=entries)
示例#23
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     entries = []
     while len(data) > 0:
         # We do the work of from_bytes in this class instead of in Dirent because we need the
         # raw length field from the struct; merely doing len(name) will exclude padding.
         record = ffi.cast('struct linux_dirent64*', ffi.from_buffer(data))
         name_len = record.d_reclen - _d_name_offset
         # the name is padded with null bytes to make the dirent aligned,
         # so we have to use strlen to find the end
         name = ffi.string(record.d_name, name_len).decode()
         entries.append(Dirent(inode=record.d_ino, offset=record.d_off, type=DT(record.d_type), name=name))
         data = data[record.d_reclen:]
     return cls(entries)
示例#24
0
 def from_bytes(self, data: bytes) -> RecvMsghdrOut:
     struct = ffi.cast('struct msghdr*', ffi.from_buffer(data))
     if self.name is None:
         name: t.Optional[Pointer[Address]] = None
         name_rest: t.Optional[Pointer[Address]] = None
     else:
         name, name_rest = self.name.split(struct.msg_namelen)
     if self.control is None:
         control: t.Optional[Pointer[CmsgList]] = None
         control_rest: t.Optional[Pointer[CmsgList]] = None
     else:
         control, control_rest = self.control.split(struct.msg_controllen)
     flags = MsghdrFlags(struct.msg_flags)
     return RecvMsghdrOut(name, control, flags, name_rest, control_rest)
示例#25
0
文件: fuse.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct fuse_in_header*', ffi.from_buffer(data))
     if struct.len > len(data):
         raise Exception(
             "only part of the FUSE in packet was passed to from_bytes",
             "length field in header is", struct.len,
             "but passed buffer is only", len(data))
     opcode = FUSE_OPCODE(struct.opcode)
     if opcode != cls.opcode:
         raise Exception("mismatch between opcode in header", opcode,
                         "and opcode for this class", cls.opcode)
     hdr = FuseInHeader.from_cffi(struct)
     variable = data[FuseInHeader.sizeof():struct.len]
     msg = cls.from_header(hdr, variable)
     return msg
示例#26
0
文件: fuse.py 项目: gc-ss/rsyscall
def fuse_in_parse_split(data: bytes) -> t.Tuple[FuseIn, bytes]:
    "Split the buffer into parsed header with variable length section, and remaining unparsed data"
    struct = ffi.cast('struct fuse_in_header*', ffi.from_buffer(data))
    if struct.len > len(data):
        raise Exception(
            "only part of the FUSE packet was passed to _header_parse_split",
            "length field in header is", struct.len,
            "but passed buffer is only", len(data))
    opcode = FUSE_OPCODE(struct.opcode)
    hdr = FuseInHeader.from_cffi(struct)
    variable = data[FuseInHeader.sizeof():struct.len]
    rest = data[struct.len:]
    # dispatch to the specific message type
    msg = opcode_classes[opcode].from_header(hdr, variable)
    return msg, rest
示例#27
0
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     struct = ffi.cast('struct kernel_sigaction const*',
                       ffi.from_buffer(data))
     handler: t.Union[Sighandler, near.Address]
     int_handler = int(ffi.cast('long int', struct.ksa_handler))
     try:
         handler = Sighandler(int_handler)
     except ValueError:
         handler = near.Address(int_handler)
     int_restorer = int(ffi.cast('long int', struct.ksa_restorer))
     return cls(
         handler=handler,
         flags=SA(struct.ksa_flags),
         mask=Sigset.from_cffi(struct.ksa_mask),
         restorer=near.Address(int_restorer) if int_restorer else None,
     )
示例#28
0
文件: socket.py 项目: gc-ss/rsyscall
 def from_bytes(self, data: bytes) -> RecvMsghdrOut:
     struct = ffi.cast('struct msghdr*', ffi.from_buffer(data))
     if self.name is None:
         name: t.Optional[ReadablePointer[Sockaddr]] = None
         name_rest: t.Optional[Pointer[Sockaddr]] = None
     else:
         name, name_rest = self.name.readable_split(struct.msg_namelen)
     if self.control is None:
         control: t.Optional[Pointer[CmsgList]] = None
         control_rest: t.Optional[Pointer[CmsgList]] = None
     else:
         control, control_rest = self.control.readable_split(
             struct.msg_controllen)
     flags = MsghdrFlags(struct.msg_flags)
     return RecvMsghdrOut(name,
                          control._linearize() if control else None, flags,
                          name_rest, control_rest)
示例#29
0
 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),
     )
示例#30
0
文件: un.py 项目: gc-ss/rsyscall
 def from_bytes(cls: t.Type[T], data: bytes) -> T:
     header = ffi.sizeof('sa_family_t')
     if len(data) < header:
         raise Exception("data too smalllll", data)
     struct = ffi.cast('struct sockaddr_un*', ffi.from_buffer(data))
     cls.check_family(AF(struct.sun_family))
     if len(data) == header:
         # unnamed socket, name is empty
         length = 0
     elif struct.sun_path[0] == b'\0':
         # abstract socket, entire buffer is part of path
         length = len(data) - header
     else:
         # TODO handle the case where there's no null terminator
         # pathname socket, path is null-terminated
         length = lib.strlen(struct.sun_path)
     return cls(bytes(ffi.buffer(struct.sun_path, length)))