Files
rsync/testsuite/stdio_daemon.py
Zen Dodd 7ee931c7b9 daemon: distinguish inetd from local stdin sockets (#1075)
* daemon: require IP stream for inetd mode
* daemon: preserve bidirectional stdio mode
* daemon: honour explicit no-detach mode
* daemon: preserve inetd socket detection
* ci: fix daemon socket checks
2026-09-11 09:10:18 +10:00

75 lines
2.1 KiB
Python

"""Launch one rsync daemon session over a loopback TCP connection."""
import socket
import subprocess
import rsync_proto as rp
from rsyncfns import rsync_argv
def _client_for_socket(sock, timeout=10):
client = object.__new__(rp.DaemonClient)
client.sock = sock
client.sock.settimeout(timeout)
client.protocol = rp.DEFAULT_PROTOCOL
client.compat_flags = None
client.seed = None
client.xfer_sum_len = 16
client._rbuf = b''
client._ndx_prev_positive = -1
client._ndx_prev_negative = 1
client._mux_in = b''
client._r_ndx_prev_positive = -1
client._r_ndx_prev_negative = 1
client.messages = []
return client
def start_stdio_daemon(conf, timeout=10, env=None):
"""Return ``(DaemonClient, Popen)`` for one daemon connection."""
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
parent = None
try:
listener.bind(('127.0.0.1', 0))
listener.listen(1)
parent = socket.create_connection(listener.getsockname(), timeout)
child, _ = listener.accept()
except OSError:
if parent is not None:
parent.close()
raise
finally:
listener.close()
try:
proc = subprocess.Popen(
rsync_argv('--daemon', '--no-detach', f'--config={conf}'),
stdin=child.fileno(), stdout=child.fileno(),
stderr=subprocess.PIPE, close_fds=True, env=env,
)
except Exception:
parent.close()
child.close()
raise
child.close()
return _client_for_socket(parent, timeout), proc
def finish_stdio_daemon(client, proc, timeout=5):
"""Close a test session and return the daemon's stderr text."""
try:
client.drain(timeout=0.25)
except OSError:
pass
client.close()
try:
proc.wait(timeout=timeout)
except subprocess.TimeoutExpired:
proc.terminate()
try:
proc.wait(timeout=timeout)
except subprocess.TimeoutExpired:
proc.kill()
proc.wait(timeout=timeout)
return proc.stderr.read().decode('utf-8', 'replace') if proc.stderr else ''