import asyncio import functools import json import struct async def get_user_home(name:str): # Check args if not isinstance(name, str): raise TypeError("name have to be a string.") # Find home proc = await asyncio.create_subprocess_exec(b"getent", b"passwd", name.encode(), stdout=asyncio.subprocess.PIPE) proc_data = proc.communicate() if not isinstance(proc_data, tuple): raise RuntimeError("Internal value isn't the expected type.") if proc.returncode != 0: raise RuntimeError("getent didn't work.") return proc_data[0].split(":")[6] async def run_access_socket(path:str, async_callback): async def run_func(read, write): # Get user id socket = write.get_extra_info("socket") tmp = socket.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize('3i')) tmp = struct.unpack('3i', tmp)[1] uid = str(tmp) # Run callback await async_callback(read, write, uid) await (await asyncio.start_unix_server(run_func, path=path)).serve_forever() _format_length = struct.Struct(">I") def rpc_callback(async_func): @functools.wraps(async_func) async def wrap_func(read, write, uid): while not read.at_eof(): # Read data size = _format_length.unpack(await read.readexactly(_format_length.size)) data = json.loads((await read.readexactly(size)).decode("UTF-8")) # Callback and return result result = json.dumps(await async_func(data, uid)).encode("UTF-8") write.write(_format_length.pack(len(result))) write.write(result) return wrap_func