fix(ibus): make the X11 frontend fail truthfully
This commit is contained in:
91
ibus.c
91
ibus.c
@@ -4,6 +4,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@@ -12,9 +13,9 @@
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Maxconns = 16,
|
Maxconns = Maxclients,
|
||||||
Maxwatches = 2*Maxconns + 1,
|
Maxwatches = 2*Maxconns + 1,
|
||||||
Maxcontexts = 64,
|
Maxcontexts = Maxclients,
|
||||||
Relmask = 1<<30,
|
Relmask = 1<<30,
|
||||||
Ibussupermask = 1<<26,
|
Ibussupermask = 1<<26,
|
||||||
/* IBus wire constants; the daemon does not link libibus. */
|
/* IBus wire constants; the daemon does not link libibus. */
|
||||||
@@ -136,11 +137,16 @@ xdisplay(char *host, int hsz, char *num, int nsz)
|
|||||||
static int
|
static int
|
||||||
buildaddrpath(char *buf, int sz)
|
buildaddrpath(char *buf, int sz)
|
||||||
{
|
{
|
||||||
char mid[64], host[64], num[8], *cfg, *home;
|
char mid[64], host[64], num[8], *cfg, *home, *explicit;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char dir[512];
|
char dir[512];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
explicit = getenv("IBUS_ADDRESS_FILE");
|
||||||
|
if(explicit != nil){
|
||||||
|
n = snprintf(buf, sz, "%s", explicit);
|
||||||
|
return explicit[0] == '\0' || n < 0 || n >= sz ? -1 : 0;
|
||||||
|
}
|
||||||
machineid(mid, sizeof(mid));
|
machineid(mid, sizeof(mid));
|
||||||
if(mid[0] == '\0')
|
if(mid[0] == '\0')
|
||||||
return -1;
|
return -1;
|
||||||
@@ -311,6 +317,12 @@ newcontext(DBusConnection *conn, const char *path)
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
clientpreedit(Ictx *ctx)
|
||||||
|
{
|
||||||
|
return (ctx->cap & Ibuscappreedit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendrequest(Ictx *ctx, int op, u32int ks, u32int mod, Keyres *res)
|
sendrequest(Ictx *ctx, int op, u32int ks, u32int mod, Keyres *res)
|
||||||
{
|
{
|
||||||
@@ -318,7 +330,7 @@ sendrequest(Ictx *ctx, int op, u32int ks, u32int mod, Keyres *res)
|
|||||||
|
|
||||||
memset(&kr, 0, sizeof kr);
|
memset(&kr, 0, sizeof kr);
|
||||||
kr.owner = ctx;
|
kr.owner = ctx;
|
||||||
kr.cap = ctx->cap & Ibuscappreedit ? Cclientpreedit : 0;
|
kr.cap = clientpreedit(ctx) ? Cclientpreedit : 0;
|
||||||
kr.op = op;
|
kr.op = op;
|
||||||
kr.ks = ks;
|
kr.ks = ks;
|
||||||
kr.mod = mod;
|
kr.mod = mod;
|
||||||
@@ -487,6 +499,9 @@ handlehello(DBusConnection *c, DBusMessage *m)
|
|||||||
char name[32];
|
char name[32];
|
||||||
const char *np;
|
const char *np;
|
||||||
|
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Hello expects no arguments");
|
||||||
busctr++;
|
busctr++;
|
||||||
snprintf(name, sizeof(name), ":1.%d", busctr);
|
snprintf(name, sizeof(name), ":1.%d", busctr);
|
||||||
np = name;
|
np = name;
|
||||||
@@ -561,6 +576,9 @@ handlecreate(DBusConnection *c, DBusMessage *m)
|
|||||||
Ictx *ctx;
|
Ictx *ctx;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
if(!dbus_message_has_signature(m, "s"))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"CreateInputContext expects one client name");
|
||||||
icctr++;
|
icctr++;
|
||||||
n = snprintf(path, sizeof(path),
|
n = snprintf(path, sizeof(path),
|
||||||
"/org/freedesktop/IBus/InputContext_%d", icctr);
|
"/org/freedesktop/IBus/InputContext_%d", icctr);
|
||||||
@@ -594,7 +612,8 @@ handlekey(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
|||||||
DBUS_TYPE_UINT32, &state,
|
DBUS_TYPE_UINT32, &state,
|
||||||
DBUS_TYPE_INVALID)){
|
DBUS_TYPE_INVALID)){
|
||||||
dbus_error_free(&err);
|
dbus_error_free(&err);
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"ProcessKeyEvent expects three unsigned integers");
|
||||||
}
|
}
|
||||||
USED(code);
|
USED(code);
|
||||||
if(!processkey(ctx, sym, state, &res))
|
if(!processkey(ctx, sym, state, &res))
|
||||||
@@ -603,7 +622,7 @@ handlekey(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
|||||||
stoutf(&res.preedit, preedit, sizeof preedit);
|
stoutf(&res.preedit, preedit, sizeof preedit);
|
||||||
if(commit[0] != '\0')
|
if(commit[0] != '\0')
|
||||||
emitcommit(c, dbus_message_get_path(m), commit);
|
emitcommit(c, dbus_message_get_path(m), commit);
|
||||||
if(ctx->cap & Ibuscappreedit)
|
if(clientpreedit(ctx))
|
||||||
emitpreedit(ctx, preedit);
|
emitpreedit(ctx, preedit);
|
||||||
return handlebool(c, m, res.eaten);
|
return handlebool(c, m, res.eaten);
|
||||||
}
|
}
|
||||||
@@ -625,6 +644,7 @@ handlereset(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
|||||||
Keyres res;
|
Keyres res;
|
||||||
|
|
||||||
sendrequest(ctx, Keyreset, 0, 0, &res);
|
sendrequest(ctx, Keyreset, 0, 0, &res);
|
||||||
|
if(clientpreedit(ctx))
|
||||||
emitpreedit(ctx, "");
|
emitpreedit(ctx, "");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
@@ -640,6 +660,7 @@ static DBusHandlerResult
|
|||||||
handlefocusout(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
handlefocusout(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
{
|
{
|
||||||
releasecontext(ctx);
|
releasecontext(ctx);
|
||||||
|
if(clientpreedit(ctx))
|
||||||
emitpreedit(ctx, "");
|
emitpreedit(ctx, "");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
@@ -740,6 +761,7 @@ handlepropertyset(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
|||||||
ctx->hints = hints;
|
ctx->hints = hints;
|
||||||
if(ctx->focused && !washidden && hidden(ctx)){
|
if(ctx->focused && !washidden && hidden(ctx)){
|
||||||
sendrequest(ctx, Keyreset, 0, 0, &res);
|
sendrequest(ctx, Keyreset, 0, 0, &res);
|
||||||
|
if(clientpreedit(ctx))
|
||||||
emitpreedit(ctx, "");
|
emitpreedit(ctx, "");
|
||||||
}
|
}
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
@@ -896,6 +918,9 @@ handleintrospect(DBusConnection *c, DBusMessage *m)
|
|||||||
DBusMessage *r;
|
DBusMessage *r;
|
||||||
const char *xml = introspectxml;
|
const char *xml = introspectxml;
|
||||||
|
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Introspect expects no arguments");
|
||||||
r = dbus_message_new_method_return(m);
|
r = dbus_message_new_method_return(m);
|
||||||
dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID);
|
dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID);
|
||||||
dbus_connection_send(c, r, nil);
|
dbus_connection_send(c, r, nil);
|
||||||
@@ -926,9 +951,13 @@ onmsg(DBusConnection *c, DBusMessage *m, void *_)
|
|||||||
if(strcmp(member, "GetNameOwner") == 0)
|
if(strcmp(member, "GetNameOwner") == 0)
|
||||||
return handlenameowner(c, m);
|
return handlenameowner(c, m);
|
||||||
if(strcmp(member, "AddMatch") == 0
|
if(strcmp(member, "AddMatch") == 0
|
||||||
|| strcmp(member, "RemoveMatch") == 0)
|
|| strcmp(member, "RemoveMatch") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, "s"))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"match rule must be one string");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(strcmp(iface, "org.freedesktop.IBus") == 0){
|
if(strcmp(iface, "org.freedesktop.IBus") == 0){
|
||||||
if(strcmp(member, "CreateInputContext") == 0)
|
if(strcmp(member, "CreateInputContext") == 0)
|
||||||
return handlecreate(c, m);
|
return handlecreate(c, m);
|
||||||
@@ -952,21 +981,41 @@ onmsg(DBusConnection *c, DBusMessage *m, void *_)
|
|||||||
"unknown input context");
|
"unknown input context");
|
||||||
if(strcmp(member, "ProcessKeyEvent") == 0)
|
if(strcmp(member, "ProcessKeyEvent") == 0)
|
||||||
return handlekey(c, m, ctx);
|
return handlekey(c, m, ctx);
|
||||||
if(strcmp(member, "FocusIn") == 0)
|
if(strcmp(member, "FocusIn") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"FocusIn expects no arguments");
|
||||||
return handlefocusin(c, m, ctx);
|
return handlefocusin(c, m, ctx);
|
||||||
if(strcmp(member, "FocusOut") == 0)
|
}
|
||||||
|
if(strcmp(member, "FocusOut") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"FocusOut expects no arguments");
|
||||||
return handlefocusout(c, m, ctx);
|
return handlefocusout(c, m, ctx);
|
||||||
if(strcmp(member, "Reset") == 0)
|
}
|
||||||
|
if(strcmp(member, "Reset") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Reset expects no arguments");
|
||||||
return handlereset(c, m, ctx);
|
return handlereset(c, m, ctx);
|
||||||
if(strcmp(member, "Destroy") == 0)
|
}
|
||||||
|
if(strcmp(member, "Destroy") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, ""))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"Destroy expects no arguments");
|
||||||
return handledestroy(c, m, ctx);
|
return handledestroy(c, m, ctx);
|
||||||
|
}
|
||||||
if(strcmp(member, "SetCursorLocation") == 0)
|
if(strcmp(member, "SetCursorLocation") == 0)
|
||||||
return handlecursor(c, m, ctx);
|
return handlecursor(c, m, ctx);
|
||||||
if(strcmp(member, "SetCapabilities") == 0)
|
if(strcmp(member, "SetCapabilities") == 0)
|
||||||
return handlecap(c, m, ctx);
|
return handlecap(c, m, ctx);
|
||||||
if(strcmp(member, "SetEngine") == 0)
|
if(strcmp(member, "SetEngine") == 0){
|
||||||
|
if(!dbus_message_has_signature(m, "s"))
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"SetEngine expects one engine name");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,11 +1026,16 @@ newconn(DBusServer *s, DBusConnection *c, void *_)
|
|||||||
|
|
||||||
USED(s);
|
USED(s);
|
||||||
USED(_);
|
USED(_);
|
||||||
if(nconns >= Maxconns)
|
if(nconns >= Maxconns){
|
||||||
|
fprintf(stderr, "strans: ibus: rejecting client: %d-connection limit reached\n",
|
||||||
|
Maxconns);
|
||||||
|
dbus_connection_close(c);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if(!dbus_connection_set_watch_functions(c, addwatch, removewatch,
|
if(!dbus_connection_set_watch_functions(c, addwatch, removewatch,
|
||||||
togglewatch, nil, nil)){
|
togglewatch, nil, nil)){
|
||||||
fprintf(stderr, "strans: ibus: cannot watch client connection\n");
|
fprintf(stderr, "strans: ibus: cannot watch client connection\n");
|
||||||
|
dbus_connection_close(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(&vt, 0, sizeof(vt));
|
memset(&vt, 0, sizeof(vt));
|
||||||
@@ -989,6 +1043,7 @@ newconn(DBusServer *s, DBusConnection *c, void *_)
|
|||||||
if(!dbus_connection_register_fallback(c, "/", &vt, nil)){
|
if(!dbus_connection_register_fallback(c, "/", &vt, nil)){
|
||||||
fprintf(stderr, "strans: ibus: cannot register client handler\n");
|
fprintf(stderr, "strans: ibus: cannot register client handler\n");
|
||||||
dbus_connection_set_watch_functions(c, nil, nil, nil, nil, nil);
|
dbus_connection_set_watch_functions(c, nil, nil, nil, nil, nil);
|
||||||
|
dbus_connection_close(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dbus_connection_ref(c);
|
dbus_connection_ref(c);
|
||||||
@@ -1085,9 +1140,13 @@ ibusthread(void *_)
|
|||||||
USED(_);
|
USED(_);
|
||||||
threadsetname("ibus");
|
threadsetname("ibus");
|
||||||
if(ibusinit() < 0)
|
if(ibusinit() < 0)
|
||||||
return;
|
die("ibus: initialization failed");
|
||||||
replyc = chancreate(sizeof(Keyres), 0);
|
replyc = chancreate(sizeof(Keyres), 0);
|
||||||
|
if(replyc == nil)
|
||||||
|
die("ibus: cannot create reply channel");
|
||||||
for(;;){
|
for(;;){
|
||||||
|
if(!dbus_server_get_is_connected(srv))
|
||||||
|
die("ibus: server disconnected");
|
||||||
n = 0;
|
n = 0;
|
||||||
for(i = 0; i < nwatches && n < Maxwatches; i++){
|
for(i = 0; i < nwatches && n < Maxwatches; i++){
|
||||||
if(watches[i] == nil)
|
if(watches[i] == nil)
|
||||||
@@ -1104,8 +1163,10 @@ ibusthread(void *_)
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
rv = poll(pfds, n, 200);
|
rv = poll(pfds, n, 200);
|
||||||
if(rv < 0)
|
if(rv < 0 && errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
if(rv < 0)
|
||||||
|
die("ibus: poll: %s", strerror(errno));
|
||||||
for(i = 0; i < n; i++){
|
for(i = 0; i < n; i++){
|
||||||
if(pfds[i].revents == 0)
|
if(pfds[i].revents == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Maxconnections = 16,
|
Maxconnections = 64,
|
||||||
Calltimeout = 4000,
|
Calltimeout = 4000,
|
||||||
Starttimeout = 8000,
|
Starttimeout = 8000,
|
||||||
Stoptimeout = 3000,
|
Stoptimeout = 3000,
|
||||||
@@ -312,7 +312,8 @@ startdaemon(Daemon *d, char *program, char *mapdir)
|
|||||||
setenv("XDG_CONFIG_HOME", d->config, 1) < 0 ||
|
setenv("XDG_CONFIG_HOME", d->config, 1) < 0 ||
|
||||||
setenv("HOME", d->home, 1) < 0 || unsetenv("DISPLAY") < 0 ||
|
setenv("HOME", d->home, 1) < 0 || unsetenv("DISPLAY") < 0 ||
|
||||||
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 ||
|
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 ||
|
||||||
unsetenv("IBUS_ADDRESS") < 0){
|
unsetenv("IBUS_ADDRESS") < 0 ||
|
||||||
|
unsetenv("IBUS_ADDRESS_FILE") < 0){
|
||||||
dprintf(STDERR_FILENO, "set daemon environment: %s\n",
|
dprintf(STDERR_FILENO, "set daemon environment: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
_exit(126);
|
_exit(126);
|
||||||
@@ -1346,6 +1347,9 @@ runlifecycle(Daemon *d)
|
|||||||
goto out;
|
goto out;
|
||||||
if(!createcontext(c1, a, sizeof a) || !createcontext(c2, b, sizeof b))
|
if(!createcontext(c1, a, sizeof a) || !createcontext(c2, b, sizeof b))
|
||||||
goto out;
|
goto out;
|
||||||
|
if(!unknowncall(c1, a, "ProcessKeyEvent", DBUS_ERROR_INVALID_ARGS) ||
|
||||||
|
!unknowncall(c1, a, "SetEngine", DBUS_ERROR_INVALID_ARGS))
|
||||||
|
goto out;
|
||||||
if(!unknowncall(c1, "/org/freedesktop/IBus/InputContext_missing",
|
if(!unknowncall(c1, "/org/freedesktop/IBus/InputContext_missing",
|
||||||
"FocusIn", DBUS_ERROR_UNKNOWN_OBJECT))
|
"FocusIn", DBUS_ERROR_UNKNOWN_OBJECT))
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1477,6 +1481,22 @@ runpolicy(Daemon *d)
|
|||||||
if(!expectkey(c1, &s1, a, 'n', Ctrlmask, 1, NULL,
|
if(!expectkey(c1, &s1, a, 'n', Ctrlmask, 1, NULL,
|
||||||
"zero-capability language") ||
|
"zero-capability language") ||
|
||||||
!expectkey(c1, &s1, a, 'k', 0, 1, NULL, "zero-capability key") ||
|
!expectkey(c1, &s1, a, 'k', 0, 1, NULL, "zero-capability key") ||
|
||||||
|
!emptycall(c1, &s1, a, "Reset") ||
|
||||||
|
!nosignal(&s1, "zero-capability Reset") ||
|
||||||
|
!expectkey(c1, &s1, a, 'k', 0, 1, NULL,
|
||||||
|
"zero-capability before PASSWORD") ||
|
||||||
|
!contentcall(c1, &s1, a, Purposepassword, 0) ||
|
||||||
|
!nosignal(&s1, "zero-capability PASSWORD") ||
|
||||||
|
!contentcall(c1, &s1, a, Purposefree, 0) ||
|
||||||
|
!nosignal(&s1, "zero-capability leave PASSWORD") ||
|
||||||
|
!expectkey(c1, &s1, a, 'k', 0, 1, NULL,
|
||||||
|
"zero-capability before FocusOut") ||
|
||||||
|
!emptycall(c1, &s1, a, "FocusOut") ||
|
||||||
|
!nosignal(&s1, "zero-capability FocusOut") ||
|
||||||
|
!emptycall(c1, &s1, a, "FocusIn") ||
|
||||||
|
!nosignal(&s1, "zero-capability refocus") ||
|
||||||
|
!expectkey(c1, &s1, a, 'k', 0, 1, NULL,
|
||||||
|
"zero-capability after refocus") ||
|
||||||
!capcall(c1, &s1, a, 1<<1) || !nosignal(&s1, "non-preedit cap") ||
|
!capcall(c1, &s1, a, 1<<1) || !nosignal(&s1, "non-preedit cap") ||
|
||||||
!capcall(c1, &s1, a, Cappreedit|(1<<1)) ||
|
!capcall(c1, &s1, a, Cappreedit|(1<<1)) ||
|
||||||
!preedit(&s1, a, "k", 1, 1, "enable inline") ||
|
!preedit(&s1, a, "k", 1, 1, "enable inline") ||
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ void
|
|||||||
ibus_machine_id_fallback(struct ct *t)
|
ibus_machine_id_fallback(struct ct *t)
|
||||||
{
|
{
|
||||||
char root[] = "/tmp/strans-machine-id.XXXXXX";
|
char root[] = "/tmp/strans-machine-id.XXXXXX";
|
||||||
char primary[128], fallback[128], got[64];
|
char primary[128], fallback[128], override[128], got[512];
|
||||||
char *path[2];
|
char *path[2], *old, *saved;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int madeprimary, madefallback;
|
int madeprimary, madefallback;
|
||||||
|
|
||||||
@@ -61,6 +61,24 @@ ibus_machine_id_fallback(struct ct *t)
|
|||||||
path[1] = fallback;
|
path[1] = fallback;
|
||||||
machineidfiles(got, sizeof got, path, nelem(path));
|
machineidfiles(got, sizeof got, path, nelem(path));
|
||||||
CT_EQ_STR(t, "fallback-machine-id", got);
|
CT_EQ_STR(t, "fallback-machine-id", got);
|
||||||
|
|
||||||
|
old = getenv("IBUS_ADDRESS_FILE");
|
||||||
|
saved = old == nil ? nil : strdup(old);
|
||||||
|
if(old == nil || CT_CHECK(t, saved != nil)){
|
||||||
|
if(CT_CHECK(t, snprintf(override, sizeof override, "%s/address", root)
|
||||||
|
< (int)sizeof override) &&
|
||||||
|
CT_CHECK(t, setenv("IBUS_ADDRESS_FILE", override, 1) == 0)){
|
||||||
|
CT_EQ_INT(t, 0, buildaddrpath(got, sizeof got));
|
||||||
|
CT_EQ_STR(t, override, got);
|
||||||
|
CT_CHECK(t, setenv("IBUS_ADDRESS_FILE", "", 1) == 0);
|
||||||
|
CT_EQ_INT(t, -1, buildaddrpath(got, sizeof got));
|
||||||
|
}
|
||||||
|
if(saved != nil){
|
||||||
|
setenv("IBUS_ADDRESS_FILE", saved, 1);
|
||||||
|
free(saved);
|
||||||
|
}else
|
||||||
|
unsetenv("IBUS_ADDRESS_FILE");
|
||||||
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
if(madefallback)
|
if(madefallback)
|
||||||
CT_CHECK(t, unlink(fallback) == 0);
|
CT_CHECK(t, unlink(fallback) == 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user