From b6cdaac364463e96736af8d02ede7b8074949de3 Mon Sep 17 00:00:00 2001 From: slush0 Date: Thu, 28 Apr 2016 23:43:53 +0200 Subject: [PATCH] Removed lib_linux (all platform-dependent handling is done by C modules). --- src/lib_linux/errno.py | 38 ----- src/lib_linux/ffilib.py | 46 ------ src/lib_linux/os.py | 272 -------------------------------- src/lib_linux/select.py | 90 ----------- src/lib_linux/stat.py | 149 ----------------- src/lib_linux/transport_pipe.py | 140 ---------------- 6 files changed, 735 deletions(-) delete mode 100644 src/lib_linux/errno.py delete mode 100644 src/lib_linux/ffilib.py delete mode 100644 src/lib_linux/os.py delete mode 100644 src/lib_linux/select.py delete mode 100644 src/lib_linux/stat.py delete mode 100644 src/lib_linux/transport_pipe.py diff --git a/src/lib_linux/errno.py b/src/lib_linux/errno.py deleted file mode 100644 index 7b7935ef8b..0000000000 --- a/src/lib_linux/errno.py +++ /dev/null @@ -1,38 +0,0 @@ -EPERM = 1 # Operation not permitted -ENOENT = 2 # No such file or directory -ESRCH = 3 # No such process -EINTR = 4 # Interrupted system call -EIO = 5 # I/O error -ENXIO = 6 # No such device or address -E2BIG = 7 # Argument list too long -ENOEXEC = 8 # Exec format error -EBADF = 9 # Bad file number -ECHILD = 10 # No child processes -EAGAIN = 11 # Try again -ENOMEM = 12 # Out of memory -EACCES = 13 # Permission denied -EFAULT = 14 # Bad address -ENOTBLK = 15 # Block device required -EBUSY = 16 # Device or resource busy -EEXIST = 17 # File exists -EXDEV = 18 # Cross-device link -ENODEV = 19 # No such device -ENOTDIR = 20 # Not a directory -EISDIR = 21 # Is a directory -EINVAL = 22 # Invalid argument -ENFILE = 23 # File table overflow -EMFILE = 24 # Too many open files -ENOTTY = 25 # Not a typewriter -ETXTBSY = 26 # Text file busy -EFBIG = 27 # File too large -ENOSPC = 28 # No space left on device -ESPIPE = 29 # Illegal seek -EROFS = 30 # Read-only file system -EMLINK = 31 # Too many links -EPIPE = 32 # Broken pipe -EDOM = 33 # Math argument out of domain of func -ERANGE = 34 # Math result not representable -EAFNOSUPPORT = 97 # Address family not supported by protocol -ECONNRESET = 104 # Connection timed out -ETIMEDOUT = 110 # Connection timed out -EINPROGRESS = 115 # Operation now in progress diff --git a/src/lib_linux/ffilib.py b/src/lib_linux/ffilib.py deleted file mode 100644 index dc4d672a28..0000000000 --- a/src/lib_linux/ffilib.py +++ /dev/null @@ -1,46 +0,0 @@ -import sys -try: - import ffi -except ImportError: - ffi = None - -_cache = {} - -def open(name, maxver=10, extra=()): - if not ffi: - return None - try: - return _cache[name] - except KeyError: - pass - def libs(): - if sys.platform == "linux": - yield '%s.so' % name - for i in range(maxver, -1, -1): - yield '%s.so.%u' % (name, i) - else: - for ext in ('dylib', 'dll'): - yield '%s.%s' % (name, ext) - for n in extra: - yield n - err = None - for n in libs(): - try: - l = ffi.open(n) - _cache[name] = l - return l - except OSError as e: - err = e - raise err - -def libc(): - return open("libc", 6) - -# Find out bitness of the platform, even if long ints are not supported -# TODO: All bitness differences should be removed from micropython-lib, and -# this snippet too. -bitness = 1 -v = sys.maxsize -while v: - bitness += 1 - v >>= 1 diff --git a/src/lib_linux/os.py b/src/lib_linux/os.py deleted file mode 100644 index 557e71c734..0000000000 --- a/src/lib_linux/os.py +++ /dev/null @@ -1,272 +0,0 @@ -import array -import ustruct as struct -import errno as errno_ -import stat as stat_ -import ffilib -import uos - -R_OK = const(4) -W_OK = const(2) -X_OK = const(1) -F_OK = const(0) - -O_ACCMODE = 0o0000003 -O_RDONLY = 0o0000000 -O_WRONLY = 0o0000001 -O_RDWR = 0o0000002 -O_CREAT = 0o0000100 -O_EXCL = 0o0000200 -O_NOCTTY = 0o0000400 -O_TRUNC = 0o0001000 -O_APPEND = 0o0002000 -O_NONBLOCK = 0o0004000 - -error = OSError -name = "posix" -sep = "/" -curdir = "." -pardir = ".." -environ = {"WARNING": "NOT_IMPLEMENTED"} - - -libc = ffilib.libc() - -if libc: - chdir_ = libc.func("i", "chdir", "s") - mkdir_ = libc.func("i", "mkdir", "si") - rename_ = libc.func("i", "rename", "ss") - unlink_ = libc.func("i", "unlink", "s") - rmdir_ = libc.func("i", "rmdir", "s") - getcwd_ = libc.func("s", "getcwd", "si") - opendir_ = libc.func("P", "opendir", "s") - readdir_ = libc.func("P", "readdir", "P") - open_ = libc.func("i", "open", "sii") - fdopen_ = libc.func("i", "fdopen", "sii") - fsync_ = libc.func("i", "fsync", "i") - #lseek = libc.func("i", "lseek", "iii") - read_ = libc.func("i", "read", "ipi") - write_ = libc.func("i", "write", "iPi") - close_ = libc.func("i", "close", "i") - dup_ = libc.func("i", "dup", "i") - access_ = libc.func("i", "access", "si") - fork_ = libc.func("i", "fork", "") - pipe_ = libc.func("i", "pipe", "p") - mkfifo_ = libc.func("i", "mkfifo", "si") - _exit_ = libc.func("v", "_exit", "i") - getpid_ = libc.func("i", "getpid", "") - waitpid_ = libc.func("i", "waitpid", "ipi") - system_ = libc.func("i", "system", "s") - execvp_ = libc.func("i", "execvp", "PP") - kill_ = libc.func("i", "kill", "ii") - getenv_ = libc.func("s", "getenv", "P") - -def check_error(ret): - # Return True is error was EINTR (which usually means that OS call - # should be restarted). - if ret == -1: - e = uos.errno() - if e == errno_.EINTR: - return True - raise OSError(e) - -def raise_error(): - raise OSError(uos.errno()) - -stat = uos.stat - -def getcwd(): - buf = bytearray(512) - return getcwd_(buf, 512) - -def mkdir(name, mode=0o777): - e = mkdir_(name, mode) - check_error(e) - -def rename(old, new): - e = rename_(old, new) - check_error(e) - -def unlink(name): - e = unlink_(name) - check_error(e) - -def rmdir(name): - e = rmdir_(name) - check_error(e) - -def makedirs(name, mode=0o777, exist_ok=False): - s = "" - comps = name.split("/") - if comps[-1] == "": - comps.pop() - for i, c in enumerate(comps): - s += c + "/" - try: - uos.mkdir(s) - except OSError as e: - if e.args[0] != errno_.EEXIST: - raise - if i == len(comps) - 1: - if exist_ok: - return - raise e - -if hasattr(uos, "ilistdir"): - ilistdir = uos.ilistdir -else: - def ilistdir(path="."): - dir = opendir_(path) - if not dir: - raise_error() - res = [] - dirent_fmt = "LLHB256s" - while True: - dirent = readdir_(dir) - if not dirent: - break - import uctypes - dirent = uctypes.bytes_at(dirent, struct.calcsize(dirent_fmt)) - dirent = struct.unpack(dirent_fmt, dirent) - dirent = (dirent[-1].split(b'\0', 1)[0], dirent[-2], dirent[0]) - yield dirent - -def listdir(path="."): - is_str = type(path) is not bytes - res = [] - for dirent in ilistdir(path): - fname = dirent[0] - if fname not in (b".", b"..", ".", ".."): - if is_str: - fname = fsdecode(fname) - res.append(fname) - return res - -def walk(top, topdown=True): - files = [] - dirs = [] - for dirent in ilistdir_ex(top): - mode = dirent[3] << 12 - fname = dirent[4].split(b'\0', 1)[0] - if stat_.S_ISDIR(mode): - if fname != b"." and fname != b"..": - dirs.append(fsdecode(fname)) - else: - files.append(fsdecode(fname)) - if topdown: - yield top, dirs, files - for d in dirs: - yield from walk(top + "/" + d, topdown) - if not topdown: - yield top, dirs, files - -def open(n, flags, mode=0o777): - r = open_(n, flags, mode) - check_error(r) - return r - -def fdopen(n, flags, mode=0o777): - r = fdopen_(n, flags, mode) - check_error(r) - return r - -def read(fd, n): - buf = bytearray(n) - r = read_(fd, buf, n) - check_error(r) - return bytes(buf[:r]) - -def write(fd, buf): - r = write_(fd, buf, len(buf)) - check_error(r) - return r - -def fsync(fd): - r = fsync_(fd) - check_error(r) - return r - -def close(fd): - r = close_(fd) - check_error(r) - return r - -def dup(fd): - r = dup_(fd) - check_error(r) - return r - -def access(path, mode): - return access_(path, mode) == 0 - -def chdir(dir): - r = chdir_(dir) - check_error(r) - -def fork(): - r = fork_() - check_error(r) - return r - -def pipe(): - a = array.array('i', [0, 0]) - r = pipe_(a) - check_error(r) - return a[0], a[1] - -def mkfifo(n, mode=0o777): - r = mkfifo_(n, mode) - check_error(r) - return r - -def _exit(n): - _exit_(n) - -def execvp(f, args): - import uctypes - args_ = array.array("P", [0] * (len(args) + 1)) - i = 0 - for a in args: - args_[i] = uctypes.addressof(a) - i += 1 - r = execvp_(f, uctypes.addressof(args_)) - check_error(r) - -def getpid(): - return getpid_() - -def waitpid(pid, opts): - a = array.array('i', [0]) - r = waitpid_(pid, a, opts) - check_error(r) - return (r, a[0]) - -def kill(pid, sig): - r = kill_(pid, sig) - check_error(r) - -def system(command): - r = system_(command) - check_error(r) - return r - -def getenv(var, default=None): - var = getenv_(var) - if var is None: - return default - return var - -def fsencode(s): - if type(s) is bytes: - return s - return bytes(s, "utf-8") - -def fsdecode(s): - if type(s) is str: - return s - return str(s, "utf-8") - - -def urandom(n): - import builtins - with builtins.open("/dev/urandom", "rb") as f: - return f.read(n) diff --git a/src/lib_linux/select.py b/src/lib_linux/select.py deleted file mode 100644 index e7de109df3..0000000000 --- a/src/lib_linux/select.py +++ /dev/null @@ -1,90 +0,0 @@ -import ffi -import ustruct as struct -import os -import errno -import ffilib - - -libc = ffilib.libc() - -#int epoll_create(int size); -epoll_create = libc.func("i", "epoll_create", "i") -#int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); -epoll_ctl = libc.func("i", "epoll_ctl", "iiiP") -#int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); -epoll_wait = libc.func("i", "epoll_wait", "ipii") - -EPOLLIN = 0x001 -EPOLLPRI = 0x002 -EPOLLOUT = 0x004 -EPOLLERR = 0x008 -EPOLLHUP = 0x010 -EPOLLRDHUP = 0x2000 -EPOLLONESHOT = 1 << 30 -EPOLLET = 1 << 31 - -EPOLL_CTL_ADD = 1 -EPOLL_CTL_DEL = 2 -EPOLL_CTL_MOD = 3 - -# TODO: struct epoll_event's 2nd member is union of uint64_t, etc. -# On x86, uint64_t is 4-byte aligned, on many other platforms - 8-byte. -# Until uctypes module can assign native struct offset, use dirty hack -# below. -# TODO: Get rid of all this dirtiness, move it on C side -if ffilib.bitness > 32: - # On x86_64, epoll_event is packed struct - epoll_event = " 0: - vals = struct.unpack(epoll_event, s) - res.append((vals[1], vals[0])) - return res - - def close(self): - os.close(self.epfd) - - -def epoll(sizehint=4): - fd = epoll_create(sizehint) - os.check_error(fd) - return Epoll(fd) diff --git a/src/lib_linux/stat.py b/src/lib_linux/stat.py deleted file mode 100644 index 704adfe2e1..0000000000 --- a/src/lib_linux/stat.py +++ /dev/null @@ -1,149 +0,0 @@ -"""Constants/functions for interpreting results of os.stat() and os.lstat(). - -Suggested usage: from stat import * -""" - -# Indices for stat struct members in the tuple returned by os.stat() - -ST_MODE = 0 -ST_INO = 1 -ST_DEV = 2 -ST_NLINK = 3 -ST_UID = 4 -ST_GID = 5 -ST_SIZE = 6 -ST_ATIME = 7 -ST_MTIME = 8 -ST_CTIME = 9 - -# Extract bits from the mode - -def S_IMODE(mode): - """Return the portion of the file's mode that can be set by - os.chmod(). - """ - return mode & 0o7777 - -def S_IFMT(mode): - """Return the portion of the file's mode that describes the - file type. - """ - return mode & 0o170000 - -# Constants used as S_IFMT() for various file types -# (not all are implemented on all systems) - -S_IFDIR = 0o040000 # directory -S_IFCHR = 0o020000 # character device -S_IFBLK = 0o060000 # block device -S_IFREG = 0o100000 # regular file -S_IFIFO = 0o010000 # fifo (named pipe) -S_IFLNK = 0o120000 # symbolic link -S_IFSOCK = 0o140000 # socket file - -# Functions to test for each file type - -def S_ISDIR(mode): - """Return True if mode is from a directory.""" - return S_IFMT(mode) == S_IFDIR - -def S_ISCHR(mode): - """Return True if mode is from a character special device file.""" - return S_IFMT(mode) == S_IFCHR - -def S_ISBLK(mode): - """Return True if mode is from a block special device file.""" - return S_IFMT(mode) == S_IFBLK - -def S_ISREG(mode): - """Return True if mode is from a regular file.""" - return S_IFMT(mode) == S_IFREG - -def S_ISFIFO(mode): - """Return True if mode is from a FIFO (named pipe).""" - return S_IFMT(mode) == S_IFIFO - -def S_ISLNK(mode): - """Return True if mode is from a symbolic link.""" - return S_IFMT(mode) == S_IFLNK - -def S_ISSOCK(mode): - """Return True if mode is from a socket.""" - return S_IFMT(mode) == S_IFSOCK - -# Names for permission bits - -S_ISUID = 0o4000 # set UID bit -S_ISGID = 0o2000 # set GID bit -S_ENFMT = S_ISGID # file locking enforcement -S_ISVTX = 0o1000 # sticky bit -S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR -S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR -S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR -S_IRWXU = 0o0700 # mask for owner permissions -S_IRUSR = 0o0400 # read by owner -S_IWUSR = 0o0200 # write by owner -S_IXUSR = 0o0100 # execute by owner -S_IRWXG = 0o0070 # mask for group permissions -S_IRGRP = 0o0040 # read by group -S_IWGRP = 0o0020 # write by group -S_IXGRP = 0o0010 # execute by group -S_IRWXO = 0o0007 # mask for others (not in group) permissions -S_IROTH = 0o0004 # read by others -S_IWOTH = 0o0002 # write by others -S_IXOTH = 0o0001 # execute by others - -# Names for file flags - -UF_NODUMP = 0x00000001 # do not dump file -UF_IMMUTABLE = 0x00000002 # file may not be changed -UF_APPEND = 0x00000004 # file may only be appended to -UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack -UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted -UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed -UF_HIDDEN = 0x00008000 # OS X: file should not be displayed -SF_ARCHIVED = 0x00010000 # file may be archived -SF_IMMUTABLE = 0x00020000 # file may not be changed -SF_APPEND = 0x00040000 # file may only be appended to -SF_NOUNLINK = 0x00100000 # file may not be renamed or deleted -SF_SNAPSHOT = 0x00200000 # file is a snapshot file - - -_filemode_table = ( - ((S_IFLNK, "l"), - (S_IFREG, "-"), - (S_IFBLK, "b"), - (S_IFDIR, "d"), - (S_IFCHR, "c"), - (S_IFIFO, "p")), - - ((S_IRUSR, "r"),), - ((S_IWUSR, "w"),), - ((S_IXUSR|S_ISUID, "s"), - (S_ISUID, "S"), - (S_IXUSR, "x")), - - ((S_IRGRP, "r"),), - ((S_IWGRP, "w"),), - ((S_IXGRP|S_ISGID, "s"), - (S_ISGID, "S"), - (S_IXGRP, "x")), - - ((S_IROTH, "r"),), - ((S_IWOTH, "w"),), - ((S_IXOTH|S_ISVTX, "t"), - (S_ISVTX, "T"), - (S_IXOTH, "x")) -) - -def filemode(mode): - """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" - perm = [] - for table in _filemode_table: - for bit, char in table: - if mode & bit == bit: - perm.append(char) - break - else: - perm.append("-") - return "".join(perm) diff --git a/src/lib_linux/transport_pipe.py b/src/lib_linux/transport_pipe.py deleted file mode 100644 index 61bc3928fc..0000000000 --- a/src/lib_linux/transport_pipe.py +++ /dev/null @@ -1,140 +0,0 @@ -'''PipeTransport implements fake wire transport over local named pipe. -Use this transport for talking with trezor simulator.''' - -import os -import ustruct -import uselect - -from trezor import loop - -read_fd = None -write_fd = None - -poll = None -on_read = None - -def init(filename): - global read_fd, write_fd, poll - - filename_read = filename + '.to' - filename_write = filename + '.from' - - os.mkfifo(filename_read, 0o600) - os.mkfifo(filename_write, 0o600) - - write_fd = os.open(filename_write, os.O_RDWR, 0o600) - read_fd = os.open(filename_read, os.O_RDWR, 0o600) - - poll = uselect.poll() - poll.register(read_fd, uselect.POLLIN) - - # Setup polling - loop.call_soon(watch_read()) - -def set_notify(_on_read): - global on_read - on_read = _on_read - -def close(): - global read_fd, write_fd - - os.close(read_fd) - os.close(write_fd) - -def watch_read(): - global on_read - sleep = loop.Sleep(10000) # 0.01s - while True: - if ready_to_read() and on_read: - on_read() - - yield sleep - -def ready_to_read(): - global poll - return len(poll.poll(0)) > 0 - -def read(): - """ - If there is data available to be read from the transport, reads the data and tries to parse it as a protobuf message. If the parsing succeeds, return a protobuf object. - Otherwise, returns None. - """ - - if not ready_to_read(): - return None - - data = _read() - if data == None: - return None - - return _parse_message(data) - -def write(msg): - """ - Write mesage to tansport. msg should be a member of a valid `protobuf class `_ with a SerializeToString() method. - """ - ser = msg.SerializeToString() - header = ustruct.pack(">HL", mapping.get_type(msg), len(ser)) - - _write(b"##%s%s" % (header, ser)) - -def _parse_message(data): - (msg_type, _data) = data - if msg_type == 'protobuf': - return _data - else: - # inst = mapping.get_class(msg_type)() - # inst.ParseFromString(_data) - inst = _data - return inst - -def _read_headers(): - global read_fd - - # Try to read headers until some sane value are detected - is_ok = False - while not is_ok: - - # Align cursor to the beginning of the header ("##") - c = os.read(read_fd, 1) - i = 0 - while c != b'#': - i += 1 - if i >= 64: - # timeout - raise Exception("Timed out while waiting for the magic character") - # print "Aligning to magic characters" - c = os.read(read_fd, 1) - print(c) - - if os.read(read_fd, 1) != b'#': - # Second character must be # to be valid header - raise Exception("Second magic character is broken") - - # Now we're most likely on the beginning of the header - try: - headerlen = ustruct.calcsize(">HL") - (msg_type, datalen) = ustruct.unpack(">HL", os.read(read_fd, headerlen)) - break - except: - raise Exception("Cannot parse header length") - - return (msg_type, datalen) - -def _write(msg): - global write_fd - try: - os.write(write_fd, msg) - # os.fsync(write_fd) - except OSError: - print("Error while writing to socket") - raise - -def _read(): - global read_fd - try: - (msg_type, datalen) = _read_headers() - return (msg_type, os.read(read_fd, datalen)) - except: - print("Failed to read from device") - raise