FreeRDP
Loading...
Searching...
No Matches
test_qt_aad_auth_helper.HelperProcess Class Reference

Public Member Functions

 __init__ (self, helper_path, env)
 
 request (self, method, params=None, timeout=REQUEST_TIMEOUT)
 
 notify (self, method, params=None)
 
 wait (self, timeout=10)
 

Data Fields

 proc
 

Protected Member Functions

 _read_loop (self)
 

Protected Attributes

 _in
 
 _out
 
 _lines
 
 _reader
 
 _next_id
 

Detailed Description

Definition at line 75 of file test_qt_aad_auth_helper.py.

Constructor & Destructor Documentation

◆ __init__()

test_qt_aad_auth_helper.HelperProcess.__init__ (   self,
  helper_path,
  env 
)

Definition at line 76 of file test_qt_aad_auth_helper.py.

76 def __init__(self, helper_path, env):
77 # the JSON-RPC channel: two pipes, their read/write ends handed to the helper via
78 # --cmdInFd=/--cmdOutFd= - not stdin/stdout, which are left as a normal passthrough so
79 # the helper's own Qt/Chromium diagnostic output doesn't collide with the protocol. The
80 # value must be encoded exactly like winpr_exportHandleToString() does it (see
81 # winpr/libwinpr/handle/handle.c), which differs by platform: on POSIX it's a 'P' type
82 # tag followed by the fd in hex; on Windows (no type tag there) it's the native HANDLE
83 # value in hex - a Windows CRT fd from os.pipe() is not that HANDLE, so it must be
84 # resolved via msvcrt.get_osfhandle() first, and marked inheritable since Windows has no
85 # equivalent of POSIX's pass_fds.
86 cmd_in_r, cmd_in_w = os.pipe()
87 cmd_out_r, cmd_out_w = os.pipe()
88
89 if sys.platform == "win32":
90 cmd_in_handle = msvcrt.get_osfhandle(cmd_in_r)
91 cmd_out_handle = msvcrt.get_osfhandle(cmd_out_w)
92 os.set_handle_inheritable(cmd_in_handle, True)
93 os.set_handle_inheritable(cmd_out_handle, True)
94 cmd_in_arg = f"--cmdInFd={cmd_in_handle:x}"
95 cmd_out_arg = f"--cmdOutFd={cmd_out_handle:x}"
96 # pass_fds is POSIX-only; close_fds=False lets CreateProcess(bInheritHandles=TRUE)
97 # inherit every inheritable handle in this process, which - since os.pipe() creates
98 # non-inheritable handles by default and only the two above were just flipped to
99 # inheritable - is just these two.
100 popen_kwargs = {"close_fds": False}
101 else:
102 cmd_in_arg = f"--cmdInFd=P{cmd_in_r:x}"
103 cmd_out_arg = f"--cmdOutFd=P{cmd_out_w:x}"
104 popen_kwargs = {"close_fds": True, "pass_fds": (cmd_in_r, cmd_out_w)}
105
106 self.proc = subprocess.Popen(
107 [helper_path, cmd_in_arg, cmd_out_arg],
108 stdin=subprocess.DEVNULL,
109 stdout=None,
110 stderr=None,
111 env=env,
112 **popen_kwargs,
113 )
114 os.close(cmd_in_r)
115 os.close(cmd_out_w)
116 self._in = os.fdopen(cmd_in_w, "w", buffering=1)
117 self._out = os.fdopen(cmd_out_r, "r")
118 self._lines = queue.Queue()
119 self._reader = threading.Thread(target=self._read_loop, daemon=True)
120 self._reader.start()
121 self._next_id = 0
122

Member Function Documentation

◆ _read_loop()

test_qt_aad_auth_helper.HelperProcess._read_loop (   self)
protected

Definition at line 123 of file test_qt_aad_auth_helper.py.

123 def _read_loop(self):
124 for line in self._out:
125 line = line.strip()
126 if line:
127 self._lines.put(line)
128

◆ notify()

test_qt_aad_auth_helper.HelperProcess.notify (   self,
  method,
  params = None 
)

Definition at line 153 of file test_qt_aad_auth_helper.py.

153 def notify(self, method, params=None):
154 msg = {"jsonrpc": "2.0", "method": method}
155 if params is not None:
156 msg["params"] = params
157 self._in.write(json.dumps(msg) + "\n")
158 self._in.flush()
159

◆ request()

test_qt_aad_auth_helper.HelperProcess.request (   self,
  method,
  params = None,
  timeout = REQUEST_TIMEOUT 
)

Definition at line 129 of file test_qt_aad_auth_helper.py.

129 def request(self, method, params=None, timeout=REQUEST_TIMEOUT):
130 self._next_id += 1
131 req_id = self._next_id
132 msg = {"jsonrpc": "2.0", "id": req_id, "method": method}
133 if params is not None:
134 msg["params"] = params
135 self._in.write(json.dumps(msg) + "\n")
136 self._in.flush()
137
138 deadline = time.monotonic() + timeout
139 while True:
140 remaining = deadline - time.monotonic()
141 if remaining <= 0:
142 break
143 try:
144 line = self._lines.get(timeout=remaining)
145 except queue.Empty:
146 break
147 reply = json.loads(line)
148 if reply.get("id") == req_id:
149 return reply
150 # notification or stray reply for a different id: ignore, keep waiting
151 raise TimeoutError(f"no reply to {method!r} within {timeout}s")
152

◆ wait()

test_qt_aad_auth_helper.HelperProcess.wait (   self,
  timeout = 10 
)

Definition at line 160 of file test_qt_aad_auth_helper.py.

160 def wait(self, timeout=10):
161 return self.proc.wait(timeout=timeout)
162
163

Field Documentation

◆ _in

test_qt_aad_auth_helper.HelperProcess._in
protected

◆ _lines

test_qt_aad_auth_helper.HelperProcess._lines
protected

Definition at line 118 of file test_qt_aad_auth_helper.py.

◆ _next_id

test_qt_aad_auth_helper.HelperProcess._next_id
protected

Definition at line 121 of file test_qt_aad_auth_helper.py.

◆ _out

test_qt_aad_auth_helper.HelperProcess._out
protected

◆ _reader

test_qt_aad_auth_helper.HelperProcess._reader
protected

Definition at line 119 of file test_qt_aad_auth_helper.py.

◆ proc

test_qt_aad_auth_helper.HelperProcess.proc

Definition at line 106 of file test_qt_aad_auth_helper.py.


The documentation for this class was generated from the following file: