def import_node(self, id, row): assert id not in self.node_cache_ if not row[4]: folder = None elif type(row[4]) is nodetypes.Entry: folder = row[4] else: folder = self.query_node(row[4]) if not row[5]: blob = None else: blob = util.Unpickle(row[5]) node = Entry(id=id, type=row[0], path=row[3], blob=blob, folder=folder, stamp=row[1], dirty=row[2]) self.node_cache_[id] = node if node.path: assert node.path not in self.path_cache_ self.path_cache_[node.path] = node return node
def load_environments(self): query = "SELECT rowid, data FROM environments" for row in self.cn.execute(query): # Note, populating the cache is mandatory otherwise. Otherwise, when the # generator populates its cache, it might give us back an env_id that # we've never seen. Another indicaton that Database is misdesigned. tools_env = nodetypes.ToolsEnv(row[0], util.Unpickle(row[1])) self.env_cache_[tools_env.env_id] = tools_env self.env_reverse_lookup_[tools_env.env_data] = tools_env
def fetch_environment(self, env_id): if env_id in self.env_cache_: return self.env_cache_[env_id] query = "SELECT data FROM environments WHERE rowid = ?" cursor = self.cn.execute(query, (env_id, )) row = cursor.fetchone() if not row: raise Exception( 'Database error, invalid environment id {}'.format(env_id)) tools_env = nodetypes.ToolsEnv(env_id, util.Unpickle(row[0])) self.env_cache_[env_id] = tools_env self.env_reverse_lookup_[tools_env.env_data] = tools_env return tools_env
def recv_impl(self): header = self.recv_all(8) if header == None: return None size, nfds = struct.unpack('ii', header) if nfds == 0: data = self.recv_all(size) return util.pickle.loads(data) iov_base = (ctypes.c_byte * size)() iovec = iovec_t() msg = msghdr_t() msg.msg_iov = ctypes.pointer(iovec) msg.msg_iovlen = 1 # Construct a buffer for the ancillary data. This is pretty arbitrary. cmsg_base = (ctypes.c_byte * 512)() msg.msg_control = ctypes.cast(cmsg_base, ctypes.c_void_p) channels = [] received = 0 while received < size: iovec.iov_base = ctypes.addressof(iov_base) + received iovec.iov_len = size - received msg.msg_controllen = len(cmsg_base) res = recvmsg(self.sock.fileno(), ctypes.pointer(msg), 0) check_errno(res) received += res if msg.msg_flags & MSG_CTRUNC: raise Exception('message control or ancillary data was truncated') # Min struct size is 12. if msg.msg_controllen >= 12: cmsg = ctypes.cast(msg.msg_control, cmsghdr_base_t_p) while cmsg: if cmsg.contents.cmsg_level == SOL_SOCKET and cmsg.contents.cmsg_type == SCM_RIGHTS: # Grab the file descriptors. wire_fds = (cmsg.contents.cmsg_len - ctypes.sizeof(cmsg.contents)) // 4 cmsg_t, cmsg_len = cmsghdr_type_for_n(wire_fds) cmsg_t_p = ctypes.POINTER(cmsg_t) cmsg = ctypes.cast(ctypes.addressof(cmsg.contents), cmsg_t_p) for i in range(wire_fds): fd = cmsg.contents.cmsg_data[i] channel = SocketChannel.fromfd('<recvd-unknown>', fd) channels.append(channel) cmsg = CMSG_NXTHDR(msg, cmsg) if nfds != len(channels): raise Exception('expected ' + str(nfds) + ' channels, received ' + str(len(channels))) if bytes == str: message = util.Unpickle(ctypes.cast(iov_base, ctypes.c_char_p).value) else: message = util.Unpickle(bytes(iov_base)) message['channels'] = tuple(channels) return message