def load_func(self, func_name, prog_type): if func_name in self.funcs: return self.funcs[func_name] if not lib.bpf_function_start(self.module, func_name.encode("ascii")): raise Exception("Unknown program %s" % func_name) buffer_len = LOG_BUFFER_SIZE while True: log_buf = ct.create_string_buffer(buffer_len) if self.debug else None fd = lib.bpf_prog_load(prog_type, lib.bpf_function_start(self.module, func_name.encode("ascii")), lib.bpf_function_size(self.module, func_name.encode("ascii")), lib.bpf_module_license(self.module), lib.bpf_module_kern_version(self.module), log_buf, ct.sizeof(log_buf) if log_buf else 0) if fd < 0 and ct.get_errno() == errno.ENOSPC and self.debug: buffer_len <<= 1 else: break if self.debug & DEBUG_BPF and log_buf.value: print(log_buf.value.decode(), file=sys.stderr) if fd < 0: atexit.register(self.donothing) if ct.get_errno() == errno.EPERM: raise Exception("Need super-user privilges to run") errstr = os.strerror(ct.get_errno()) raise Exception("Failed to load BPF program %s: %s" % (func_name, errstr)) fn = BPF.Function(self, func_name, fd) self.funcs[func_name] = fn return fn
def umount(mount_point): """ This function unmounts a mounted directory forcibly. This will be used for unmounting broken hard drive mounts which may hang. If umount returns EBUSY this will lazy unmount. :param mount_point: str. A String representing the filesystem mount point :return: int. Returns 0 on success. errno otherwise. """ libc_path = ctypes.util.find_library("c") libc = ctypes.CDLL(libc_path, use_errno=True) # First try to umount with MNT_FORCE ret = libc.umount(mount_point, 1) if ret < 0: err = ctypes.get_errno() if err == errno.EBUSY: # Detach from try. IE lazy umount ret = libc.umount(mount_point, 2) if ret < 0: err = ctypes.get_errno() return err return 0 else: return err return 0
def upload(self, local, remote): remote_fd = self._glfs_creat(self.fs, remote, os.O_RDWR, 0o644) if remote_fd is None: err = ctypes.get_errno() raise IOError( "Failed to create {0}: {1}".format(remote, os.strerror(err)) ) ret = self._glfs_ftruncate(remote_fd, 0) if ret == -1: err = ctypes.get_errno() raise IOError( "Failed to truncate {0}: {1}".format(remote, os.strerror(err)) ) with open(local, "r") as local_fd: while True: chunk = local_fd.read(CHUNK_SIZE) if not chunk: break ret = self._glfs_write(remote_fd, chunk, len(chunk), 0) if ret == -1: err = ctypes.get_errno() raise IOError( "Write failed {0}".format(os.strerror(err)) ) self._glfs_close(remote_fd)
def load_func(self, func_name, prog_type): func_name = _assert_is_bytes(func_name) if func_name in self.funcs: return self.funcs[func_name] if not lib.bpf_function_start(self.module, func_name): raise Exception("Unknown program %s" % func_name) log_level = 0 if (self.debug & DEBUG_BPF_REGISTER_STATE): log_level = 2 elif (self.debug & DEBUG_BPF): log_level = 1 fd = lib.bpf_prog_load(prog_type, func_name, lib.bpf_function_start(self.module, func_name), lib.bpf_function_size(self.module, func_name), lib.bpf_module_license(self.module), lib.bpf_module_kern_version(self.module), log_level, None, 0); if fd < 0: atexit.register(self.donothing) if ct.get_errno() == errno.EPERM: raise Exception("Need super-user privileges to run") errstr = os.strerror(ct.get_errno()) raise Exception("Failed to load BPF program %s: %s" % (func_name, errstr)) fn = BPF.Function(self, func_name, fd) self.funcs[func_name] = fn return fn
def __getxattr_low(file_id, attr_name, getxattr_func): value = 'x' * 256 got = getxattr_func(file_id, attr_name, value, len(value)) if got < 0: err = ctypes.get_errno() if err == errno.ENODATA: # The file exists, but doesn't have the specified xattr. return None elif err != errno.ERANGE: raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) got = getxattr_func(file_id, attr_name, None, 0) if got < 0: err = ctypes.get_errno() raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) assert got > len(value) value = 'x' * got # We have a race condition here, someone might have changed the xattr # by now. got = getxattr_func(file_id, attr_name, value, got) if got < 0: err = ctypes.get_errno() raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) return value assert got <= len(value) return value[:got]
def __listxattr_low(file_id, listxattr_func): value = 'x' * 256 got = listxattr_func(file_id, value, len(value)) if got < 0: err = ctypes.get_errno() if err != errno.ERANGE: raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) got = listxattr_func(file_id, None, 0) if got < 0: err = ctypes.get_errno() raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) assert got > len(value) value = 'x' * got # We have a race condition here, someone might have changed the xattr # by now. got = listxattr_func(file_id, value, got) if got < 0: err = ctypes.get_errno() raise OSError(err, '%s: %r' % (os.strerror(err), file_id)) if got: assert got <= len(value) assert value[got - 1] == '\0' return value[:got - 1].split('\0') else: return []
def _add_watch_for_path(self, path): logging.debug('_add_watch_for_path(%r)', path) for dirpath, directories, _ in itertools.chain( [('', [path], None)], os.walk(path, topdown=True, followlinks=True)): for directory in directories: directory_path = os.path.join(dirpath, directory) # dirpath cannot be used as the parent directory path because it is the # empty string for symlinks :-( parent_path = os.path.dirname(directory_path) watch_descriptor = InotifyFileWatcher._libc.inotify_add_watch( self._inotify_fd, ctypes.create_string_buffer(directory_path), _INTERESTING_INOTIFY_EVENTS) if watch_descriptor < 0: if ctypes.get_errno() == errno.ENOSPC: logging.warning( 'There are too many directories in your application for ' 'changes in all of them to be monitored. You may have to ' 'restart the development server to see some changes to your ' 'files.') return error = OSError('could not add watch for %r' % directory_path) error.errno = ctypes.get_errno() error.strerror = errno.errorcode[ctypes.get_errno()] error.filename = directory_path raise error if parent_path in self._directory_to_subdirs: self._directory_to_subdirs[parent_path].add(directory_path) self._watch_to_directory[watch_descriptor] = directory_path self._directory_to_watch_descriptor[directory_path] = watch_descriptor self._directory_to_subdirs[directory_path] = set()
def mount(self, passwd=None): if self.mountpoint and os.path.ismount(self.mountpoint): raise Exception("Disk partition already mounted") elif self.fstype == "Unknown": raise Exception("Cannot mount a partition of unknown type") signals.emit("filesystems", "pre_mount", self) mount_point = self.mountpoint if self.mountpoint else os.path.join("/media", self.id) if self.crypt and passwd: # Decrypt the disk first if it's an encrypted disk s = crypto.luks_open(self.path, self.id, passwd) if s != 0: raise Exception("Failed to decrypt %s with errno %s" % (self.id, str(s))) s = libc.mount(ctypes.c_char_p(os.path.join("/dev/mapper", self.id)), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: crypto.luks_close(self.id) raise Exception("Failed to mount %s: %s" % (self.id, os.strerror(ctypes.get_errno()))) elif self.crypt and not passwd: raise Exception("Must provide password to decrypt encrypted disk") else: s = libc.mount(ctypes.c_char_p(self.path), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: raise Exception("Failed to mount %s: %s"%(self.id, os.strerror(ctypes.get_errno()))) signals.emit("filesystems", "post_mount", self) self.mountpoint = mount_point
def mount(self): """ Mount a GlusterFS volume for use. :raises: LibgfapiException on failure """ if self.fs and self._mounted: # Already mounted return self.fs = api.glfs_new(self.volname) if not self.fs: err = ctypes.get_errno() raise LibgfapiException("glfs_new(%s) failed: %s" % (self.volname, os.strerror(err))) ret = api.glfs_set_volfile_server(self.fs, self.protocol, self.host, self.port) if ret < 0: err = ctypes.get_errno() raise LibgfapiException("glfs_set_volfile_server(%s, %s, %s, " "%s) failed: %s" % (self.fs, self.protocol, self.host, self.port, os.strerror(err))) self.set_logging(self.log_file, self.log_level) if self.fs and not self._mounted: ret = api.glfs_init(self.fs) if ret < 0: err = ctypes.get_errno() raise LibgfapiException("glfs_init(%s) failed: %s" % (self.fs, os.strerror(err))) else: self._mounted = True
def __init__(self, path, no_atime = False, **kw): arg_is_unicode = isinstance(path, unicode) if _is_linux and no_atime: try: fd = os.open(path, os.O_RDONLY | os.O_NOCTTY | os.O_NOATIME) except OSError as e: if e.errno == errno.EPERM: fd = os.open(path, os.O_RDONLY | os.O_NOCTTY) else: raise self.dirp = _libc.fdopendir(fd) if not self.dirp: try: os.close(fd) except OSError: unhandled_exc_handler() e = ctypes.get_errno() raise OSError(e, os.strerror(e), path) else: self.dirp = _libc.opendir(path.encode(sys.getfilesystemencoding()) if arg_is_unicode else path) if not self.dirp: e = ctypes.get_errno() raise OSError(e, os.strerror(e), path) self.path = path self.my_dirent = Dirent() self.my_dirent_p = Dirent_p() self.arg_is_unicode = arg_is_unicode self.reset = functools.partial(_libc.rewinddir, self.dirp)
def getxattr(self, path, key, size=0): """ Retrieve the value of the extended attribute identified by key for path specified. :param path: Path to file or directory :param key: Key of extended attribute :param size: If size is specified as zero, we first determine the size of xattr and then allocate a buffer accordingly. If size is non-zero, it is assumed the caller knows the size of xattr. :returns: Value of extended attribute corresponding to key specified. """ if size == 0: size = api.glfs_getxattr(self.fs, path, key, None, 0) if size < 0: err = ctypes.get_errno() raise OSError(err, os.strerror(err)) buf = ctypes.create_string_buffer(size) rc = api.glfs_getxattr(self.fs, path, key, buf, size) if rc < 0: err = ctypes.get_errno() raise OSError(err, os.strerror(err)) return buf.value[:rc]
def calculate_statistics(numbers): '''Calculate the mean, median, mode, and range using the shared statistics library''' # Make the arr and arrlen values ctypes compatible arr = (ctypes.c_double * len(numbers))(*numbers) arrlen = ctypes.c_size_t(len(numbers)) # Calculate and check errno after each call mean = libstats.mean(arr, arrlen) check_error(ctypes.get_errno()) median = libstats.median(arr, arrlen) check_error(ctypes.get_errno()) mode = libstats.mode(arr, arrlen) check_error(ctypes.get_errno()) rng = libstats.range(arr, arrlen) check_error(ctypes.get_errno()) stats = Statistics( mean=mean, median=median, mode=mode, rng=rng, count=len(numbers)) return stats
def mount(self, passwd=None): if self.mountpoint and os.path.ismount(self.mountpoint): raise Exception("Virtual disk already mounted") signals.emit("filesystems", "pre_mount", self) if not os.path.isdir(os.path.join("/media", self.id)): os.makedirs(os.path.join("/media", self.id)) mount_point = self.mountpoint if self.mountpoint else os.path.join("/media", self.id) # Find a free loopback device and mount loop = losetup.find_unused_loop_device() loop.mount(str(self.path), offset=1048576) if self.crypt and passwd: # If it's an encrypted virtual disk, decrypt first then mount s = crypto.luks_open(loop.device, self.id, passwd) if s != 0: loop.unmount() raise Exception("Failed to decrypt %s with errno %s" % (self.id, str(s))) s = libc.mount(ctypes.c_char_p(os.path.join("/dev/mapper", self.id)), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: crypto.luks_close(self.id) loop.unmount() raise Exception("Failed to mount %s: %s" % (self.id, os.strerror(ctypes.get_errno()))) elif self.crypt and not passwd: raise Exception("Must provide password to decrypt encrypted container") else: s = libc.mount(ctypes.c_char_p(loop.device), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: loop.unmount() raise Exception("Failed to mount %s: %s" % (self.id, os.strerror(ctypes.get_errno()))) signals.emit("filesystems", "post_mount", self) self.mountpoint = mount_point
def pagecache_incore(self, filename): with open(filename, "r") as fd: stat = os.fstat(fd.fileno()) filesize = stat.st_size if filesize == 0: return (0, 0, 0.0) faddr = self.mmap(0, filesize, PROT_READ, MAP_SHARED, fd.fileno(), 0) if faddr == self.MAP_FAILED: fd.close() print "Failed to mmap %s (errno: %d)" % (filename, get_errno()) sys.exit(-1) vec_size = (filesize + PAGESIZE - 1) / PAGESIZE vec = (c_ubyte * vec_size)() rv = self.mincore(faddr, filesize, cast(vec, POINTER(c_ubyte))) if rv == -1: fd.close() print "mincore failed: 0x%x, 0x%x: %d" % (faddr, filesize, get_errno()) sys.exit(-1) cached_pages = 0 for pageidx in xrange(len(vec)): if vec[pageidx] & 1: cached_pages += 1 # Clean up fd.close() if faddr: self.munmap(faddr, filesize) del stat del vec # Return cached pages, total pages, ratio total_pages = math.ceil(float(filesize) / PAGESIZE) ratio = (cached_pages / total_pages) return (cached_pages, int(total_pages), ratio)
def __init__(self, directories): """Initializer for InotifyFileWatcher. Args: directories: An iterable of strings representing the path to a directory that should be monitored for changes i.e. files and directories added, renamed, deleted or changed. Raises: OSError: if there are no inotify instances available. """ assert _libc is not None, "InotifyFileWatcher only available on Linux." self._directories = [os.path.abspath(d) for d in directories] self._real_directories = [os.path.realpath(d) for d in self._directories] self._watch_to_directory = {} self._directory_to_watch_descriptor = {} self._directory_to_subdirs = {} self._inotify_events = "" self._inotify_fd = _libc.inotify_init() if self._inotify_fd < 0: error = OSError("failed call to inotify_init") error.errno = ctypes.get_errno() error.strerror = errno.errorcode[ctypes.get_errno()] raise error self._inotify_poll = select.poll() # Protects operations that cannot be done while the watcher is quitting. self._inotify_fd_lock = threading.Lock()
def _remove_watch_for_path(self, path): # Must be called with _inotify_fd_lock held. logging.debug('_remove_watch_for_path(%r)', path) wd = self._directory_to_watch_descriptor[path] if _libc.inotify_rm_watch(self._inotify_fd, wd) < 0: # If the directory is deleted then the watch will removed automatically # and inotify_rm_watch will fail. Just log the error. logging.debug('inotify_rm_watch failed for %r: %d [%r]', path, ctypes.get_errno(), errno.errorcode[ctypes.get_errno()]) parent_path = os.path.dirname(path) if parent_path in self._directory_to_subdirs: self._directory_to_subdirs[parent_path].remove(path) # _directory_to_subdirs must be copied because it is mutated in the # recursive call. for subdir in frozenset(self._directory_to_subdirs[path]): self._remove_watch_for_path(subdir) del self._watch_to_directory[wd] del self._directory_to_watch_descriptor[path] del self._directory_to_subdirs[path] del self._directory_to_rootdir[path]
def _create(netns, libc=None): libc = libc or ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True) netnspath = _get_netnspath(netns) netnsdir = os.path.dirname(netnspath) # init netnsdir try: os.mkdir(netnsdir) except OSError as e: if e.errno != errno.EEXIST: raise # this code is ported from iproute2 done = False while libc.mount(b'', netnsdir, b'none', MS_SHARED | MS_REC, None) != 0: if done: raise OSError(ctypes.get_errno(), 'share rundir failed', netns) if libc.mount(netnsdir, netnsdir, b'none', MS_BIND, None) != 0: raise OSError(ctypes.get_errno(), 'mount rundir failed', netns) done = True # create mountpoint os.close(os.open(netnspath, os.O_RDONLY | os.O_CREAT | os.O_EXCL, 0)) # unshare if libc.unshare(CLONE_NEWNET) < 0: raise OSError(ctypes.get_errno(), 'unshare failed', netns) # bind the namespace if libc.mount(b'/proc/self/ns/net', netnspath, b'none', MS_BIND, None) < 0: raise OSError(ctypes.get_errno(), 'mount failed', netns)
def setresgid(rgid=-1, egid=-1, sgid=-1): rgid = ctypes.c_long(rgid) egid = ctypes.c_long(egid) sgid = ctypes.c_long(sgid) res = _libc.setresgid(rgid, egid, sgid) if res: raise OSError(ctypes.get_errno(), os.strerror(ctypes.get_errno()))
def setresuid(ruid=-1, euid=-1, suid=-1): ruid = ctypes.c_long(ruid) euid = ctypes.c_long(euid) suid = ctypes.c_long(suid) res = _libc.setresuid(ruid, euid, suid) if res: raise OSError(ctypes.get_errno(), os.strerror(ctypes.get_errno()))
def condPersonality(per=None): if per is None or per in ('noarch',): return if personality_defs.get(per, None) is None: return res = _libc.personality(personality_defs[per]) if res == -1: raise OSError(ctypes.get_errno(), os.strerror(ctypes.get_errno()))
def getresgid(): rgid = ctypes.c_long() egid = ctypes.c_long() sgid = ctypes.c_long() res = _libc.getresgid(ctypes.byref(rgid), ctypes.byref(egid), ctypes.byref(sgid)) if res: raise OSError(ctypes.get_errno(), os.strerror(ctypes.get_errno())) return (rgid.value, egid.value, sgid.value)
def _add_watch_for_path(self, path): # Must be called with _inotify_fd_lock held. logging.debug('_add_watch_for_path(%r)', path) if path not in self._directory_to_rootdir: # a newly created dir, perhaps self._directory_to_rootdir[path] = ( self._directory_to_rootdir[os.path.dirname(path)]) # Get the skip-files-re that applies to this subtree, if any. rootdir = self._directory_to_rootdir[path] skip_files_re = self._skip_files_re.get(rootdir) for dirpath, directories, _ in itertools.chain( [(os.path.dirname(path), [os.path.basename(path)], None)], os.walk(path, topdown=True, followlinks=True)): relative_dirpath = os.path.relpath(dirpath, rootdir) if relative_dirpath == '.': relative_dirpath = '' if relative_dirpath != '..': # never skip the top-level directory watcher_common.skip_ignored_dirs(directories, relative_dirpath, skip_files_re) # TODO: this is not an ideal solution as there are other ways for # symlinks to confuse our algorithm but a general solution is going to # be very complex and this is good enough to solve the immediate problem # with Dart's directory structure. watcher_common.skip_local_symlinks( self._real_directories, dirpath, directories) for directory in directories: directory_path = os.path.join(dirpath, directory) # dirpath cannot be used as the parent directory path because it is the # empty string for symlinks :-( parent_path = os.path.dirname(directory_path) watch_descriptor = _libc.inotify_add_watch( self._inotify_fd, ctypes.create_string_buffer(directory_path), _INTERESTING_INOTIFY_EVENTS) if watch_descriptor < 0: if ctypes.get_errno() == errno.ENOSPC: logging.warning( 'There are too many directories in your application for ' 'changes in all of them to be monitored. You may have to ' 'restart the development server to see some changes to your ' 'files.') return error = OSError('could not add watch for %r' % directory_path) error.errno = ctypes.get_errno() error.strerror = errno.errorcode[ctypes.get_errno()] error.filename = directory_path raise error if parent_path in self._directory_to_subdirs: self._directory_to_subdirs[parent_path].add(directory_path) self._watch_to_directory[watch_descriptor] = directory_path self._directory_to_watch_descriptor[directory_path] = watch_descriptor self._directory_to_subdirs[directory_path] = set() self._directory_to_rootdir[directory_path] = ( self._directory_to_rootdir[path])
def check(): # Check that connection is alive buf = ctypes.create_string_buffer(2) self._sys_recv(self._socket.fileno(), buf, 1, socket.MSG_DONTWAIT | socket.MSG_PEEK) if ctypes.get_errno() == errno.EAGAIN: ctypes.set_errno(0) return errno.EAGAIN return (ctypes.get_errno() if ctypes.get_errno() else errno.ECONNRESET)
def _open_for_cpu(cpu, attr): pfd = Perf.syscall(Perf.NR_PERF_EVENT_OPEN, ct.byref(attr), -1, cpu, -1, Perf.PERF_FLAG_FD_CLOEXEC) if pfd < 0: errno_ = ct.get_errno() raise OSError(errno_, os.strerror(errno_)) if Perf.ioctl(pfd, Perf.PERF_EVENT_IOC_SET_FILTER, "common_pid == -17") < 0: errno_ = ct.get_errno() raise OSError(errno_, os.strerror(errno_)) if Perf.ioctl(pfd, Perf.PERF_EVENT_IOC_ENABLE, 0) < 0: errno_ = ct.get_errno() raise OSError(errno_, os.strerror(errno_))
def start(self): """Start watching the directory for changes.""" self._class_setup() self._inotify_fd = InotifyFileWatcher._libc.inotify_init() if self._inotify_fd < 0: error = OSError('failed call to inotify_init') error.errno = ctypes.get_errno() error.strerror = errno.errorcode[ctypes.get_errno()] raise error self._add_watch_for_path(self._directory)
def attach_raw_socket(fn, dev): if not isinstance(fn, BPF.Function): raise Exception("arg 1 must be of type BPF.Function") sock = lib.bpf_open_raw_sock(dev.encode("ascii")) if sock < 0: errstr = os.strerror(ct.get_errno()) raise Exception("Failed to open raw device %s: %s" % (dev, errstr)) res = lib.bpf_attach_socket(sock, fn.fd) if res < 0: errstr = os.strerror(ct.get_errno()) raise Exception("Failed to attach BPF to device %s: %s" % (dev, errstr)) fn.sock = sock
def _asm_func(self, restype=None, argtypes=(), byte_code=[]): global is_windows byte_code = bytes.join(b'', byte_code) address = None if is_windows: # Allocate a memory segment the size of the byte code, and make it executable size = len(byte_code) MEM_COMMIT = ctypes.c_ulong(0x1000) PAGE_EXECUTE_READWRITE = ctypes.c_ulong(0x40) address = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_size_t(size), MEM_COMMIT, PAGE_EXECUTE_READWRITE) if not address: raise Exception("Failed to VirtualAlloc") # Copy the byte code into the memory segment memmove = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t)(ctypes._memmove_addr) if memmove(address, byte_code, size) < 0: raise Exception("Failed to memmove") else: # Allocate a memory segment the size of the byte code size = len(byte_code) address = libc.valloc(size) if not address: errno = ctypes.get_errno() errmsg = os.strerror(errno) raise Exception("Failed to valloc (%d: %s)" % (errno, errmsg)) # Mark the memory segment as writeable only if not self.is_selinux_enforcing: WRITE = 0x2 if libc.mprotect(address, size, WRITE) < 0: errno = ctypes.get_errno() errmsg = os.strerror(errno) raise Exception("Failed to mprotect (%d: %s)" % (errno, errmsg)) # Copy the byte code into the memory segment if libc.memmove(address, byte_code, size) < 0: errno = ctypes.get_errno() errmsg = os.strerror(errno) raise Exception("Failed to memmove (%d: %s)" % (errno, errmsg)) # Mark the memory segment as writeable and executable only if not self.is_selinux_enforcing: WRITE_EXECUTE = 0x2 | 0x4 if libc.mprotect(address, size, WRITE_EXECUTE) < 0: errno = ctypes.get_errno() errmsg = os.strerror(errno) raise Exception("Failed to mprotect (%d: %s)" % (errno, errmsg)) # Cast the memory segment into a function functype = ctypes.CFUNCTYPE(restype, *argtypes) fun = functype(address) return fun, address
def check(): # Check that connection is alive buf = ctypes.create_string_buffer(2) try: sock_fd = self._socket.fileno() except socket.error as e: if e.errno == errno.EBADF: return errno.ECONNRESET else: self._sys_recv(sock_fd, buf, 1, socket.MSG_DONTWAIT | socket.MSG_PEEK) if ctypes.get_errno() == errno.EAGAIN: ctypes.set_errno(0) return errno.EAGAIN return (ctypes.get_errno() if ctypes.get_errno() else errno.ECONNRESET)
def _get_next_event(self): _reset_event(self.event_buffer) last = _next_event(self.binlog_parser_handle, self.event_buffer) if last < 0: raise NextEventError(ctypes.get_errno()) et = _event_type(self.event_buffer) base_event = Event(et, self.event_buffer.contents.offset, self.event_buffer.contents.timestamp) # TODO: check this on the C side if self.event_buffer.contents.data is None: raise EmptyEventError() if et == "QUERY_EVENT": query_event = _event_to_safe_qe(self.event_buffer) base_event.data = QueryEvent(query_event.contents.db_name, query_event.contents.statement, query_event.contents.query_time) _dispose_safe_qe(query_event) elif et == "ROTATE_EVENT": rotate_event = _event_to_safe_re(self.event_buffer) base_event.data = RotateEvent(rotate_event.contents.next_position, rotate_event.contents.file_name) _dispose_safe_re(rotate_event) elif et == "XID_EVENT": xid_event = _event_to_safe_xe(self.event_buffer) base_event.data = XIDEvent(xid_event.contents.id) _dispose_safe_xe(xid_event) return (base_event, last == 0)
def mount(source, target, fs, flags=0): if ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True ).mount(source, target, fs, flags) < 0: log.error("Failed to mount {} ({}) to {} with flags {}: {}". format(source, fs, target, flags, os.strerror(ctypes.get_errno()))) exit(1)
def init(): if we.libcomcom_python_init() == -1: raise OSError(ctypes.get_errno())
def destroy(): if lib.libcomcom_destroy() == -1: raise OSError(ctypes.get_errno())
def _errcheck(result, func, args): if result: errnum = ctypes.get_errno() raise OSError(errnum, os.strerror(errnum)) if func is not _settime: return tuple(args[1])
def handle_error(self): eno = ctypes.get_errno() extra = '' if eno == errno.ENOSPC: extra = 'You may need to increase the inotify limits on your system, via /proc/sys/fs/inotify/max_user_*' raise OSError(eno, self.os.strerror(eno) + str(extra))
def raise_on_nanomsg_error(errorcode): from nanomsg import nn_strerror import ctypes if errorcode < 0: raise RuntimeError(nn_strerror(ctypes.get_errno()))
def test_find_ext_caps(): offset = vfu_pci_find_capability(ctx, True, PCI_EXT_CAP_ID_DSN) assert offset == cap_offsets[0] space = get_pci_ext_cfg_space(ctx) cap_id, cap_next = ext_cap_hdr(space, offset) assert cap_id == PCI_EXT_CAP_ID_DSN assert cap_next == cap_offsets[1] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_DSN) assert offset == 0 offset = vfu_pci_find_capability(ctx, True, PCI_EXT_CAP_ID_VNDR) assert offset == cap_offsets[1] cap_id, cap_next = ext_cap_hdr(space, offset) assert cap_id == PCI_EXT_CAP_ID_VNDR assert cap_next == cap_offsets[2] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_DSN) assert offset == 0 offset = vfu_pci_find_next_capability(ctx, True, 0, PCI_EXT_CAP_ID_VNDR) assert offset == cap_offsets[1] cap_id, cap_next = ext_cap_hdr(space, offset) assert cap_id == PCI_EXT_CAP_ID_VNDR assert cap_next == cap_offsets[2] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_VNDR) assert offset == cap_offsets[2] cap_id, cap_next = ext_cap_hdr(space, offset) assert cap_id == PCI_EXT_CAP_ID_VNDR assert cap_next == cap_offsets[3] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_VNDR) assert offset == cap_offsets[3] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_VNDR) assert offset == cap_offsets[4] offset = vfu_pci_find_next_capability(ctx, True, offset, PCI_EXT_CAP_ID_VNDR) assert offset == 0 # check for invalid offsets offset = vfu_pci_find_next_capability(ctx, True, 8192, PCI_EXT_CAP_ID_DSN) assert offset == 0 assert c.get_errno() == errno.EINVAL offset = vfu_pci_find_next_capability(ctx, True, 4096, PCI_EXT_CAP_ID_DSN) assert offset == 0 assert c.get_errno() == errno.EINVAL offset = vfu_pci_find_next_capability(ctx, True, 4095, PCI_EXT_CAP_ID_DSN) assert offset == 0 assert c.get_errno() == errno.EINVAL offset = vfu_pci_find_next_capability(ctx, True, cap_offsets[1] + 1, PCI_EXT_CAP_ID_DSN) assert offset == 0 assert c.get_errno() == errno.ENOENT
if err < 0: raise Exception("Set scan parameters failed") # occurs when scanning is still enabled from previous call # allows LE advertising events hci_filter = struct.pack("<IQH", 0x00000010, 0x4000000000000000, 0) sock.setsockopt(SOL_HCI, HCI_FILTER, hci_filter) err = bluez.hci_le_set_scan_enable( sock.fileno(), 1, # 1 - turn on; 0 - turn off 0, # 0-filtering disabled, 1-filter out duplicates 1000 # timeout ) if err < 0: errnum = get_errno() raise Exception("{} {}".format(errno.errorcode[errnum], os.strerror(errnum))) #This function scans the stream of data from the socket and checks to see if any of the addresses that it finds match the address of the Atmotube. If so, it reads the rest of the packet, picks out the data, and returns the voc, humidity, and temperature. def scan(): voc = 0.0 humidity = 0 temperature = 0.0 is_done = False start_time = time.time() while not is_done: current_time = time.time() data = sock.recv(1024) #Get bluetooth address fr. BLE advertising packet
bits = "64bit" processor = "x86_64" elif processor == "Power Macintosh": processor = "ppc" bits = re.search('(\d+)bit', bits).group(1) info.update({'processor': processor, 'bits': int(bits), }) if info['os'] == 'linux': import ctypes import errno PR_SET_SECCOMP = 22 SECCOMP_MODE_FILTER = 2 ctypes.CDLL("libc.so.6", use_errno=True).prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0) info['has_sandbox'] = ctypes.get_errno() == errno.EFAULT else: info['has_sandbox'] = True # standard value of choices, for easy inspection choices = {'os': ['linux', 'bsd', 'win', 'mac', 'unix'], 'bits': [32, 64], 'processor': ['x86', 'x86_64', 'ppc']} def sanitize(info): """Do some sanitization of input values, primarily to handle universal Mac builds.""" if "processor" in info and info["processor"] == "universal-x86-x86_64": # If we're running on OS X 10.6 or newer, assume 64-bit if release[:4] >= "10.6": # Note this is a string comparison
def get_errno(self): return ctypes.get_errno()
def _check(rv, path=None): if rv < 0: raise OSError(get_errno(), path) return rv
def _get_next_event(self): _reset_event(self.event_buffer) last = _next_event(self.binlog_parser_handle, self.event_buffer) if last < 0: raise NextEventError(ctypes.get_errno()) return build_event(self.event_buffer), last == 0
def _checkNull(result, func, arguments): if result: return result else: err = get_last_error() if 'Windows' in _system() else get_errno() raise OSError(err, _strerror(err))
def __call__(self, *args): ret = self.f(*args) if not ret and get_errno(): raise PyperclipWindowsException("Error calling " + self.f.__name__) return ret
def csp_err_negative(result, func, args): if result != 0: raise CspException(os.strerror(ctypes.get_errno())) else: return result
def _raise_changelog_err(): errn = get_errno() raise ChangelogException(errn, os.strerror(errn))
def readSPI(port, count): buffer = (C.c_uint8 * count)() rv = _readSPI(port, buffer, count) if rv < 0: raise IOError(_os.strerror(C.get_errno())) return buffer[:]
def posix_error(filename): errno = ctypes.get_errno() exc = OSError(errno, strerror(errno)) exc.filename = filename return exc
def readI2C(port, deviceAddress, count): buffer = (C.c_uint8 * count)() rv = _readI2C(port, deviceAddress, buffer, count) if rv < 0: raise IOError(_os.strerror(C.get_errno())) return buffer[:]
def unshare(flags): libc = ctypes.CDLL("libc.so.6", use_errno=True) if libc.unshare(ctypes.c_int(flags)): errno = ctypes.get_errno() raise OSError(errno, os.strerror(errno))
def writeI2C(port, deviceAddress, dataToSend): sendSize = len(dataToSend) buffer = (C.c_uint8 * sendSize)(*dataToSend) rv = _writeI2C(port, deviceAddress, buffer, sendSize) if rv < 0: raise IOError(_os.strerror(C.get_errno()))
def errno(): return ctypes.get_errno()
def get_darwin_ifaddrs(): """ Enumerates all network interfaces and all IP addresses assigned for each interfaces both IPv4 and IPv6 on Macintosh host :return: list of NetworkInterface """ from socket import AF_INET, AF_INET6, inet_ntop from ctypes import (Structure, Union, POINTER, pointer, get_errno, cast, c_ushort, c_byte, c_uint8, c_void_p, c_char_p, c_uint, c_int, c_uint16, c_uint32) import ctypes.util import ctypes class struct_sockaddr(Structure): _fields_ = [ ('sa_len', c_uint8), ('sa_family', c_uint8), ('sa_data', c_byte * 14), ] class struct_sockaddr_in(Structure): _fields_ = [ ('sin_len', c_uint8), ('sin_family', c_uint8), ('sin_port', c_uint16), ('sin_addr', c_uint8 * 4), ('sin_zero', c_byte * 8), ] class struct_sockaddr_in6(Structure): _fields_ = [('sin6_len', c_uint8), ('sin6_family', c_ushort), ('sin6_port', c_uint16), ('sin6_flowinfo', c_uint32), ('sin6_addr', c_byte * 16), ('sin6_scope_id', c_uint32)] """ class union_ifa_ifu(Union): _fields_ = [ ('ifu_broadaddr', POINTER(struct_sockaddr)), ('ifu_dstaddr', POINTER(struct_sockaddr)),] """ class struct_ifaddrs(Structure): pass struct_ifaddrs._fields_ = [ ('ifa_next', POINTER(struct_ifaddrs)), ('ifa_name', c_char_p), ('ifa_flags', c_uint), ('ifa_addr', POINTER(struct_sockaddr)), ('ifa_netmask', POINTER(struct_sockaddr)), ('ifa_dstaddr', POINTER(struct_sockaddr)), ('ifa_data', c_void_p), ] libc = ctypes.CDLL(ctypes.util.find_library('c')) def ifap_iter(ifap): ifa = ifap.contents while True: yield ifa if not ifa.ifa_next: break ifa = ifa.ifa_next.contents def getfamaddr(sa): family = sa.sa_family addr = None if family == AF_INET: sa = cast(pointer(sa), POINTER(struct_sockaddr_in)).contents addr = inet_ntop(family, sa.sin_addr) elif family == AF_INET6: sa = cast(pointer(sa), POINTER(struct_sockaddr_in6)).contents addr = inet_ntop(family, sa.sin6_addr) return family, addr ifap = POINTER(struct_ifaddrs)() result = libc.getifaddrs(pointer(ifap)) if result != 0: raise OSError(get_errno()) del result try: interfacesd = {} for ifa in ifap_iter(ifap): ifname = ifa.ifa_name.decode("UTF-8") if ifname not in interfacesd: interfacesd[ifname] = NetworkInterface() interfacesd[ifname].ifname = ifname interfacesd[ifname].ifindex = libc.if_nametoindex(ifname) family, addr = getfamaddr(ifa.ifa_addr.contents) interfacesd[ifname].addresses.append(ipaddress.ip_address(addr)) return interfacesd finally: libc.freeifaddrs(ifap)
def unshare_mounts(): return_value = _libc.unshare(CLONE_NEWNS) if 0 != return_value: errno_val = ctypes.get_errno() raise OSError("unshare() called failed (errno={0} ({1}))".format( errno_val, errno.errorcode.get(errno_val, "?")))
def _chk_int(res, func, args, gt0=False): if res < 0 or (gt0 and res == 0): errno_ = ctypes.get_errno() raise NFLogError(errno_, os.strerror(errno_)) return res
def check_status(result, function, arguments): if result < 0: raise can.CanError(error_code_to_str(ctypes.get_errno())) return result
def res_timerfd_settime(r): if r == -1: raise OSError(ctypes.get_errno()) assert r >= 0 return r
def res_timerfd_create(fd): if fd == -1: raise OSError(ctypes.get_errno()) assert fd >= 0 return fd
def enter(read_fd, write_fd, rootfs=None, binds=None, qemu=None, identity=None, cwd=None): """ Chroot into rootfs with a new user and mount namespace, then execute the desired command. """ # pylint: disable=too-many-locals,too-many-statements if not binds: binds = [] if not identity: identity = [0, 0] if not cwd: cwd = '/' glibc = get_glibc() uid = glibc.getuid() gid = glibc.getgid() logging.debug("Before unshare, uid=%d, gid=%d\n", uid, gid) # --------------------------------------------------------------------- # Create User Namespace # --------------------------------------------------------------------- # First, unshare the user namespace and assume admin capability in the # new namespace err = glibc.unshare(glibc.CLONE_NEWUSER) if err != 0: raise OSError(err, "Failed to unshared user namespace", None) # write a uid/pid map pid = glibc.getpid() logging.debug("My pid: %d\n", pid) # Notify the helper that we have created the new namespace, and we need # it to set our uid/gid map logging.debug("Waiting for helper to set my uid/gid map") os.write(write_fd, "#") # Wait for the helper to finish setting our uid/gid map os.read(read_fd, 1) logging.debug("Helper has finished setting my uid/gid map") # --------------------------------------------------------------------- # Create Mount Namespace # --------------------------------------------------------------------- err = glibc.unshare(glibc.CLONE_NEWNS) if err != 0: logging.error('Failed to unshare mount namespace') null_ptr = ctypes.POINTER(ctypes.c_char)() for bind_spec in binds: if isinstance(bind_spec, (list, tuple)): source, dest = bind_spec elif ':' in bind_spec: source, dest = bind_spec.split(':') else: source = bind_spec dest = bind_spec dest = dest.lstrip('/') rootfs_dest = os.path.join(rootfs, dest) logging.debug('Binding: %s -> %s', source, rootfs_dest) assert os.path.exists(source),\ "source directory to bind does not exit {}".format(source) # Create the mountpoint if it is not already in the rootfs if os.path.isdir(source): make_sure_is_dir(rootfs_dest, source) else: make_sure_is_file(rootfs_dest, source) if source.lstrip('/') == 'proc': # NOTE(josh): user isn't allowed to mount proc without MS_REC, see # https://stackoverflow.com/a/23435317 result = glibc.mount(source, rootfs_dest, "proc", glibc.MS_REC | glibc.MS_BIND, null_ptr) else: result = glibc.mount(source, rootfs_dest, null_ptr, glibc.MS_BIND, null_ptr) if result == -1: err = ctypes.get_errno() logging.warn('Failed to mount %s -> %s [%s](%d) %s', source, rootfs_dest, errno.errorcode.get(err, '??'), err, os.strerror(err)) if qemu: dest = qemu.lstrip('/') rootfs_dest = os.path.join(rootfs, dest) make_sure_is_dir(os.path.dirname(rootfs_dest), qemu) logging.debug("Installing %s", qemu) with open(rootfs_dest, 'wb') as outfile: with open(qemu, 'rb') as infile: chunk = infile.read(1024 * 4) while chunk: outfile.write(chunk) chunk = infile.read(1024 * 4) os.chmod(rootfs_dest, 0o755) # --------------------------------------------------------------------- # Chroot # --------------------------------------------------------------------- # Now chroot into the desired directory err = glibc.chroot(rootfs) if err != 0: logging.error("Failed to chroot") raise OSError(err, "Failed to chroot", rootfs) # Set the cwd os.chdir(cwd) # Now drop admin in our namespace err = glibc.setresuid(identity[0], identity[0], identity[0]) if err != 0: logging.error("Failed to set uid") err = glibc.setresgid(identity[1], identity[1], identity[1]) if err: logging.error("Failed to set gid\n")
def _time(): if _clock_gettime(ctypes.c_long(_clockid), ctypes.pointer(tv)) != 0: _ernno = ctypes.get_errno() raise OSError(_ernno, strerror(_ernno)) return tv.tv_sec + (tv.tv_usec * 0.000000001)
def monotonic_time(): t = Time.timespec() if Time.clock_gettime(Time.CLOCK_MONOTONIC_RAW, ct.pointer(t)) != 0: errno_ = ct.get_errno() raise OSError(errno_, os.strerror(errno_)) return t.tv_sec * 1e9 + t.tv_nsec