async def op(sem: RAM) -> t.Tuple[WrittenPointer[Path], WrittenPointer[ArgList], WrittenPointer[ArgList]]: argv_ptrs = ArgList([await sem.ptr(Arg(arg)) for arg in argv]) envp_ptrs = ArgList([await sem.ptr(Arg(arg)) for arg in envp]) return (await sem.ptr(path), await sem.ptr(argv_ptrs), await sem.ptr(envp_ptrs))
async def op(sem: RAM) -> t.Tuple[WrittenPointer[t.Union[str, os.PathLike]], WrittenPointer[ArgList], WrittenPointer[ArgList]]: argv_ptrs = ArgList([await sem.ptr(arg) for arg in argv]) envp_ptrs = ArgList([await sem.ptr(arg) for arg in envp]) return (await sem.ptr(path), await sem.ptr(argv_ptrs), await sem.ptr(envp_ptrs))
async def as_arglist(self, task: Task) -> WrittenPointer[ArgList]: if self.arglist_ptr is None: envp = ['='.join([key, value]) for key, value in self.data.items()] envp_ptrs = [await task.ptr(arg) for arg in envp] ptr = await task.ptr(ArgList(envp_ptrs)) ptr, *envp_ptrs = await share_pointers([ptr, *envp_ptrs]) # we could just do two calls to share_pointers (one before task.ptr), but that adds a little latency, # so instead we do this horrible abstraction-break # TODO think about how to do this safely and abstractly ptr.value = ArgList(envp_ptrs) self.arglist_ptr = ptr return self.arglist_ptr
async def _execve( self, path: t.Union[str, os.PathLike], argv: t.List[str], envp: t.List[str], command: Command = None, ) -> AsyncChildPid: "Call execve, abstracting over memory; self.{exec,execve} are probably preferable" filename = await self.ptr(path) argv_ptr = await self.ptr( ArgList([await self.ptr(arg) for arg in argv])) envp_ptr = await self.ptr( ArgList([await self.ptr(arg) for arg in envp])) await self.task.execve(filename, argv_ptr, envp_ptr, command=command) return self.pid
async def execv( self, path: t.Union[str, os.PathLike], argv: t.Sequence[t.Union[str, os.PathLike]], command: Command = None, ) -> AsyncChildPid: """Replace the running executable in this process with another; see execve. """ filename_ptr = await self.ptr(path) argv_ptr = await self.ptr( ArgList([await self.ptr(arg) for arg in argv])) envp_ptr = await self.environ.as_arglist(self.task) await self.task.execve(filename_ptr, argv_ptr, envp_ptr, command=command) return self.pid
async def op(sem: RAM) -> WrittenPointer[ArgList]: envp_ptrs = ArgList([await sem.ptr(arg) for arg in envp]) return await sem.ptr(envp_ptrs)