ibus: complete setup before publication

This commit is contained in:
2026-08-14 02:48:49 +09:00
parent 6a2b2bccc4
commit f395f29918
4 changed files with 123 additions and 13 deletions

49
ibus.c
View File

@@ -182,14 +182,15 @@ writeaddr(char *path, char *addr)
fd = -1;
if(fprintf(fp, "IBUS_ADDRESS=%s\n", addr) < 0 ||
fprintf(fp, "IBUS_DAEMON_PID=%d\n", (int)getpid()) < 0 ||
fflush(fp) < 0 || fsync(fileno(fp)) < 0)
fflush(fp) < 0 || fsync(fileno(fp)) < 0 ||
fstat(fileno(fp), &st) < 0)
goto out;
if(fclose(fp) < 0){
fp = nil;
goto out;
}
fp = nil;
if(rename(tmp, path) < 0 || lstat(path, &st) < 0)
if(rename(tmp, path) < 0)
goto out;
addrdev = st.st_dev;
addrino = st.st_ino;
@@ -695,11 +696,19 @@ newconn(DBusServer *s, DBusConnection *c, void *_)
USED(_);
if(nconns >= Maxconns)
return;
dbus_connection_ref(c);
dbus_connection_set_watch_functions(c, addwatch, removewatch, togglewatch, nil, nil);
if(!dbus_connection_set_watch_functions(c, addwatch, removewatch,
togglewatch, nil, nil)){
fprintf(stderr, "strans: ibus: cannot watch client connection\n");
return;
}
memset(&vt, 0, sizeof(vt));
vt.message_function = onmsg;
dbus_connection_register_fallback(c, "/", &vt, nil);
if(!dbus_connection_register_fallback(c, "/", &vt, nil)){
fprintf(stderr, "strans: ibus: cannot register client handler\n");
dbus_connection_set_watch_functions(c, nil, nil, nil, nil, nil);
return;
}
dbus_connection_ref(c);
conns[nconns++] = c;
}
@@ -726,7 +735,10 @@ ibusinit(void)
DBusError err;
char addr[128];
char *full;
int cleanupregistered;
full = nil;
cleanupregistered = 0;
if(buildaddrpath(addrfile, sizeof(addrfile)) < 0){
fprintf(stderr, "strans: ibus: cannot build address path\n");
return -1;
@@ -745,20 +757,37 @@ ibusinit(void)
return -1;
}
dbus_server_set_new_connection_function(srv, newconn, nil, nil);
dbus_server_set_watch_functions(srv, addwatch, removewatch, togglewatch, nil, nil);
if(!dbus_server_set_watch_functions(srv, addwatch, removewatch,
togglewatch, nil, nil)){
fprintf(stderr, "strans: ibus: cannot watch server\n");
goto fail;
}
full = dbus_server_get_address(srv);
if(full == nil){
fprintf(stderr, "strans: ibus: cannot get server address\n");
goto fail;
}
if(!atexit(unlinkaddr)){
fprintf(stderr, "strans: ibus: cannot register address cleanup\n");
goto fail;
}
cleanupregistered = 1;
if(writeaddr(addrfile, full) < 0){
fprintf(stderr, "strans: ibus: cannot write %s\n", addrfile);
goto fail;
}
dbus_free(full);
return 0;
fail:
if(cleanupregistered)
atexitdont(unlinkaddr);
if(full != nil)
dbus_free(full);
dbus_server_disconnect(srv);
dbus_server_unref(srv);
srv = nil;
addrfile[0] = '\0';
return -1;
}
dbus_free(full);
atexit(unlinkaddr);
return 0;
}
void

View File

@@ -1,6 +1,8 @@
#include "../ibus.c"
#include "../cutest/cutest.h"
#include <errno.h>
void testengineinit(int);
void testenginehandle(Keyreq*);
void* testengineowner(void);
@@ -67,6 +69,83 @@ cleanup:
CT_CHECK(t, rmdir(root) == 0);
}
void
ibus_startup_requires_ownership(struct ct *t)
{
char root[] = "/tmp/strans-ibus-startup.XXXXXX";
char busdir[128], ibusdir[128], path[512], *old, *saved;
struct stat st;
int i, made, rv;
made = 0;
busdir[0] = '\0';
ibusdir[0] = '\0';
path[0] = '\0';
old = getenv("XDG_CONFIG_HOME");
saved = old == nil ? nil : strdup(old);
if(old != nil && !CT_CHECK(t, saved != nil))
return;
if(!CT_CHECK(t, mkdtemp(root) != nil))
goto cleanup;
made = 1;
if(!CT_CHECK(t, snprintf(busdir, sizeof busdir, "%s/ibus/bus", root)
< (int)sizeof busdir) ||
!CT_CHECK(t, snprintf(ibusdir, sizeof ibusdir, "%s/ibus", root)
< (int)sizeof ibusdir) ||
!CT_CHECK(t, setenv("XDG_CONFIG_HOME", root, 1) == 0) ||
!CT_CHECK(t, buildaddrpath(path, sizeof path) == 0))
goto cleanup;
memset(watches, 0, sizeof watches);
for(i = 0; i < nelem(watches); i++)
watches[i] = (DBusWatch*)1;
nwatches = nelem(watches);
rv = ibusinit();
CT_EQ_INT(t, -1, rv);
CT_EQ_PTR(t, nil, srv);
CT_CHECK(t, lstat(path, &st) < 0 && errno == ENOENT);
if(rv == 0){
dbus_server_disconnect(srv);
dbus_server_unref(srv);
srv = nil;
unlinkaddr();
atexitdont(unlinkaddr);
}
memset(watches, 0, sizeof watches);
nwatches = 0;
while(atexit(unlinkaddr))
continue;
CT_EQ_INT(t, -1, ibusinit());
CT_EQ_PTR(t, nil, srv);
CT_CHECK(t, lstat(path, &st) < 0 && errno == ENOENT);
cleanup:
if(srv != nil){
dbus_server_disconnect(srv);
dbus_server_unref(srv);
srv = nil;
}
unlinkaddr();
atexitdont(unlinkaddr);
memset(watches, 0, sizeof watches);
nwatches = 0;
addrfile[0] = '\0';
if(saved != nil){
setenv("XDG_CONFIG_HOME", saved, 1);
free(saved);
}else
unsetenv("XDG_CONFIG_HOME");
if(made){
if(path[0] != '\0')
unlink(path);
if(busdir[0] != '\0')
CT_CHECK(t, rmdir(busdir) == 0 || errno == ENOENT);
if(ibusdir[0] != '\0')
CT_CHECK(t, rmdir(ibusdir) == 0 || errno == ENOENT);
CT_CHECK(t, rmdir(root) == 0);
}
}
static void
enginepump(void *arg)
{

View File

@@ -72,5 +72,6 @@ void ipc_response_fragmented_and_truncated(struct ct*);
void ipc_broken_peer_send(struct ct*);
void server_connection_ownership(struct ct*);
void ibus_machine_id_fallback(struct ct*);
void ibus_startup_requires_ownership(struct ct*);
void ibus_context_lifecycle(struct ct*);
void ibus_active_release_lifecycle(struct ct*);

View File

@@ -126,6 +126,7 @@ static const struct ct_test tests[] = {
{ "ipc/broken-peer-send", ipc_broken_peer_send },
{ "server/connection-ownership", server_connection_ownership },
{ "ibus/machine-id-fallback", ibus_machine_id_fallback },
{ "ibus/startup-requires-ownership", ibus_startup_requires_ownership },
{ "ibus/context-lifecycle", ibus_context_lifecycle },
{ "ibus/active-release-lifecycle", ibus_active_release_lifecycle },
};