ipc: strip machinery no peer uses; keep client state in one Keyreq

ipc.c: an AF_UNIX nonblocking connect completes at once or fails with
EAGAIN, so the EINPROGRESS/poll/SO_ERROR path and the fcntl juggling
were dead; the deadline plumbing checked a clock that cannot fail and
re-tested the deadline before every transfer although only waitfd
blocks; readfield's truncation and discard loop served the unit test,
since every caller owns char[Ipcfieldmax+1]; NULL-argument checks on
in-tree encoders are gone (peer validation stays). The primary key frame
is Ipckey, not 'legacy'; ipckeysym names the keysym mapping.

srv.c: the per-connection capability and caret already lived in the
persistent Keyreq; the mirror locals and 'negotiated' flag guarded a
protocol rule no client relied on. proccreate never fails in libthread.

gtk: focus-out no longer round-trips a reset before closing the socket
that releases the engine; the caret dedup compares the packed frame;
srvconnect's preedit no-ops and the insimple flag are gone.
This commit is contained in:
2026-08-16 15:53:08 +09:00
parent 43b469f70b
commit eb0f88f764
11 changed files with 205 additions and 394 deletions

View File

@@ -169,13 +169,12 @@ allowrequest(Enginegate *g)
}
static int
readreply(struct ct *t, Testclient *client, int want, char *preedit, int npreedit)
readreply(struct ct *t, Testclient *client, int want, char *preedit)
{
char commit[Maxutf];
char commit[Ipcfieldmax+1];
Ipcresp resp;
if(ipcreadresp(client->peer, want, commit, sizeof commit,
preedit, npreedit, &resp) < 0)
if(ipcreadresp(client->peer, want, commit, preedit, &resp) < 0)
return CT_ERRORF(t, "response read failed: %s", strerror(errno));
CT_EQ_STR(t, "", commit);
return resp.eaten;
@@ -247,7 +246,7 @@ server_connection_ownership(struct ct *t)
Keyreq req;
Drawcmd dc;
Str shown;
char preedit[Maxutf];
char preedit[Ipcfieldmax+1];
void *aowner, *bowner, *cowner;
uchar byte, token;
ssize_t n;
@@ -279,14 +278,14 @@ server_connection_ownership(struct ct *t)
req = nextrequest(t, &gate, Keypress);
aowner = req.owner;
allowrequest(&gate);
CT_CHECK(t, readreply(t, &a, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "k", preedit);
if(!sendkey(t, &a, 1, 0, 'a'))
goto cleanup;
req = nextrequest(t, &gate, Keypress);
CT_EQ_PTR(t, aowner, req.owner);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &a, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "", preedit);
CT_EQ_PTR(t, aowner, testengineowner());
@@ -296,7 +295,7 @@ server_connection_ownership(struct ct *t)
bowner = req.owner;
CT_CHECK(t, bowner != aowner);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "", preedit);
CT_EQ_PTR(t, bowner, testengineowner());
@@ -305,14 +304,14 @@ server_connection_ownership(struct ct *t)
req = nextrequest(t, &gate, Keyreset);
CT_EQ_PTR(t, aowner, req.owner);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &a, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "", preedit);
CT_EQ_PTR(t, bowner, testengineowner());
if(!sendkey(t, &b, 1, 0, Kmodfirst))
goto cleanup;
req = nextrequest(t, &gate, Keypress);
allowrequest(&gate);
CT_CHECK(t, !readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, !readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "", preedit);
disconnectclient(t, &gate, &a, aowner);
@@ -321,12 +320,12 @@ server_connection_ownership(struct ct *t)
goto cleanup;
req = nextrequest(t, &gate, Keypress);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &b, 1, preedit));
if(!sendkey(t, &b, 1, 0, 'a'))
goto cleanup;
req = nextrequest(t, &gate, Keypress);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "にゃ", preedit);
if(!sendreset(t, &b, 1))
@@ -334,7 +333,7 @@ server_connection_ownership(struct ct *t)
req = nextrequest(t, &gate, Keyreset);
CT_EQ_PTR(t, bowner, req.owner);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "", preedit);
CT_EQ_PTR(t, bowner, testengineowner());
@@ -343,7 +342,7 @@ server_connection_ownership(struct ct *t)
req = nextrequestcap(t, &gate, Keypress, 0);
CT_EQ_PTR(t, bowner, req.owner);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 0, nil, 0));
CT_CHECK(t, readreply(t, &b, 0, preedit));
errno = 0;
n = recv(b.peer, &byte, 1, MSG_PEEK|MSG_DONTWAIT);
CT_EQ_INT(t, -1, n);
@@ -353,7 +352,7 @@ server_connection_ownership(struct ct *t)
goto cleanup;
req = nextrequest(t, &gate, Keypress);
allowrequest(&gate);
CT_CHECK(t, readreply(t, &b, 1, preedit, sizeof preedit));
CT_CHECK(t, readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "", preedit);
disconnectclient(t, &gate, &b, bowner);
@@ -410,7 +409,7 @@ server_extension_stream(struct ct *t)
Keyreq req;
Drawcmd dc;
uchar frame[Ipccaretsz], token;
char preedit[Maxutf];
char preedit[Ipcfieldmax+1];
void *aowner, *bowner;
int gateactive;
@@ -442,10 +441,10 @@ server_extension_stream(struct ct *t)
aowner = req.owner;
CT_EQ_PTR(t, nil, testengineowner());
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "", preedit);
CT_EQ_INT(t, 0, ipcpackcaret(frame, 1, -101, -7, 23));
ipcpackcaret(frame, 1, -101, -7, 23);
if(!sendframe(t, &a, frame, Ipccaretsz, 1))
goto cleanup;
req = nextrequest(t, &gate, Keycaret);
@@ -468,7 +467,7 @@ server_extension_stream(struct ct *t)
CT_EQ_INT(t, -7, req.caret.y);
CT_EQ_INT(t, 23, req.caret.h);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "k", preedit);
CT_EQ_PTR(t, aowner, testengineowner());
@@ -479,7 +478,7 @@ server_extension_stream(struct ct *t)
CT_EQ_PTR(t, aowner, req.owner);
CT_EQ_INT(t, 1, req.caret.valid);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 0, nil, 0));
CT_EQ_INT(t, 1, readreply(t, &a, 0, preedit));
/* Reset is still the old six-byte frame and does not discard caret. */
ipcpackreset(frame, 0);
@@ -492,14 +491,14 @@ server_extension_stream(struct ct *t)
CT_EQ_INT(t, -7, req.caret.y);
CT_EQ_INT(t, 23, req.caret.h);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 0, nil, 0));
CT_EQ_INT(t, 1, readreply(t, &a, 0, preedit));
ipcpackcap(frame, Cclientpreedit);
if(!sendframe(t, &a, frame, Ipcreqsz, 0))
goto cleanup;
req = nextrequest(t, &gate, Keycap);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "", preedit);
ipcpackreq(frame, 1, 0, 'n');
if(!sendframe(t, &a, frame, Ipcreqsz, 0))
@@ -508,7 +507,7 @@ server_extension_stream(struct ct *t)
CT_EQ_INT(t, 1, req.caret.valid);
CT_EQ_INT(t, -101, req.caret.x);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
CT_EQ_STR(t, "", preedit);
disconnectclient(t, &gate, &a, aowner);
@@ -520,7 +519,7 @@ server_extension_stream(struct ct *t)
bowner = req.owner;
CT_EQ_INT(t, 0, req.caret.valid);
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &b, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &b, 1, preedit));
CT_EQ_STR(t, "k", preedit);
disconnectclient(t, &gate, &b, bowner);
@@ -554,7 +553,7 @@ server_rejects_unknown_extension(struct ct *t)
Keyreq req;
Drawcmd dc;
uchar frame[Ipccaretsz], token;
char preedit[Maxutf];
char preedit[Ipcfieldmax+1];
void *owner;
int gateactive;
@@ -580,7 +579,7 @@ server_rejects_unknown_extension(struct ct *t)
if(!startclient(t, &badver))
goto cleanup;
CT_EQ_INT(t, 0, ipcpackcaret(frame, 1, 3, 4, 5));
ipcpackcaret(frame, 1, 3, 4, 5);
frame[1]++;
if(!sendframe(t, &badver, frame, sizeof frame, 0))
goto cleanup;
@@ -592,7 +591,7 @@ server_rejects_unknown_extension(struct ct *t)
if(!startclient(t, &badop))
goto cleanup;
CT_EQ_INT(t, 0, ipcpackcaret(frame, 1, 3, 4, 5));
ipcpackcaret(frame, 1, 3, 4, 5);
frame[2]++;
if(!sendframe(t, &badop, frame, sizeof frame, 1))
goto cleanup;
@@ -608,7 +607,7 @@ server_rejects_unknown_extension(struct ct *t)
req = nextrequest(t, &gate, Keypress);
owner = req.owner;
allowrequest(&gate);
CT_EQ_INT(t, 1, readreply(t, &good, 1, preedit, sizeof preedit));
CT_EQ_INT(t, 1, readreply(t, &good, 1, preedit));
CT_EQ_STR(t, "k", preedit);
disconnectclient(t, &gate, &good, owner);