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 74 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 75 of file test_qt_aad_auth_helper.py.

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

Member Function Documentation

◆ _read_loop()

test_qt_aad_auth_helper.HelperProcess._read_loop (   self)
protected

Definition at line 122 of file test_qt_aad_auth_helper.py.

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

◆ notify()

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

Definition at line 152 of file test_qt_aad_auth_helper.py.

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

◆ request()

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

Definition at line 128 of file test_qt_aad_auth_helper.py.

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

◆ wait()

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

Definition at line 159 of file test_qt_aad_auth_helper.py.

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

Field Documentation

◆ _in

test_qt_aad_auth_helper.HelperProcess._in
protected

◆ _lines

test_qt_aad_auth_helper.HelperProcess._lines
protected

Definition at line 117 of file test_qt_aad_auth_helper.py.

◆ _next_id

test_qt_aad_auth_helper.HelperProcess._next_id
protected

Definition at line 120 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 118 of file test_qt_aad_auth_helper.py.

◆ proc

test_qt_aad_auth_helper.HelperProcess.proc

Definition at line 105 of file test_qt_aad_auth_helper.py.


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