ibus: complete setup before publication
This commit is contained in:
49
ibus.c
49
ibus.c
@@ -182,14 +182,15 @@ writeaddr(char *path, char *addr)
|
|||||||
fd = -1;
|
fd = -1;
|
||||||
if(fprintf(fp, "IBUS_ADDRESS=%s\n", addr) < 0 ||
|
if(fprintf(fp, "IBUS_ADDRESS=%s\n", addr) < 0 ||
|
||||||
fprintf(fp, "IBUS_DAEMON_PID=%d\n", (int)getpid()) < 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;
|
goto out;
|
||||||
if(fclose(fp) < 0){
|
if(fclose(fp) < 0){
|
||||||
fp = nil;
|
fp = nil;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
fp = nil;
|
fp = nil;
|
||||||
if(rename(tmp, path) < 0 || lstat(path, &st) < 0)
|
if(rename(tmp, path) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
addrdev = st.st_dev;
|
addrdev = st.st_dev;
|
||||||
addrino = st.st_ino;
|
addrino = st.st_ino;
|
||||||
@@ -695,11 +696,19 @@ newconn(DBusServer *s, DBusConnection *c, void *_)
|
|||||||
USED(_);
|
USED(_);
|
||||||
if(nconns >= Maxconns)
|
if(nconns >= Maxconns)
|
||||||
return;
|
return;
|
||||||
dbus_connection_ref(c);
|
if(!dbus_connection_set_watch_functions(c, addwatch, removewatch,
|
||||||
dbus_connection_set_watch_functions(c, addwatch, removewatch, togglewatch, nil, nil);
|
togglewatch, nil, nil)){
|
||||||
|
fprintf(stderr, "strans: ibus: cannot watch client connection\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
memset(&vt, 0, sizeof(vt));
|
memset(&vt, 0, sizeof(vt));
|
||||||
vt.message_function = onmsg;
|
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;
|
conns[nconns++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +735,10 @@ ibusinit(void)
|
|||||||
DBusError err;
|
DBusError err;
|
||||||
char addr[128];
|
char addr[128];
|
||||||
char *full;
|
char *full;
|
||||||
|
int cleanupregistered;
|
||||||
|
|
||||||
|
full = nil;
|
||||||
|
cleanupregistered = 0;
|
||||||
if(buildaddrpath(addrfile, sizeof(addrfile)) < 0){
|
if(buildaddrpath(addrfile, sizeof(addrfile)) < 0){
|
||||||
fprintf(stderr, "strans: ibus: cannot build address path\n");
|
fprintf(stderr, "strans: ibus: cannot build address path\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -745,10 +757,31 @@ ibusinit(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dbus_server_set_new_connection_function(srv, newconn, nil, nil);
|
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);
|
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){
|
if(writeaddr(addrfile, full) < 0){
|
||||||
fprintf(stderr, "strans: ibus: cannot write %s\n", addrfile);
|
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_free(full);
|
||||||
dbus_server_disconnect(srv);
|
dbus_server_disconnect(srv);
|
||||||
dbus_server_unref(srv);
|
dbus_server_unref(srv);
|
||||||
@@ -756,10 +789,6 @@ ibusinit(void)
|
|||||||
addrfile[0] = '\0';
|
addrfile[0] = '\0';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dbus_free(full);
|
|
||||||
atexit(unlinkaddr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ibusthread(void *_)
|
ibusthread(void *_)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "../ibus.c"
|
#include "../ibus.c"
|
||||||
#include "../cutest/cutest.h"
|
#include "../cutest/cutest.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
void testengineinit(int);
|
void testengineinit(int);
|
||||||
void testenginehandle(Keyreq*);
|
void testenginehandle(Keyreq*);
|
||||||
void* testengineowner(void);
|
void* testengineowner(void);
|
||||||
@@ -67,6 +69,83 @@ cleanup:
|
|||||||
CT_CHECK(t, rmdir(root) == 0);
|
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
|
static void
|
||||||
enginepump(void *arg)
|
enginepump(void *arg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,5 +72,6 @@ void ipc_response_fragmented_and_truncated(struct ct*);
|
|||||||
void ipc_broken_peer_send(struct ct*);
|
void ipc_broken_peer_send(struct ct*);
|
||||||
void server_connection_ownership(struct ct*);
|
void server_connection_ownership(struct ct*);
|
||||||
void ibus_machine_id_fallback(struct ct*);
|
void ibus_machine_id_fallback(struct ct*);
|
||||||
|
void ibus_startup_requires_ownership(struct ct*);
|
||||||
void ibus_context_lifecycle(struct ct*);
|
void ibus_context_lifecycle(struct ct*);
|
||||||
void ibus_active_release_lifecycle(struct ct*);
|
void ibus_active_release_lifecycle(struct ct*);
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ static const struct ct_test tests[] = {
|
|||||||
{ "ipc/broken-peer-send", ipc_broken_peer_send },
|
{ "ipc/broken-peer-send", ipc_broken_peer_send },
|
||||||
{ "server/connection-ownership", server_connection_ownership },
|
{ "server/connection-ownership", server_connection_ownership },
|
||||||
{ "ibus/machine-id-fallback", ibus_machine_id_fallback },
|
{ "ibus/machine-id-fallback", ibus_machine_id_fallback },
|
||||||
|
{ "ibus/startup-requires-ownership", ibus_startup_requires_ownership },
|
||||||
{ "ibus/context-lifecycle", ibus_context_lifecycle },
|
{ "ibus/context-lifecycle", ibus_context_lifecycle },
|
||||||
{ "ibus/active-release-lifecycle", ibus_active_release_lifecycle },
|
{ "ibus/active-release-lifecycle", ibus_active_release_lifecycle },
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user