3
* Copyright (C) 1999, 2000 Red Hat Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
22
#include "gconf-internals.h"
23
#include "gconf-backend.h"
24
#include "gconf-schema.h"
26
#include <orb/orbit.h>
27
#include <liboaf/liboaf.h>
30
#include <sys/types.h>
41
#define g_utf8_skip gconf_g_utf8_skip
43
typedef void (* GSpawnChildSetupFunc) (gpointer user_data);
47
G_SPAWN_LEAVE_DESCRIPTORS_OPEN = 1 << 0,
48
G_SPAWN_DO_NOT_REAP_CHILD = 1 << 1,
49
/* look for argv[0] in the path i.e. use execvp() */
50
G_SPAWN_SEARCH_PATH = 1 << 2,
51
/* Dump output to /dev/null */
52
G_SPAWN_STDOUT_TO_DEV_NULL = 1 << 3,
53
G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4,
54
G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5,
55
G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6
58
static gboolean g_spawn_async (const gchar *working_directory,
62
GSpawnChildSetupFunc child_setup,
67
gboolean gconf_log_debug_messages = FALSE;
69
static gboolean gconf_daemon_mode = FALSE;
70
static gchar* daemon_ior = NULL;
73
gconf_set_daemon_mode(gboolean setting)
75
gconf_daemon_mode = setting;
79
gconf_in_daemon_mode(void)
81
return gconf_daemon_mode;
85
gconf_set_daemon_ior(const gchar* ior)
87
if (daemon_ior != NULL)
94
daemon_ior = g_strdup(ior);
98
gconf_get_daemon_ior(void)
104
gconf_key_directory (const gchar* key)
110
end = strrchr(key, '/');
114
gconf_log(GCL_ERR, _("No '/' in key `%s'"), key);
123
retval = g_strdup("/");
127
retval = g_malloc(len);
129
strncpy(retval, key, len);
131
retval[len-1] = '\0';
138
gconf_key_key (const gchar* key)
142
end = strrchr(key, '/');
154
gconf_file_exists (const gchar* filename)
158
g_return_val_if_fail (filename != NULL,FALSE);
160
return stat (filename, &s) == 0;
164
gconf_file_test(const gchar* filename, int test)
167
if(stat (filename, &s) != 0)
169
if(!(test & GCONF_FILE_ISFILE) && S_ISREG(s.st_mode))
171
if(!(test & GCONF_FILE_ISLINK) && S_ISLNK(s.st_mode))
173
if(!(test & GCONF_FILE_ISDIR) && S_ISDIR(s.st_mode))
179
gconf_value_from_corba_value(const ConfigValue* value)
182
GConfValueType type = GCONF_VALUE_INVALID;
190
type = GCONF_VALUE_INT;
193
type = GCONF_VALUE_STRING;
196
type = GCONF_VALUE_FLOAT;
199
type = GCONF_VALUE_BOOL;
202
type = GCONF_VALUE_SCHEMA;
205
type = GCONF_VALUE_LIST;
208
type = GCONF_VALUE_PAIR;
211
gconf_log(GCL_DEBUG, "Invalid type in %s", G_GNUC_FUNCTION);
215
g_assert(GCONF_VALUE_TYPE_VALID(type));
217
gval = gconf_value_new(type);
221
case GCONF_VALUE_INT:
222
gconf_value_set_int(gval, value->_u.int_value);
224
case GCONF_VALUE_STRING:
225
if (!g_utf8_validate (value->_u.string_value, -1, NULL))
227
gconf_log (GCL_ERR, _("Invalid UTF-8 in string value in '%s'"),
228
value->_u.string_value);
232
gconf_value_set_string(gval, value->_u.string_value);
235
case GCONF_VALUE_FLOAT:
236
gconf_value_set_float(gval, value->_u.float_value);
238
case GCONF_VALUE_BOOL:
239
gconf_value_set_bool(gval, value->_u.bool_value);
241
case GCONF_VALUE_SCHEMA:
242
gconf_value_set_schema_nocopy(gval,
243
gconf_schema_from_corba_schema(&(value->_u.schema_value)));
245
case GCONF_VALUE_LIST:
250
switch (value->_u.list_value.list_type)
253
gconf_value_set_list_type(gval, GCONF_VALUE_INT);
256
gconf_value_set_list_type(gval, GCONF_VALUE_BOOL);
259
gconf_value_set_list_type(gval, GCONF_VALUE_FLOAT);
262
gconf_value_set_list_type(gval, GCONF_VALUE_STRING);
267
g_warning("Bizarre list type in %s", G_GNUC_FUNCTION);
271
if (gconf_value_get_list_type(gval) != GCONF_VALUE_INVALID)
274
while (i < value->_u.list_value.seq._length)
278
/* This is a bit dubious; we cast a ConfigBasicValue to ConfigValue
279
because they have the same initial members, but by the time
280
the CORBA and C specs kick in, not sure we are guaranteed
281
to be able to do this.
283
val = gconf_value_from_corba_value((ConfigValue*)&value->_u.list_value.seq._buffer[i]);
286
gconf_log(GCL_ERR, _("Couldn't interpret CORBA value for list element"));
287
else if (val->type != gconf_value_get_list_type(gval))
288
gconf_log(GCL_ERR, _("Incorrect type for list element in %s"), G_GNUC_FUNCTION);
290
list = g_slist_prepend(list, val);
295
list = g_slist_reverse(list);
297
gconf_value_set_list_nocopy(gval, list);
301
gconf_log(GCL_ERR, _("Received list from gconfd with a bad list type"));
305
case GCONF_VALUE_PAIR:
307
g_return_val_if_fail(value->_u.pair_value._length == 2, gval);
309
gconf_value_set_car_nocopy(gval,
310
gconf_value_from_corba_value((ConfigValue*)&value->_u.list_value.seq._buffer[0]));
312
gconf_value_set_cdr_nocopy(gval,
313
gconf_value_from_corba_value((ConfigValue*)&value->_u.list_value.seq._buffer[1]));
317
g_assert_not_reached();
325
fill_corba_value_from_gconf_value(GConfValue* value,
336
case GCONF_VALUE_INT:
338
cv->_u.int_value = gconf_value_get_int(value);
340
case GCONF_VALUE_STRING:
342
cv->_u.string_value = CORBA_string_dup((char*)gconf_value_get_string(value));
344
case GCONF_VALUE_FLOAT:
346
cv->_u.float_value = gconf_value_get_float(value);
348
case GCONF_VALUE_BOOL:
350
cv->_u.bool_value = gconf_value_get_bool(value);
352
case GCONF_VALUE_SCHEMA:
354
fill_corba_schema_from_gconf_schema(gconf_value_get_schema(value),
355
&cv->_u.schema_value);
357
case GCONF_VALUE_LIST:
364
list = gconf_value_get_list(value);
366
n = g_slist_length(list);
368
cv->_u.list_value.seq._buffer =
369
CORBA_sequence_ConfigBasicValue_allocbuf(n);
370
cv->_u.list_value.seq._length = n;
371
cv->_u.list_value.seq._maximum = n;
372
CORBA_sequence_set_release(&cv->_u.list_value.seq, TRUE);
374
switch (gconf_value_get_list_type(value))
376
case GCONF_VALUE_INT:
377
cv->_u.list_value.list_type = BIntVal;
380
case GCONF_VALUE_BOOL:
381
cv->_u.list_value.list_type = BBoolVal;
384
case GCONF_VALUE_STRING:
385
cv->_u.list_value.list_type = BStringVal;
388
case GCONF_VALUE_FLOAT:
389
cv->_u.list_value.list_type = BFloatVal;
392
case GCONF_VALUE_SCHEMA:
393
cv->_u.list_value.list_type = BSchemaVal;
397
cv->_u.list_value.list_type = BInvalidVal;
398
gconf_log(GCL_DEBUG, "Invalid list type in %s", G_GNUC_FUNCTION);
405
/* That dubious ConfigBasicValue->ConfigValue cast again */
406
fill_corba_value_from_gconf_value((GConfValue*)list->data,
407
(ConfigValue*)&cv->_u.list_value.seq._buffer[i]);
409
list = g_slist_next(list);
414
case GCONF_VALUE_PAIR:
418
cv->_u.pair_value._buffer =
419
CORBA_sequence_ConfigBasicValue_allocbuf(2);
420
cv->_u.pair_value._length = 2;
421
cv->_u.pair_value._maximum = 2;
422
CORBA_sequence_set_release(&cv->_u.pair_value, TRUE);
425
fill_corba_value_from_gconf_value(gconf_value_get_car(value),
426
(ConfigValue*)&cv->_u.pair_value._buffer[0]);
427
fill_corba_value_from_gconf_value(gconf_value_get_cdr(value),
428
(ConfigValue*)&cv->_u.pair_value._buffer[1]);
432
case GCONF_VALUE_INVALID:
437
gconf_log(GCL_DEBUG, "Unknown type in %s", G_GNUC_FUNCTION);
443
corba_value_from_gconf_value(GConfValue* value)
447
cv = ConfigValue__alloc();
449
fill_corba_value_from_gconf_value(value, cv);
455
invalid_corba_value()
459
cv = ConfigValue__alloc();
467
gconf_object_to_string (CORBA_Object obj,
470
CORBA_Environment ev;
474
CORBA_exception_init (&ev);
476
ior = CORBA_ORB_object_to_string (gconf_orb_get (), obj, &ev);
480
gconf_set_error (err,
482
_("Failed to convert object to IOR"));
487
retval = g_strdup (ior);
494
static ConfigValueType
495
corba_type_from_gconf_type(GConfValueType type)
499
case GCONF_VALUE_INT:
501
case GCONF_VALUE_BOOL:
503
case GCONF_VALUE_FLOAT:
505
case GCONF_VALUE_INVALID:
507
case GCONF_VALUE_STRING:
509
case GCONF_VALUE_SCHEMA:
511
case GCONF_VALUE_LIST:
513
case GCONF_VALUE_PAIR:
516
g_assert_not_reached();
521
static GConfValueType
522
gconf_type_from_corba_type(ConfigValueType type)
527
return GCONF_VALUE_INVALID;
529
return GCONF_VALUE_STRING;
531
return GCONF_VALUE_INT;
533
return GCONF_VALUE_FLOAT;
535
return GCONF_VALUE_SCHEMA;
537
return GCONF_VALUE_BOOL;
539
return GCONF_VALUE_LIST;
541
return GCONF_VALUE_PAIR;
543
g_assert_not_reached();
544
return GCONF_VALUE_INVALID;
549
fill_corba_schema_from_gconf_schema(GConfSchema* sc,
552
cs->value_type = corba_type_from_gconf_type(sc->type);
553
cs->value_list_type = corba_type_from_gconf_type(sc->list_type);
554
cs->value_car_type = corba_type_from_gconf_type(sc->car_type);
555
cs->value_cdr_type = corba_type_from_gconf_type(sc->cdr_type);
557
cs->locale = CORBA_string_dup(sc->locale ? sc->locale : "");
558
cs->short_desc = CORBA_string_dup(sc->short_desc ? sc->short_desc : "");
559
cs->long_desc = CORBA_string_dup(sc->long_desc ? sc->long_desc : "");
560
cs->owner = CORBA_string_dup(sc->owner ? sc->owner : "");
564
GConfValue* default_val;
566
default_val = gconf_schema_get_default_value(sc);
570
encoded = gconf_value_encode(default_val);
572
g_assert(encoded != NULL);
574
cs->encoded_default_value = CORBA_string_dup(encoded);
579
cs->encoded_default_value = CORBA_string_dup("");
584
corba_schema_from_gconf_schema(GConfSchema* sc)
588
cs = ConfigSchema__alloc();
590
fill_corba_schema_from_gconf_schema(sc, cs);
596
gconf_schema_from_corba_schema(const ConfigSchema* cs)
599
GConfValueType type = GCONF_VALUE_INVALID;
600
GConfValueType list_type = GCONF_VALUE_INVALID;
601
GConfValueType car_type = GCONF_VALUE_INVALID;
602
GConfValueType cdr_type = GCONF_VALUE_INVALID;
604
type = gconf_type_from_corba_type(cs->value_type);
605
list_type = gconf_type_from_corba_type(cs->value_list_type);
606
car_type = gconf_type_from_corba_type(cs->value_car_type);
607
cdr_type = gconf_type_from_corba_type(cs->value_cdr_type);
609
sc = gconf_schema_new();
611
gconf_schema_set_type(sc, type);
612
gconf_schema_set_list_type(sc, list_type);
613
gconf_schema_set_car_type(sc, car_type);
614
gconf_schema_set_cdr_type(sc, cdr_type);
616
if (*cs->locale != '\0')
618
if (!g_utf8_validate (cs->locale, -1, NULL))
619
gconf_log (GCL_ERR, _("Invalid UTF-8 in locale for schema"));
621
gconf_schema_set_locale(sc, cs->locale);
624
if (*cs->short_desc != '\0')
626
if (!g_utf8_validate (cs->short_desc, -1, NULL))
627
gconf_log (GCL_ERR, _("Invalid UTF-8 in short description for schema"));
629
gconf_schema_set_short_desc(sc, cs->short_desc);
632
if (*cs->long_desc != '\0')
634
if (!g_utf8_validate (cs->long_desc, -1, NULL))
635
gconf_log (GCL_ERR, _("Invalid UTF-8 in long description for schema"));
637
gconf_schema_set_long_desc(sc, cs->long_desc);
640
if (*cs->owner != '\0')
642
if (!g_utf8_validate (cs->owner, -1, NULL))
643
gconf_log (GCL_ERR, _("Invalid UTF-8 in owner for schema"));
645
gconf_schema_set_owner(sc, cs->owner);
651
val = gconf_value_decode(cs->encoded_default_value);
654
gconf_schema_set_default_value_nocopy(sc, val);
661
gconf_value_type_to_string(GConfValueType type)
665
case GCONF_VALUE_INT:
668
case GCONF_VALUE_STRING:
671
case GCONF_VALUE_FLOAT:
674
case GCONF_VALUE_BOOL:
677
case GCONF_VALUE_SCHEMA:
680
case GCONF_VALUE_LIST:
683
case GCONF_VALUE_PAIR:
686
case GCONF_VALUE_INVALID:
690
g_assert_not_reached();
691
return NULL; /* for warnings */
697
gconf_value_type_from_string(const gchar* type_str)
699
if (strcmp(type_str, "int") == 0)
700
return GCONF_VALUE_INT;
701
else if (strcmp(type_str, "float") == 0)
702
return GCONF_VALUE_FLOAT;
703
else if (strcmp(type_str, "string") == 0)
704
return GCONF_VALUE_STRING;
705
else if (strcmp(type_str, "bool") == 0)
706
return GCONF_VALUE_BOOL;
707
else if (strcmp(type_str, "schema") == 0)
708
return GCONF_VALUE_SCHEMA;
709
else if (strcmp(type_str, "list") == 0)
710
return GCONF_VALUE_LIST;
711
else if (strcmp(type_str, "pair") == 0)
712
return GCONF_VALUE_PAIR;
714
return GCONF_VALUE_INVALID;
718
* Config files (yikes! we can't store our config in GConf!)
722
unquote_string(gchar* s)
726
/* Strip whitespace and first quote from front of string */
727
while (*s && (isspace(*s) || (*s == '"')))
734
--end; /* one back from '\0' */
736
/* Strip whitespace and last quote from end of string */
737
while ((end > s) && (isspace(*end) || (*end == '"')))
747
get_variable(const gchar* varname)
749
/* These first two DO NOT use environment variables, which
750
makes things a bit more "secure" in some sense
752
if (strcmp(varname, "HOME") == 0)
754
return g_get_home_dir();
756
else if (strcmp(varname, "USER") == 0)
758
return g_get_user_name();
760
else if (varname[0] == 'E' &&
765
/* This is magic: if a variable called ENV_FOO is used,
766
then the environment variable FOO is checked */
767
gchar* envvar = getenv(&varname[4]);
779
subst_variables(const gchar* src)
786
g_return_val_if_fail(src != NULL, NULL);
788
retval_len = strlen(src) + 1;
791
retval = g_malloc0(retval_len+3); /* add 3 just to avoid off-by-one
792
segvs - yeah I know it bugs
799
gboolean performed_subst = FALSE;
801
if (pos >= retval_len)
804
retval = g_realloc(retval, retval_len+3); /* add 3 for luck */
807
if (*iter == '$' && *(iter+1) == '(')
809
const gchar* varstart = iter + 2;
810
const gchar* varend = strchr(varstart, ')');
818
performed_subst = TRUE;
820
varname = g_strndup(varstart, varend - varstart);
822
varval = get_variable(varname);
825
varval_len = strlen(varval);
827
if ((retval_len - pos) < varval_len)
830
retval = g_realloc(retval, retval_len+3);
833
strcpy(&retval[pos], varval);
840
if (!performed_subst)
853
gconf_load_source_path(const gchar* filename, GError** err)
862
f = fopen(filename, "r");
867
*err = gconf_error_new(GCONF_ERROR_FAILED,
868
_("Couldn't open path file `%s': %s\n"),
874
while (fgets(buf, 512, f) != NULL)
878
while (*s && isspace(*s))
883
/* Allow comments, why not */
889
else if (strncmp("include", s, 7) == 0)
897
unq = unquote_string(s);
899
varsubst = subst_variables (unq);
901
included = gconf_load_source_path (varsubst, NULL);
905
if (included != NULL)
907
gchar** iter = included;
911
l = g_slist_prepend(l, *iter); /* Note that we won't free *included */
915
g_free(included); /* Only the array, not the contained strings */
923
unq = unquote_string(buf);
924
varsubst = subst_variables(unq);
926
if (*varsubst != '\0') /* Drop lines with just two quote marks or something */
928
gconf_log(GCL_DEBUG, _("Adding source `%s'\n"), varsubst);
929
l = g_slist_prepend(l, g_strdup(varsubst));
937
/* This should basically never happen */
939
*err = gconf_error_new(GCONF_ERROR_FAILED,
940
_("Read error on file `%s': %s\n"),
943
/* don't return, we want to go ahead and return any
944
addresses we already loaded. */
949
/* This will make sense if you realize that we reversed the list
950
as we loaded it, and are now reversing it to be correct again.
956
n = g_slist_length(l);
960
addresses = g_malloc0(sizeof(gchar*) * (n+1));
969
addresses[n] = tmp->data;
971
tmp = g_slist_next(tmp);
975
g_assert(addresses[0] != NULL); /* since we used malloc0 this detects bad logic */
980
/* This should also support concatting filesystem dirs and keys,
984
gconf_concat_dir_and_key(const gchar* dir, const gchar* key)
990
g_return_val_if_fail(dir != NULL, NULL);
991
g_return_val_if_fail(key != NULL, NULL);
992
g_return_val_if_fail(*dir == '/', NULL);
994
dirlen = strlen(dir);
995
keylen = strlen(key);
997
retval = g_malloc0(dirlen+keylen+3); /* auto-null-terminate */
1001
if (dir[dirlen-1] == '/')
1003
/* dir ends in slash, strip key slash if needed */
1007
strcpy((retval+dirlen), key);
1011
/* Dir doesn't end in slash, add slash if key lacks one. */
1012
gchar* dest = retval + dirlen;
1027
gconf_string_to_gulong(const gchar* str)
1032
retval = strtoul(str, &end, 10);
1033
if (end == str || errno != 0)
1040
gconf_string_to_double(const gchar* str, gdouble* retloc)
1045
/* make sure we write values to files in a consistent manner */
1046
old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
1047
setlocale (LC_NUMERIC, "C");
1050
res = sscanf (str, "%lf", retloc);
1052
setlocale (LC_NUMERIC, old_locale);
1053
g_free (old_locale);
1062
gconf_double_to_string(gdouble val)
1064
char str[101 + DBL_DIG];
1067
/* make sure we write values to files in a consistent manner */
1068
old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
1069
setlocale (LC_NUMERIC, "C");
1071
if (fabs (val) < 1e9 && fabs (val) > 1e-5)
1072
g_snprintf (str, 100 + DBL_DIG, "%.*g", DBL_DIG, val);
1074
g_snprintf (str, 100 + DBL_DIG, "%f", val);
1076
setlocale (LC_NUMERIC, old_locale);
1077
g_free (old_locale);
1079
return g_strdup(str);
1083
gconf_current_locale(void)
1085
#ifdef HAVE_LC_MESSAGES
1086
return setlocale(LC_MESSAGES, NULL);
1088
return setlocale(LC_CTYPE, NULL);
1097
gconf_quote_percents(const gchar* src)
1103
g_return_val_if_fail(src != NULL, NULL);
1105
/* waste memory! woo-hoo! */
1106
dest = g_malloc0(strlen(src)*2+4);
1143
gconf_log(GConfLogPriority pri, const gchar* fmt, ...)
1147
int syslog_pri = LOG_DEBUG;
1149
if (!gconf_log_debug_messages &&
1153
va_start (args, fmt);
1154
msg = g_strdup_vprintf(fmt, args);
1157
if (gconf_daemon_mode)
1162
syslog_pri = LOG_EMERG;
1166
syslog_pri = LOG_ALERT;
1170
syslog_pri = LOG_CRIT;
1174
syslog_pri = LOG_ERR;
1178
syslog_pri = LOG_WARNING;
1182
syslog_pri = LOG_NOTICE;
1186
syslog_pri = LOG_INFO;
1190
syslog_pri = LOG_DEBUG;
1194
g_assert_not_reached();
1198
syslog(syslog_pri, "%s", msg);
1209
fprintf(stderr, "%s\n", msg);
1215
printf("%s\n", msg);
1219
g_assert_not_reached();
1228
* List/pair conversion
1232
gconf_value_list_from_primitive_list(GConfValueType list_type, GSList* list,
1238
g_return_val_if_fail(list_type != GCONF_VALUE_INVALID, NULL);
1239
g_return_val_if_fail(list_type != GCONF_VALUE_LIST, NULL);
1240
g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, NULL);
1250
val = gconf_value_new(list_type);
1254
case GCONF_VALUE_INT:
1255
gconf_value_set_int(val, GPOINTER_TO_INT(tmp->data));
1258
case GCONF_VALUE_BOOL:
1259
gconf_value_set_bool(val, GPOINTER_TO_INT(tmp->data));
1262
case GCONF_VALUE_FLOAT:
1263
gconf_value_set_float(val, *((gdouble*)tmp->data));
1266
case GCONF_VALUE_STRING:
1267
if (!g_utf8_validate (tmp->data, -1, NULL))
1269
g_set_error (err, GCONF_ERROR,
1271
_("Text contains invalid UTF-8"));
1275
gconf_value_set_string(val, tmp->data);
1278
case GCONF_VALUE_SCHEMA:
1279
if (!gconf_schema_validate (tmp->data, err))
1281
gconf_value_set_schema(val, tmp->data);
1285
g_assert_not_reached();
1289
value_list = g_slist_prepend(value_list, val);
1291
tmp = g_slist_next(tmp);
1294
/* Get it in the right order. */
1295
value_list = g_slist_reverse(value_list);
1298
GConfValue* value_with_list;
1300
value_with_list = gconf_value_new(GCONF_VALUE_LIST);
1301
gconf_value_set_list_type(value_with_list, list_type);
1302
gconf_value_set_list_nocopy(value_with_list, value_list);
1304
return value_with_list;
1308
g_slist_foreach (value_list, (GFunc)gconf_value_free, NULL);
1309
g_slist_free (value_list);
1315
from_primitive(GConfValueType type, gconstpointer address,
1320
val = gconf_value_new(type);
1324
case GCONF_VALUE_INT:
1325
gconf_value_set_int(val, *((const gint*)address));
1328
case GCONF_VALUE_BOOL:
1329
gconf_value_set_bool(val, *((const gboolean*)address));
1332
case GCONF_VALUE_STRING:
1333
if (!g_utf8_validate (*((const gchar**)address), -1, NULL))
1335
g_set_error (err, GCONF_ERROR,
1337
_("Text contains invalid UTF-8"));
1338
gconf_value_free (val);
1342
gconf_value_set_string(val, *((const gchar**)address));
1345
case GCONF_VALUE_FLOAT:
1346
gconf_value_set_float(val, *((const gdouble*)address));
1349
case GCONF_VALUE_SCHEMA:
1350
if (!gconf_schema_validate (*((GConfSchema**)address), err))
1352
gconf_value_free (val);
1356
gconf_value_set_schema(val, *((GConfSchema**)address));
1360
g_assert_not_reached();
1368
gconf_value_pair_from_primitive_pair(GConfValueType car_type,
1369
GConfValueType cdr_type,
1370
gconstpointer address_of_car,
1371
gconstpointer address_of_cdr,
1378
g_return_val_if_fail(car_type != GCONF_VALUE_INVALID, NULL);
1379
g_return_val_if_fail(car_type != GCONF_VALUE_LIST, NULL);
1380
g_return_val_if_fail(car_type != GCONF_VALUE_PAIR, NULL);
1381
g_return_val_if_fail(cdr_type != GCONF_VALUE_INVALID, NULL);
1382
g_return_val_if_fail(cdr_type != GCONF_VALUE_LIST, NULL);
1383
g_return_val_if_fail(cdr_type != GCONF_VALUE_PAIR, NULL);
1384
g_return_val_if_fail(address_of_car != NULL, NULL);
1385
g_return_val_if_fail(address_of_cdr != NULL, NULL);
1387
car = from_primitive(car_type, address_of_car, err);
1390
cdr = from_primitive(cdr_type, address_of_cdr, err);
1393
gconf_value_free (car);
1397
pair = gconf_value_new(GCONF_VALUE_PAIR);
1398
gconf_value_set_car_nocopy(pair, car);
1399
gconf_value_set_cdr_nocopy(pair, cdr);
1406
gconf_value_list_to_primitive_list_destructive(GConfValue* val,
1407
GConfValueType list_type,
1412
g_return_val_if_fail(val != NULL, NULL);
1413
g_return_val_if_fail(list_type != GCONF_VALUE_INVALID, NULL);
1414
g_return_val_if_fail(list_type != GCONF_VALUE_LIST, NULL);
1415
g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, NULL);
1416
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1418
if (val->type != GCONF_VALUE_LIST)
1421
*err = gconf_error_new(GCONF_ERROR_TYPE_MISMATCH,
1422
_("Expected list, got %s"),
1423
gconf_value_type_to_string(val->type));
1424
gconf_value_free(val);
1428
if (gconf_value_get_list_type(val) != list_type)
1431
*err = gconf_error_new(GCONF_ERROR_TYPE_MISMATCH,
1432
_("Expected list of %s, got list of %s"),
1433
gconf_value_type_to_string(list_type),
1434
gconf_value_type_to_string(val->type));
1435
gconf_value_free(val);
1439
g_assert(gconf_value_get_list_type(val) == list_type);
1441
retval = gconf_value_get_list(val);
1443
/* Cheating the API to avoid a list copy; set this to NULL to
1444
avoid destroying the list */
1445
val->d.list_data.list = NULL;
1447
gconf_value_free(val);
1451
/* map (typeChange, retval) */
1458
GConfValue* elem = tmp->data;
1460
g_assert(elem != NULL);
1461
g_assert(elem->type == list_type);
1465
case GCONF_VALUE_INT:
1466
case GCONF_VALUE_BOOL:
1467
tmp->data = GINT_TO_POINTER(gconf_value_get_int(elem));
1470
case GCONF_VALUE_FLOAT:
1472
gdouble* d = g_new(gdouble, 1);
1473
*d = gconf_value_get_float(elem);
1478
case GCONF_VALUE_STRING:
1480
/* Cheat again, and steal the string from the value */
1481
tmp->data = elem->d.string_data;
1482
elem->d.string_data = NULL;
1486
case GCONF_VALUE_SCHEMA:
1488
/* and also steal the schema... */
1489
tmp->data = elem->d.schema_data;
1490
elem->d.schema_data = NULL;
1495
g_assert_not_reached();
1499
/* Clean up the value */
1500
gconf_value_free(elem);
1502
tmp = g_slist_next(tmp);
1504
} /* list conversion block */
1511
primitive_value(gpointer retloc, GConfValue* val)
1515
case GCONF_VALUE_INT:
1516
*((gint*)retloc) = gconf_value_get_int(val);
1519
case GCONF_VALUE_FLOAT:
1520
*((gdouble*)retloc) = gconf_value_get_float(val);
1523
case GCONF_VALUE_STRING:
1525
*((gchar**)retloc) = val->d.string_data;
1526
/* cheat and steal the string to avoid a copy */
1527
val->d.string_data = NULL;
1531
case GCONF_VALUE_BOOL:
1532
*((gboolean*)retloc) = gconf_value_get_bool(val);
1535
case GCONF_VALUE_SCHEMA:
1536
*((GConfSchema**)retloc) = gconf_value_get_schema(val);
1540
g_assert_not_reached();
1546
gconf_value_pair_to_primitive_pair_destructive(GConfValue* val,
1547
GConfValueType car_type,
1548
GConfValueType cdr_type,
1549
gpointer car_retloc,
1550
gpointer cdr_retloc,
1556
g_return_val_if_fail(val != NULL, FALSE);
1557
g_return_val_if_fail(car_type != GCONF_VALUE_INVALID, FALSE);
1558
g_return_val_if_fail(car_type != GCONF_VALUE_LIST, FALSE);
1559
g_return_val_if_fail(car_type != GCONF_VALUE_PAIR, FALSE);
1560
g_return_val_if_fail(cdr_type != GCONF_VALUE_INVALID, FALSE);
1561
g_return_val_if_fail(cdr_type != GCONF_VALUE_LIST, FALSE);
1562
g_return_val_if_fail(cdr_type != GCONF_VALUE_PAIR, FALSE);
1563
g_return_val_if_fail(car_retloc != NULL, FALSE);
1564
g_return_val_if_fail(cdr_retloc != NULL, FALSE);
1565
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
1567
if (val->type != GCONF_VALUE_PAIR)
1570
*err = gconf_error_new(GCONF_ERROR_TYPE_MISMATCH,
1571
_("Expected pair, got %s"),
1572
gconf_value_type_to_string(val->type));
1573
gconf_value_free(val);
1577
car = gconf_value_get_car(val);
1578
cdr = gconf_value_get_cdr(val);
1584
*err = gconf_error_new(GCONF_ERROR_TYPE_MISMATCH,
1585
_("Expected (%s,%s) pair, got a pair with one or both values missing"),
1586
gconf_value_type_to_string(car_type),
1587
gconf_value_type_to_string(cdr_type));
1589
gconf_value_free(val);
1593
g_assert(car != NULL);
1594
g_assert(cdr != NULL);
1596
if (car->type != car_type ||
1597
cdr->type != cdr_type)
1600
*err = gconf_error_new(GCONF_ERROR_TYPE_MISMATCH,
1601
_("Expected pair of type (%s,%s) got type (%s,%s)"),
1602
gconf_value_type_to_string(car_type),
1603
gconf_value_type_to_string(cdr_type),
1604
gconf_value_type_to_string(car->type),
1605
gconf_value_type_to_string(cdr->type));
1606
gconf_value_free(val);
1610
primitive_value(car_retloc, car);
1611
primitive_value(cdr_retloc, cdr);
1613
gconf_value_free(val);
1625
gconf_quote_string (const gchar* src)
1631
g_return_val_if_fail(src != NULL, NULL);
1633
/* waste memory! woo-hoo! */
1634
dest = g_malloc0(strlen(src)*2+4);
1674
/* End with quote mark and NULL */
1683
gconf_unquote_string (const gchar* str, const gchar** end, GError** err)
1686
gchar* unq_end = NULL;
1688
g_return_val_if_fail(end != NULL, NULL);
1689
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1690
g_return_val_if_fail(str != NULL, NULL);
1692
unq = g_strdup(str);
1694
gconf_unquote_string_inplace(unq, &unq_end, err);
1696
*end = (str + (unq_end - unq));
1702
gconf_unquote_string_inplace (gchar* str, gchar** end, GError** err)
1707
g_return_if_fail(end != NULL);
1708
g_return_if_fail(err == NULL || *err == NULL);
1709
g_return_if_fail(str != NULL);
1716
*err = gconf_error_new(GCONF_ERROR_PARSE_ERROR,
1717
_("Quoted string doesn't begin with a quotation mark"));
1722
/* Skip the initial quote mark */
1727
g_assert(s > dest); /* loop invariant */
1732
/* End of the string, return now */
1740
/* Possible escaped quote or \ */
1748
else if (*s == '\\')
1756
/* not an escaped char */
1759
/* ++s already done. */
1770
g_assert(s > dest); /* loop invariant */
1773
/* If we reach here this means the close quote was never encountered */
1778
*err = gconf_error_new(GCONF_ERROR_PARSE_ERROR,
1779
_("Quoted string doesn't end with a quotation mark"));
1784
/* The encoding format
1786
The first byte of the encoded string is the type of the value:
1797
For int, the rest of the encoded value is the integer to be parsed with atoi()
1798
For bool, the rest is 't' or 'f'
1799
For float, the rest is a float to parse with g_strtod()
1800
For string, the rest is the string (not quoted)
1801
For schema, the encoding is complicated; see below.
1802
For pair, the rest is two primitive encodings (ibcfs), quoted, separated by a comma,
1804
For list, first character is type, the rest is primitive encodings, quoted,
1809
After the 'c' indicating schema, the second character is a byte indicating
1810
the type the schema expects. Then a comma, and the quoted locale, or "" for none.
1811
comma, and quoted short description; comma, quoted long description; comma, default
1812
value in the encoded format given above, quoted.
1815
static gchar type_byte(GConfValueType type)
1819
case GCONF_VALUE_INT:
1823
case GCONF_VALUE_BOOL:
1827
case GCONF_VALUE_FLOAT:
1831
case GCONF_VALUE_STRING:
1835
case GCONF_VALUE_SCHEMA:
1839
case GCONF_VALUE_LIST:
1843
case GCONF_VALUE_PAIR:
1847
case GCONF_VALUE_INVALID:
1852
g_assert_not_reached();
1859
byte_type(gchar byte)
1864
return GCONF_VALUE_INT;
1868
return GCONF_VALUE_BOOL;
1872
return GCONF_VALUE_STRING;
1876
return GCONF_VALUE_SCHEMA;
1880
return GCONF_VALUE_FLOAT;
1884
return GCONF_VALUE_LIST;
1888
return GCONF_VALUE_PAIR;
1892
return GCONF_VALUE_INVALID;
1896
return GCONF_VALUE_INVALID;
1902
gconf_value_decode (const gchar* encoded)
1904
GConfValueType type;
1908
type = byte_type(*encoded);
1910
if (type == GCONF_VALUE_INVALID)
1913
if (!g_utf8_validate (encoded, -1, NULL))
1915
gconf_log (GCL_ERR, _("Encoded value is not valid UTF-8"));
1919
val = gconf_value_new(type);
1925
case GCONF_VALUE_INT:
1926
gconf_value_set_int(val, atoi(s));
1929
case GCONF_VALUE_BOOL:
1930
gconf_value_set_bool(val, *s == 't' ? TRUE : FALSE);
1933
case GCONF_VALUE_FLOAT:
1936
gchar* endptr = NULL;
1938
d = g_strtod(s, &endptr);
1940
g_warning("Failure converting string to double in %s", G_GNUC_FUNCTION);
1941
gconf_value_set_float(val, d);
1945
case GCONF_VALUE_STRING:
1947
gconf_value_set_string(val, s);
1951
case GCONF_VALUE_SCHEMA:
1953
GConfSchema* sc = gconf_schema_new();
1954
const gchar* end = NULL;
1957
gconf_value_set_schema(val, sc);
1959
gconf_schema_set_type(sc, byte_type(*s));
1961
gconf_schema_set_list_type(sc, byte_type(*s));
1963
gconf_schema_set_car_type(sc, byte_type(*s));
1965
gconf_schema_set_cdr_type(sc, byte_type(*s));
1969
unquoted = gconf_unquote_string(s, &end, NULL);
1971
gconf_schema_set_locale(sc, unquoted);
1976
g_warning("no comma after locale in schema");
1982
unquoted = gconf_unquote_string(s, &end, NULL);
1984
gconf_schema_set_short_desc(sc, unquoted);
1989
g_warning("no comma after short desc in schema");
1996
unquoted = gconf_unquote_string(s, &end, NULL);
1998
gconf_schema_set_long_desc(sc, unquoted);
2003
g_warning("no comma after long desc in schema");
2010
unquoted = gconf_unquote_string(s, &end, NULL);
2012
gconf_schema_set_default_value_nocopy(sc, gconf_value_decode(unquoted));
2017
g_warning("trailing junk after encoded schema");
2021
case GCONF_VALUE_LIST:
2023
GSList* value_list = NULL;
2025
gconf_value_set_list_type(val, byte_type(*s));
2035
unquoted = gconf_unquote_string(s, &end, NULL);
2037
elem = gconf_value_decode(unquoted);
2042
value_list = g_slist_prepend(value_list, elem);
2047
else if (*s != '\0')
2049
g_warning("weird character in encoded list");
2054
value_list = g_slist_reverse(value_list);
2056
gconf_value_set_list_nocopy(val, value_list);
2060
case GCONF_VALUE_PAIR:
2068
unquoted = gconf_unquote_string(s, &end, NULL);
2070
car = gconf_value_decode(unquoted);
2079
g_warning("weird character in encoded pair");
2082
unquoted = gconf_unquote_string(s, &end, NULL);
2084
cdr = gconf_value_decode(unquoted);
2088
gconf_value_set_car_nocopy(val, car);
2089
gconf_value_set_cdr_nocopy(val, cdr);
2094
g_assert_not_reached();
2102
gconf_value_encode (GConfValue* val)
2104
gchar* retval = NULL;
2106
g_return_val_if_fail(val != NULL, NULL);
2110
case GCONF_VALUE_INT:
2111
retval = g_strdup_printf("i%d", gconf_value_get_int(val));
2114
case GCONF_VALUE_BOOL:
2115
retval = g_strdup_printf("b%c", gconf_value_get_bool(val) ? 't' : 'f');
2118
case GCONF_VALUE_FLOAT:
2119
retval = g_strdup_printf("f%g", gconf_value_get_float(val));
2122
case GCONF_VALUE_STRING:
2123
retval = g_strdup_printf("s%s", gconf_value_get_string(val));
2126
case GCONF_VALUE_SCHEMA:
2134
sc = gconf_value_get_schema(val);
2136
tmp = g_strdup_printf("c%c%c%c%c,",
2137
type_byte(gconf_schema_get_type(sc)),
2138
type_byte(gconf_schema_get_list_type(sc)),
2139
type_byte(gconf_schema_get_car_type(sc)),
2140
type_byte(gconf_schema_get_cdr_type(sc)));
2142
quoted = gconf_quote_string(gconf_schema_get_locale(sc) ?
2143
gconf_schema_get_locale(sc) : "");
2144
retval = g_strconcat(tmp, quoted, ",", NULL);
2150
quoted = gconf_quote_string(gconf_schema_get_short_desc(sc) ?
2151
gconf_schema_get_short_desc(sc) : "");
2153
retval = g_strconcat(tmp, quoted, ",", NULL);
2160
quoted = gconf_quote_string(gconf_schema_get_long_desc(sc) ?
2161
gconf_schema_get_long_desc(sc) : "");
2163
retval = g_strconcat(tmp, quoted, ",", NULL);
2169
if (gconf_schema_get_default_value(sc) != NULL)
2170
encoded = gconf_value_encode(gconf_schema_get_default_value(sc));
2172
encoded = g_strdup("");
2176
quoted = gconf_quote_string(encoded);
2178
retval = g_strconcat(tmp, quoted, NULL);
2186
case GCONF_VALUE_LIST:
2190
retval = g_strdup_printf("l%c", type_byte(gconf_value_get_list_type(val)));
2192
tmp = gconf_value_get_list(val);
2196
GConfValue* elem = tmp->data;
2200
g_assert(elem != NULL);
2202
encoded = gconf_value_encode(elem);
2204
quoted = gconf_quote_string(encoded);
2212
retval = g_strconcat(retval, ",", quoted, NULL);
2218
tmp = g_slist_next(tmp);
2223
case GCONF_VALUE_PAIR:
2230
car_encoded = gconf_value_encode(gconf_value_get_car(val));
2231
cdr_encoded = gconf_value_encode(gconf_value_get_cdr(val));
2233
car_quoted = gconf_quote_string(car_encoded);
2234
cdr_quoted = gconf_quote_string(cdr_encoded);
2236
retval = g_strconcat("p", car_quoted, ",", cdr_quoted, NULL);
2238
g_free(car_encoded);
2239
g_free(cdr_encoded);
2246
g_assert_not_reached();
2255
gconf_handle_oaf_exception(CORBA_Environment* ev, GError** err)
2259
case CORBA_NO_EXCEPTION:
2260
CORBA_exception_free(ev);
2263
case CORBA_SYSTEM_EXCEPTION:
2265
*err = gconf_error_new (GCONF_ERROR_NO_SERVER, _("CORBA error: %s"),
2266
CORBA_exception_id (ev));
2267
CORBA_exception_free (ev);
2271
case CORBA_USER_EXCEPTION:
2273
const gchar* id = CORBA_exception_id(ev);
2275
if (strcmp(id, "IDL:OAF/GeneralError:1.0") == 0)
2277
OAF_GeneralError* ge = CORBA_exception_value(ev);
2280
*err = gconf_error_new (GCONF_ERROR_OAF_ERROR,
2281
_("OAF problem description: '%s'"),
2284
else if (strcmp (id,"IDL:OAF/ActivationContext/NotListed:1.0" ) == 0)
2287
*err = gconf_error_new(GCONF_ERROR_OAF_ERROR, _("attempt to remove not-listed OAF object directory"));
2289
else if (strcmp (id,"IDL:OAF/ActivationContext/AlreadyListed:1.0" ) == 0)
2292
*err = gconf_error_new(GCONF_ERROR_OAF_ERROR, _("attempt to add already-listed OAF directory"));
2294
else if (strcmp (id,"IDL:OAF/ActivationContext/ParseFailed:1.0") == 0)
2296
OAF_ActivationContext_ParseFailed* pe = CORBA_exception_value(ev);
2299
*err = gconf_error_new(GCONF_ERROR_OAF_ERROR, _("OAF parse error: %s"), pe->description);
2304
*err = gconf_error_new(GCONF_ERROR_OAF_ERROR, _("Unknown OAF error"));
2307
CORBA_exception_free(ev);
2312
g_assert_not_reached();
2323
* Locks works as follows. We have a lock directory to hold the locking
2324
* mess, and we have an IOR file inside the lock directory with the
2325
* gconfd IOR, and we have an fcntl() lock on the IOR file. The IOR
2326
* file is created atomically using a temporary file, then link()
2330
gchar *lock_directory;
2336
gconf_lock_destroy (GConfLock* lock)
2338
if (lock->lock_fd >= 0)
2339
close (lock->lock_fd);
2340
g_free (lock->iorfile);
2341
g_free (lock->lock_directory);
2346
set_close_on_exec (int fd)
2350
val = fcntl (fd, F_GETFD, 0);
2353
gconf_log (GCL_DEBUG, "couldn't F_GETFD: %s\n", g_strerror (errno));
2359
if (fcntl (fd, F_SETFD, val) < 0)
2360
gconf_log (GCL_DEBUG, "couldn't F_SETFD: %s\n", g_strerror (errno));
2363
/* Your basic Stevens cut-and-paste */
2365
lock_reg (int fd, int cmd, int type, off_t offset, int whence, off_t len)
2369
lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
2370
lock.l_start = offset; /* byte offset relative to whence */
2371
lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
2372
lock.l_len = len; /* #bytes, 0 for eof */
2374
return fcntl (fd, cmd, &lock);
2377
#define lock_entire_file(fd) \
2378
lock_reg ((fd), F_SETLK, F_WRLCK, 0, SEEK_SET, 0)
2379
#define unlock_entire_file(fd) \
2380
lock_reg ((fd), F_SETLK, F_UNLCK, 0, SEEK_SET, 0)
2383
file_locked_by_someone_else (int fd)
2387
lock.l_type = F_WRLCK;
2389
lock.l_whence = SEEK_SET;
2392
if (fcntl (fd, F_GETLK, &lock) < 0)
2393
return TRUE; /* pretend it's locked */
2395
if (lock.l_type == F_UNLCK)
2396
return FALSE; /* we have the lock */
2398
return TRUE; /* someone else has it */
2402
unique_filename (const char *directory)
2407
guid = gconf_unique_key ();
2408
uniquefile = g_strconcat (directory, "/", guid, NULL);
2415
create_new_locked_file (const gchar *directory,
2416
const gchar *filename,
2425
uniquefile = unique_filename (directory);
2427
fd = open (uniquefile, O_WRONLY | O_CREAT, 0700);
2429
/* Lock our temporary file, lock hopefully applies to the
2430
* inode and so also counts once we link it to the new name
2432
if (lock_entire_file (fd) < 0)
2436
GCONF_ERROR_LOCK_FAILED,
2437
_("Could not lock temporary file '%s': %s"),
2438
uniquefile, g_strerror (errno));
2442
/* Create lockfile as a link to unique file */
2443
if (link (uniquefile, filename) == 0)
2445
/* filename didn't exist before, and open succeeded, and we have the lock */
2451
/* see if the link really succeeded */
2453
if (stat (uniquefile, &sb) == 0 &&
2463
GCONF_ERROR_LOCK_FAILED,
2464
_("Could not create file '%s', probably because it already exists"),
2472
set_close_on_exec (fd);
2474
unlink (uniquefile);
2475
g_free (uniquefile);
2488
open_empty_locked_file (const gchar *directory,
2489
const gchar *filename,
2494
fd = create_new_locked_file (directory, filename, NULL);
2499
/* We failed to create the file, most likely because it already
2500
* existed; try to get the lock on the existing file, and if we can
2501
* get that lock, delete it, then start over.
2503
fd = open (filename, O_RDWR, 0700);
2506
/* File has gone away? */
2509
GCONF_ERROR_LOCK_FAILED,
2510
_("Failed to create or open '%s'"),
2515
if (lock_entire_file (fd) < 0)
2519
GCONF_ERROR_LOCK_FAILED,
2520
_("Failed to lock '%s': probably another process has the lock, or your operating system has NFS file locking misconfigured, or a hard NFS client crash caused a stale lock (%s)"),
2521
filename, strerror (errno));
2526
/* We have the lock on filename, so delete it */
2531
/* Now retry creating our file */
2532
fd = create_new_locked_file (directory, filename, err);
2538
read_current_server (const gchar *iorfile,
2539
gboolean warn_if_fail)
2543
fp = fopen (iorfile, "r");
2548
gconf_log (GCL_WARNING, _("IOR file '%s' not opened successfully, no gconfd located: %s"),
2549
iorfile, g_strerror (errno));
2551
return CORBA_OBJECT_NIL;
2553
else /* successfully opened IOR file */
2555
char buf[2048] = { '\0' };
2556
const char *str = NULL;
2558
fgets (buf, sizeof (buf) - 2, fp);
2561
/* The lockfile format is <pid>:<ior> for gconfd
2562
* or <pid>:none for gconftool
2565
while (isdigit(*str))
2571
if (str[0] == 'n' &&
2577
gconf_log (GCL_WARNING,
2578
_("gconftool or other non-gconfd process has the lock file '%s'"),
2581
else /* file contains daemon IOR */
2584
CORBA_Environment ev;
2585
ConfigServer server;
2587
CORBA_exception_init (&ev);
2589
orb = gconf_orb_get ();
2594
gconf_log (GCL_WARNING,
2595
_("couldn't contact ORB to resolve existing gconfd object reference"));
2596
return CORBA_OBJECT_NIL;
2599
server = CORBA_ORB_string_to_object (orb, (char*) str, &ev);
2600
CORBA_exception_free (&ev);
2605
return CORBA_OBJECT_NIL;
2610
gconf_get_lock_or_current_holder (const gchar *lock_directory,
2611
ConfigServer *current_server,
2614
ConfigServer server;
2617
g_return_val_if_fail(lock_directory != NULL, NULL);
2620
*current_server = CORBA_OBJECT_NIL;
2622
if (mkdir (lock_directory, 0700) < 0 &&
2625
gconf_set_error (err,
2626
GCONF_ERROR_LOCK_FAILED,
2627
_("couldn't create directory `%s': %s"),
2628
lock_directory, g_strerror (errno));
2633
server = CORBA_OBJECT_NIL;
2635
lock = g_new0 (GConfLock, 1);
2637
lock->lock_directory = g_strdup (lock_directory);
2639
lock->iorfile = g_strconcat (lock->lock_directory, "/ior", NULL);
2641
/* Check the current IOR file and ping its daemon */
2643
lock->lock_fd = open_empty_locked_file (lock->lock_directory,
2647
if (lock->lock_fd < 0)
2649
/* We didn't get the lock. Read the old server, and provide
2650
* it to the caller. Error is already set.
2653
*current_server = read_current_server (lock->iorfile, TRUE);
2655
gconf_lock_destroy (lock);
2661
/* Write IOR to lockfile */
2666
s = g_strdup_printf ("%u:", (guint) getpid ());
2668
retval = write (lock->lock_fd, s, strlen (s));
2674
ior = gconf_get_daemon_ior();
2677
retval = write (lock->lock_fd, "none", 4);
2679
retval = write (lock->lock_fd, ior, strlen (ior));
2684
gconf_set_error (err,
2685
GCONF_ERROR_LOCK_FAILED,
2686
_("Can't write to file `%s': %s"),
2687
lock->iorfile, g_strerror (errno));
2689
unlink (lock->iorfile);
2690
gconf_lock_destroy (lock);
2700
gconf_get_lock (const gchar *lock_directory,
2703
return gconf_get_lock_or_current_holder (lock_directory, NULL, err);
2707
gconf_release_lock (GConfLock *lock,
2716
/* A paranoia check to avoid disaster if e.g.
2717
* some random client code opened and closed the
2718
* lockfile (maybe Nautilus checking its MIME type or
2721
if (lock->lock_fd < 0 ||
2722
file_locked_by_someone_else (lock->lock_fd))
2727
_("We didn't have the lock on file `%s', but we should have"),
2732
/* To avoid annoying .nfs3435314513453145 files on unlink, which keep us
2733
* from removing the lock directory, we don't want to hold the
2734
* lockfile open after removing all links to it. But we can't
2735
* close it then unlink, because then we would be unlinking without
2736
* holding the lock. So, we create a unique filename and link it too
2737
* the locked file, then unlink the locked file, then drop our locks
2738
* and close file descriptors, then unlink the unique filename
2741
uniquefile = unique_filename (lock->lock_directory);
2743
if (link (lock->iorfile, uniquefile) < 0)
2748
_("Failed to link '%s' to '%s': %s"),
2749
uniquefile, lock->iorfile, g_strerror (errno));
2754
/* Note that we unlink while still holding the lock to avoid races */
2755
if (unlink (lock->iorfile) < 0)
2760
_("Failed to remove lock file `%s': %s"),
2762
g_strerror (errno));
2766
/* Now drop our lock */
2767
if (lock->lock_fd >= 0)
2769
close (lock->lock_fd);
2773
/* Now remove the temporary link we used to avoid .nfs351453 garbage */
2774
if (unlink (uniquefile) < 0)
2779
_("Failed to clean up file '%s': %s"),
2780
uniquefile, g_strerror (errno));
2785
/* And finally clean up the directory - this would have failed if
2786
* we had .nfs323423423 junk
2788
if (rmdir (lock->lock_directory) < 0)
2793
_("Failed to remove lock directory `%s': %s"),
2794
lock->lock_directory,
2795
g_strerror (errno));
2803
g_free (uniquefile);
2804
gconf_lock_destroy (lock);
2808
/* This function doesn't try to see if the lock is valid or anything
2809
* of the sort; it just reads it. It does do the object_to_string
2812
gconf_get_current_lock_holder (const gchar *lock_directory)
2815
ConfigServer server;
2817
iorfile = g_strconcat (lock_directory, "/ior", NULL);
2818
server = read_current_server (iorfile, FALSE);
2823
/* Copied from OAF */
2824
#ifndef ORBIT_USES_GLIB_MAIN_LOOP
2827
orb_handle_connection (GIOChannel * source, GIOCondition cond,
2828
GIOPConnection * cnx)
2830
/* The best way to know about an fd exception is if select()/poll()
2831
* tells you about it, so we just relay that information on to ORBit
2835
if (cond & (G_IO_HUP | G_IO_NVAL | G_IO_ERR))
2836
giop_main_handle_connection_exception (cnx);
2838
giop_main_handle_connection (cnx);
2844
orb_add_connection (GIOPConnection * cnx)
2847
GIOChannel *channel;
2849
channel = g_io_channel_unix_new (GIOP_CONNECTION_GET_FD (cnx));
2850
tag = g_io_add_watch_full (channel, G_PRIORITY_LOW,
2851
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
2852
(GIOFunc) orb_handle_connection,
2854
g_io_channel_unref (channel);
2856
cnx->user_data = GUINT_TO_POINTER (tag);
2860
orb_remove_connection (GIOPConnection * cnx)
2862
g_source_remove (GPOINTER_TO_UINT (cnx->user_data));
2863
cnx->user_data = GINT_TO_POINTER (-1);
2866
#endif /* !ORBIT_USES_GLIB_MAIN_LOOP */
2869
#include <netinet/in.h>
2871
#include <arpa/inet.h>
2875
static char *hostname = NULL;
2876
char hn_tmp[65], ha_tmp[4];
2877
struct hostent *hent;
2880
gethostname (hn_tmp, sizeof (hn_tmp) - 1);
2882
hent = gethostbyname (hn_tmp);
2884
memcpy (ha_tmp, hent->h_addr, 4);
2885
hent = gethostbyaddr (ha_tmp, 4, AF_INET);
2887
hostname = g_strdup (hent->h_name);
2895
hostname = g_strdup (hn_tmp);
2902
gconf_orb_get (void)
2904
if (gconf_in_daemon_mode ())
2906
static CORBA_ORB gconf_orb = CORBA_OBJECT_NIL;
2908
if (gconf_orb == CORBA_OBJECT_NIL)
2910
CORBA_Environment ev;
2912
char *argv[] = { "gconf", NULL };
2913
CORBA_Context context;
2914
const char *hostname;
2916
#ifndef ORBIT_USES_GLIB_MAIN_LOOP
2917
IIOPAddConnectionHandler = orb_add_connection;
2918
IIOPRemoveConnectionHandler = orb_remove_connection;
2919
#endif /* !ORBIT_USES_GLIB_MAIN_LOOP */
2921
CORBA_exception_init (&ev);
2923
gconf_orb = CORBA_ORB_init (&argc, argv, "orbit-local-orb", &ev);
2924
g_assert (ev._major == CORBA_NO_EXCEPTION);
2926
/* Set values in default context */
2927
CORBA_ORB_get_default_context (gconf_orb, &context, &ev);
2928
g_assert (ev._major == CORBA_NO_EXCEPTION);
2930
hostname = get_hostname ();
2931
CORBA_Context_set_one_value (context, "hostname",
2932
(char *) hostname, &ev);
2933
CORBA_Context_set_one_value (context, "domain", "user", &ev);
2934
CORBA_Context_set_one_value (context, "username",
2935
g_get_user_name (), &ev);
2937
CORBA_exception_free (&ev);
2944
return oaf_orb_get ();
2949
gconf_get_daemon_dir (void)
2951
return g_strconcat (g_get_home_dir (), "/.gconfd", NULL);
2955
gconf_get_lock_dir (void)
2960
gconfd_dir = gconf_get_daemon_dir ();
2961
lock_dir = g_strconcat (gconfd_dir, "/lock", NULL);
2963
g_free (gconfd_dir);
2968
static void set_cloexec (gint fd);
2971
close_fd_func (gpointer data)
2978
open_max = sysconf (_SC_OPEN_MAX);
2979
for (i = 3; i < open_max; i++)
2981
/* don't close our write pipe */
2988
gconf_activate_server (gboolean start_if_not_found,
2991
ConfigServer server;
2992
int p[2] = { -1, -1 };
2998
CORBA_Environment ev;
3000
gconfd_dir = gconf_get_daemon_dir ();
3002
if (mkdir (gconfd_dir, 0700) < 0 && errno != EEXIST)
3003
gconf_log (GCL_WARNING, _("Failed to create %s: %s"),
3004
gconfd_dir, g_strerror (errno));
3006
g_free (gconfd_dir);
3008
lock_dir = gconf_get_lock_dir ();
3009
server = gconf_get_current_lock_holder (lock_dir);
3012
/* Confirm server exists */
3013
CORBA_exception_init (&ev);
3015
if (!CORBA_Object_is_nil (server, &ev))
3017
ConfigServer_ping (server, &ev);
3019
if (ev._major != CORBA_NO_EXCEPTION)
3020
server = CORBA_OBJECT_NIL;
3023
CORBA_exception_free (&ev);
3025
if (server != CORBA_OBJECT_NIL)
3028
if (start_if_not_found)
3035
GCONF_ERROR_NO_SERVER,
3036
_("Failed to create pipe for communicating with spawned gconf daemon: %s\n"),
3037
g_strerror (errno));
3041
if (gconf_file_exists (GCONF_BINDIR"/gconfd-2"))
3042
argv[0] = g_strconcat (GCONF_BINDIR, "/gconfd-2", NULL);
3044
argv[0] = g_strconcat (GCONF_BINDIR, "/" GCONFD, NULL);
3046
argv[1] = g_strdup_printf ("%d", p[1]);
3050
if (!g_spawn_async (NULL,
3053
G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
3063
GCONF_ERROR_NO_SERVER,
3064
_("Failed to launch configuration server: %s\n"),
3066
g_error_free (tmp_err);
3073
/* Block until server starts up */
3074
read (p[0], buf, 1);
3076
lock_dir = gconf_get_lock_dir ();
3077
server = gconf_get_current_lock_holder (lock_dir);
3082
if (server == CORBA_OBJECT_NIL &&
3087
GCONF_ERROR_NO_SERVER,
3088
_("Failed to contact configuration server (a likely cause of this is that you have an existing configuration server (gconfd) running, but it isn't reachable from here - if you're logged in from two machines at once, you may need to enable TCP networking for ORBit)\n"));
3096
/* g_spawn cut-and-paste, changed to make all symbols static */
3098
/* gspawn.h - Process launching
3100
* Copyright 2000 Red Hat, Inc.
3102
* GLib is free software; you can redistribute it and/or
3103
* modify it under the terms of the GNU Lesser General Public License as
3104
* published by the Free Software Foundation; either version 2 of the
3105
* License, or (at your option) any later version.
3107
* GLib is distributed in the hope that it will be useful,
3108
* but WITHOUT ANY WARRANTY; without even the implied warranty of
3109
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3110
* Lesser General Public License for more details.
3112
* You should have received a copy of the GNU Lesser General Public
3113
* License along with GLib; see the file COPYING.LIB. If not, write
3114
* to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3115
* Boston, MA 02111-1307, USA.
3118
#ifndef __G_SPAWN_H__
3119
#define __G_SPAWN_H__
3121
/* I'm not sure I remember our proposed naming convention here. */
3122
#define G_SPAWN_ERROR g_spawn_error_quark ()
3126
G_SPAWN_ERROR_FORK, /* fork failed due to lack of memory */
3127
G_SPAWN_ERROR_READ, /* read or select on pipes failed */
3128
G_SPAWN_ERROR_CHDIR, /* changing to working dir failed */
3129
G_SPAWN_ERROR_ACCES, /* execv() returned EACCES */
3130
G_SPAWN_ERROR_PERM, /* execv() returned EPERM */
3131
G_SPAWN_ERROR_2BIG, /* execv() returned E2BIG */
3132
G_SPAWN_ERROR_NOEXEC, /* execv() returned ENOEXEC */
3133
G_SPAWN_ERROR_NAMETOOLONG, /* "" "" ENAMETOOLONG */
3134
G_SPAWN_ERROR_NOENT, /* "" "" ENOENT */
3135
G_SPAWN_ERROR_NOMEM, /* "" "" ENOMEM */
3136
G_SPAWN_ERROR_NOTDIR, /* "" "" ENOTDIR */
3137
G_SPAWN_ERROR_LOOP, /* "" "" ELOOP */
3138
G_SPAWN_ERROR_TXTBUSY, /* "" "" ETXTBUSY */
3139
G_SPAWN_ERROR_IO, /* "" "" EIO */
3140
G_SPAWN_ERROR_NFILE, /* "" "" ENFILE */
3141
G_SPAWN_ERROR_MFILE, /* "" "" EMFLE */
3142
G_SPAWN_ERROR_INVAL, /* "" "" EINVAL */
3143
G_SPAWN_ERROR_ISDIR, /* "" "" EISDIR */
3144
G_SPAWN_ERROR_LIBBAD, /* "" "" ELIBBAD */
3145
G_SPAWN_ERROR_FAILED /* other fatal failure, error->message
3150
static GQuark g_spawn_error_quark (void);
3152
static gboolean g_spawn_async (const gchar *working_directory,
3156
GSpawnChildSetupFunc child_setup,
3162
/* Opens pipes for non-NULL standard_output, standard_input, standard_error,
3163
* and returns the parent's end of the pipes.
3165
static gboolean g_spawn_async_with_pipes (const gchar *working_directory,
3169
GSpawnChildSetupFunc child_setup,
3172
gint *standard_input,
3173
gint *standard_output,
3174
gint *standard_error,
3178
#endif /* __G_SPAWN_H__ */
3183
/* gspawn.c - Process launching
3185
* Copyright 2000 Red Hat, Inc.
3186
* g_execvpe implementation based on GNU libc execvp:
3187
* Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
3189
* GLib is free software; you can redistribute it and/or
3190
* modify it under the terms of the GNU Lesser General Public License as
3191
* published by the Free Software Foundation; either version 2 of the
3192
* License, or (at your option) any later version.
3194
* GLib is distributed in the hope that it will be useful,
3195
* but WITHOUT ANY WARRANTY; without even the implied warranty of
3196
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3197
* Lesser General Public License for more details.
3199
* You should have received a copy of the GNU Lesser General Public
3200
* License along with GLib; see the file COPYING.LIB. If not, write
3201
* to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3202
* Boston, MA 02111-1307, USA.
3206
#include <sys/time.h>
3207
#include <sys/types.h>
3208
#include <sys/wait.h>
3215
#ifdef HAVE_SYS_SELECT_H
3216
#include <sys/select.h>
3217
#endif /* HAVE_SYS_SELECT_H */
3219
static gint g_execute (const gchar *file,
3222
gboolean search_path);
3224
static gboolean make_pipe (gint p[2],
3226
static gboolean fork_exec_with_pipes (gboolean intermediate_child,
3227
const gchar *working_directory,
3230
gboolean close_descriptors,
3231
gboolean search_path,
3232
gboolean stdout_to_null,
3233
gboolean stderr_to_null,
3234
gboolean child_inherits_stdin,
3235
gboolean file_and_argv_zero,
3236
GSpawnChildSetupFunc child_setup,
3239
gint *standard_input,
3240
gint *standard_output,
3241
gint *standard_error,
3245
g_spawn_error_quark (void)
3247
static GQuark quark = 0;
3249
quark = g_quark_from_static_string ("g-exec-error-quark");
3255
* @working_directory: child's current working directory, or NULL to inherit parent's
3256
* @argv: child's argument vector
3257
* @envp: child's environment, or NULL to inherit parent's
3258
* @flags: flags from #GSpawnFlags
3259
* @child_setup: function to run in the child just before exec()
3260
* @user_data: user data for @child_setup
3261
* @child_pid: return location for child process ID, or NULL
3262
* @error: return location for error
3264
* See g_spawn_async_with_pipes() for a full description; this function
3265
* simply calls the g_spawn_async_with_pipes() without any pipes.
3267
* Return value: TRUE on success, FALSE if error is set
3270
g_spawn_async (const gchar *working_directory,
3274
GSpawnChildSetupFunc child_setup,
3279
g_return_val_if_fail (argv != NULL, FALSE);
3281
return g_spawn_async_with_pipes (working_directory,
3291
/* Avoids a danger in threaded situations (calling close()
3292
* on a file descriptor twice, and another thread has
3293
* re-opened it since the first close)
3296
close_and_invalidate (gint *fd)
3308
READ_FAILED = 0, /* FALSE */
3314
* g_spawn_async_with_pipes:
3315
* @working_directory: child's current working directory, or NULL to inherit parent's
3316
* @argv: child's argument vector
3317
* @envp: child's environment, or NULL to inherit parent's
3318
* @flags: flags from #GSpawnFlags
3319
* @child_setup: function to run in the child just before exec()
3320
* @user_data: user data for @child_setup
3321
* @child_pid: return location for child process ID, or NULL
3322
* @standard_input: return location for file descriptor to write to child's stdin, or NULL
3323
* @standard_output: return location for file descriptor to read child's stdout, or NULL
3324
* @standard_error: return location for file descriptor to read child's stderr, or NULL
3325
* @error: return location for error
3327
* Executes a child program asynchronously (your program will not
3328
* block waiting for the child to exit). The child program is
3329
* specified by the only argument that must be provided, @argv. @argv
3330
* should be a NULL-terminated array of strings, to be passed as the
3331
* argument vector for the child. The first string in @argv is of
3332
* course the name of the program to execute. By default, the name of
3333
* the program must be a full path; the PATH shell variable will only
3334
* be searched if you pass the %G_SPAWN_SEARCH_PATH flag.
3336
* @envp is a NULL-terminated array of strings, where each string
3337
* has the form <literal>KEY=VALUE</literal>. This will become
3338
* the child's environment. If @envp is NULL, the child inherits its
3339
* parent's environment.
3341
* @flags should be the bitwise OR of any flags you want to affect the
3342
* function's behavior. The %G_SPAWN_DO_NOT_REAP_CHILD means that the
3343
* child will not be automatically reaped; you must call waitpid() or
3344
* handle SIGCHLD yourself, or the child will become a zombie.
3345
* %G_SPAWN_LEAVE_DESCRIPTORS_OPEN means that the parent's open file
3346
* descriptors will be inherited by the child; otherwise all
3347
* descriptors except stdin/stdout/stderr will be closed before
3348
* calling exec() in the child. %G_SPAWN_SEARCH_PATH means that
3349
* <literal>argv[0]</literal> need not be an absolute path, it
3350
* will be looked for in the user's PATH. %G_SPAWN_STDOUT_TO_DEV_NULL
3351
* means that the child's standad output will be discarded, instead
3352
* of going to the same location as the parent's standard output.
3353
* %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error
3354
* will be discarded. %G_SPAWN_CHILD_INHERITS_STDIN means that
3355
* the child will inherit the parent's standard input (by default,
3356
* the child's standard input is attached to /dev/null).
3357
* %G_SPAWN_FILE_AND_ARGV_ZERO means that the first element of @argv is
3358
* the file to execute, while the remaining elements are the
3359
* actual argument vector to pass to the file. Normally
3360
* g_spawn_async_with_pipes() uses @argv[0] as the file to execute, and
3361
* passes all of @argv to the child.
3363
* @child_setup and @user_data are a function and user data to be
3364
* called in the child after GLib has performed all the setup it plans
3365
* to perform (including creating pipes, closing file descriptors,
3366
* etc.) but before calling exec(). That is, @child_setup is called
3367
* just before calling exec() in the child. Obviously actions taken in
3368
* this function will only affect the child, not the parent.
3370
* If non-NULL, @child_pid will be filled with the child's process
3371
* ID. You can use the process ID to send signals to the child, or
3372
* to waitpid() if you specified the %G_SPAWN_DO_NOT_REAP_CHILD flag.
3374
* If non-NULL, the @standard_input, @standard_output, @standard_error
3375
* locations will be filled with file descriptors for writing to the child's
3376
* standard input or reading from its standard output or standard error.
3377
* The caller of g_spawn_async_with_pipes() must close these file descriptors
3378
* when they are no longer in use. If these parameters are NULL, the
3379
* corresponding pipe won't be created.
3381
* @error can be NULL to ignore errors, or non-NULL to report errors.
3382
* If an error is set, the function returns FALSE. Errors
3383
* are reported even if they occur in the child (for example if the
3384
* executable in <literal>argv[0]</literal> is not found). Typically
3385
* the <literal>message</literal> field of returned errors should be displayed
3386
* to users. Possible errors are those from the #G_SPAWN_ERROR domain.
3388
* If an error occurs, @child_pid, @standard_input, @standard_output,
3389
* and @standard_error will not be filled with valid values.
3391
* Return value: TRUE on success, FALSE if an error was set
3394
g_spawn_async_with_pipes (const gchar *working_directory,
3398
GSpawnChildSetupFunc child_setup,
3401
gint *standard_input,
3402
gint *standard_output,
3403
gint *standard_error,
3406
g_return_val_if_fail (argv != NULL, FALSE);
3407
g_return_val_if_fail (standard_output == NULL ||
3408
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
3409
g_return_val_if_fail (standard_error == NULL ||
3410
!(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
3411
/* can't inherit stdin if we have an input pipe. */
3412
g_return_val_if_fail (standard_input == NULL ||
3413
!(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
3415
return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD),
3419
!(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
3420
(flags & G_SPAWN_SEARCH_PATH) != 0,
3421
(flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
3422
(flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
3423
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
3424
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
3435
exec_err_to_g_error (gint en)
3441
return G_SPAWN_ERROR_ACCES;
3447
return G_SPAWN_ERROR_PERM;
3453
return G_SPAWN_ERROR_2BIG;
3459
return G_SPAWN_ERROR_NOEXEC;
3465
return G_SPAWN_ERROR_NAMETOOLONG;
3471
return G_SPAWN_ERROR_NOENT;
3477
return G_SPAWN_ERROR_NOMEM;
3483
return G_SPAWN_ERROR_NOTDIR;
3489
return G_SPAWN_ERROR_LOOP;
3495
return G_SPAWN_ERROR_TXTBUSY;
3501
return G_SPAWN_ERROR_IO;
3507
return G_SPAWN_ERROR_NFILE;
3513
return G_SPAWN_ERROR_MFILE;
3519
return G_SPAWN_ERROR_INVAL;
3525
return G_SPAWN_ERROR_ISDIR;
3531
return G_SPAWN_ERROR_LIBBAD;
3536
return G_SPAWN_ERROR_FAILED;
3542
write_err_and_exit (gint fd, gint msg)
3546
write (fd, &msg, sizeof(msg));
3547
write (fd, &en, sizeof(en));
3553
set_cloexec (gint fd)
3555
fcntl (fd, F_SETFD, FD_CLOEXEC);
3559
sane_dup2 (gint fd1, gint fd2)
3564
ret = dup2 (fd1, fd2);
3565
if (ret < 0 && errno == EINTR)
3580
do_exec (gint child_err_report_fd,
3584
const gchar *working_directory,
3587
gboolean close_descriptors,
3588
gboolean search_path,
3589
gboolean stdout_to_null,
3590
gboolean stderr_to_null,
3591
gboolean child_inherits_stdin,
3592
gboolean file_and_argv_zero,
3593
GSpawnChildSetupFunc child_setup,
3596
if (working_directory && chdir (working_directory) < 0)
3597
write_err_and_exit (child_err_report_fd,
3598
CHILD_CHDIR_FAILED);
3600
/* Close all file descriptors but stdin stdout and stderr as
3601
* soon as we exec. Note that this includes
3602
* child_err_report_fd, which keeps the parent from blocking
3603
* forever on the other end of that pipe.
3605
if (close_descriptors)
3610
open_max = sysconf (_SC_OPEN_MAX);
3611
for (i = 3; i < open_max; i++)
3616
/* We need to do child_err_report_fd anyway */
3617
set_cloexec (child_err_report_fd);
3620
/* Redirect pipes as required */
3624
/* dup2 can't actually fail here I don't think */
3626
if (sane_dup2 (stdin_fd, 0) < 0)
3627
write_err_and_exit (child_err_report_fd,
3630
/* ignore this if it doesn't work */
3631
close_and_invalidate (&stdin_fd);
3633
else if (!child_inherits_stdin)
3635
/* Keep process from blocking on a read of stdin */
3636
gint read_null = open ("/dev/null", O_RDONLY);
3637
sane_dup2 (read_null, 0);
3638
close_and_invalidate (&read_null);
3643
/* dup2 can't actually fail here I don't think */
3645
if (sane_dup2 (stdout_fd, 1) < 0)
3646
write_err_and_exit (child_err_report_fd,
3649
/* ignore this if it doesn't work */
3650
close_and_invalidate (&stdout_fd);
3652
else if (stdout_to_null)
3654
gint write_null = open ("/dev/null", O_WRONLY);
3655
sane_dup2 (write_null, 1);
3656
close_and_invalidate (&write_null);
3661
/* dup2 can't actually fail here I don't think */
3663
if (sane_dup2 (stderr_fd, 2) < 0)
3664
write_err_and_exit (child_err_report_fd,
3667
/* ignore this if it doesn't work */
3668
close_and_invalidate (&stderr_fd);
3670
else if (stderr_to_null)
3672
gint write_null = open ("/dev/null", O_WRONLY);
3673
sane_dup2 (write_null, 2);
3674
close_and_invalidate (&write_null);
3677
/* Call user function just before we exec */
3680
(* child_setup) (user_data);
3684
file_and_argv_zero ? argv + 1 : argv,
3688
write_err_and_exit (child_err_report_fd,
3705
if (bytes >= sizeof(gint)*2)
3706
break; /* give up, who knows what happened, should not be
3712
((gchar*)buf) + bytes,
3713
sizeof(gint) * n_ints_in_buf - bytes);
3714
if (chunk < 0 && errno == EINTR)
3719
/* Some weird shit happened, bail out */
3723
G_SPAWN_ERROR_FAILED,
3724
_("Failed to read from child pipe (%s)"),
3725
g_strerror (errno));
3729
else if (chunk == 0)
3731
else /* chunk > 0 */
3735
*n_ints_read = (gint)(bytes / sizeof(gint));
3741
fork_exec_with_pipes (gboolean intermediate_child,
3742
const gchar *working_directory,
3745
gboolean close_descriptors,
3746
gboolean search_path,
3747
gboolean stdout_to_null,
3748
gboolean stderr_to_null,
3749
gboolean child_inherits_stdin,
3750
gboolean file_and_argv_zero,
3751
GSpawnChildSetupFunc child_setup,
3754
gint *standard_input,
3755
gint *standard_output,
3756
gint *standard_error,
3760
gint stdin_pipe[2] = { -1, -1 };
3761
gint stdout_pipe[2] = { -1, -1 };
3762
gint stderr_pipe[2] = { -1, -1 };
3763
gint child_err_report_pipe[2] = { -1, -1 };
3764
gint child_pid_report_pipe[2] = { -1, -1 };
3767
if (!make_pipe (child_err_report_pipe, error))
3770
if (intermediate_child && !make_pipe (child_pid_report_pipe, error))
3771
goto cleanup_and_fail;
3773
if (standard_input && !make_pipe (stdin_pipe, error))
3774
goto cleanup_and_fail;
3776
if (standard_output && !make_pipe (stdout_pipe, error))
3777
goto cleanup_and_fail;
3779
if (standard_error && !make_pipe (stderr_pipe, error))
3780
goto cleanup_and_fail;
3789
_("Failed to fork (%s)"),
3790
g_strerror (errno));
3792
goto cleanup_and_fail;
3796
/* Immediate child. This may or may not be the child that
3797
* actually execs the new process.
3800
/* Be sure we crash if the parent exits
3801
* and we write to the err_report_pipe
3803
signal (SIGPIPE, SIG_DFL);
3805
/* Close the parent's end of the pipes;
3806
* not needed in the close_descriptors case,
3809
close_and_invalidate (&child_err_report_pipe[0]);
3810
close_and_invalidate (&child_pid_report_pipe[0]);
3811
close_and_invalidate (&stdin_pipe[1]);
3812
close_and_invalidate (&stdout_pipe[0]);
3813
close_and_invalidate (&stderr_pipe[0]);
3815
if (intermediate_child)
3817
/* We need to fork an intermediate child that launches the
3818
* final child. The purpose of the intermediate child
3819
* is to exit, so we can waitpid() it immediately.
3820
* Then the grandchild will not become a zombie.
3822
gint grandchild_pid;
3824
grandchild_pid = fork ();
3826
if (grandchild_pid < 0)
3828
/* report -1 as child PID */
3829
write (child_pid_report_pipe[1], &grandchild_pid,
3830
sizeof(grandchild_pid));
3832
write_err_and_exit (child_err_report_pipe[1],
3835
else if (grandchild_pid == 0)
3837
do_exec (child_err_report_pipe[1],
3848
child_inherits_stdin,
3855
write (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid));
3856
close_and_invalidate (&child_pid_report_pipe[1]);
3863
/* Just run the child.
3866
do_exec (child_err_report_pipe[1],
3877
child_inherits_stdin,
3890
/* Close the uncared-about ends of the pipes */
3891
close_and_invalidate (&child_err_report_pipe[1]);
3892
close_and_invalidate (&child_pid_report_pipe[1]);
3893
close_and_invalidate (&stdin_pipe[0]);
3894
close_and_invalidate (&stdout_pipe[1]);
3895
close_and_invalidate (&stderr_pipe[1]);
3897
/* If we had an intermediate child, reap it */
3898
if (intermediate_child)
3901
if (waitpid (pid, &status, 0) < 0)
3905
else if (errno == ECHILD)
3906
; /* do nothing, child already reaped */
3908
g_warning ("waitpid() should not fail in "
3909
"'fork_exec_with_pipes'");
3914
if (!read_ints (child_err_report_pipe[0],
3917
goto cleanup_and_fail;
3921
/* Error from the child. */
3925
case CHILD_CHDIR_FAILED:
3928
G_SPAWN_ERROR_CHDIR,
3929
_("Failed to change to directory '%s' (%s)"),
3931
g_strerror (buf[1]));
3935
case CHILD_EXEC_FAILED:
3938
exec_err_to_g_error (buf[1]),
3939
_("Failed to execute child process (%s)"),
3940
g_strerror (buf[1]));
3944
case CHILD_DUP2_FAILED:
3947
G_SPAWN_ERROR_FAILED,
3948
_("Failed to redirect output or input of child process (%s)"),
3949
g_strerror (buf[1]));
3953
case CHILD_FORK_FAILED:
3957
_("Failed to fork child process (%s)"),
3958
g_strerror (buf[1]));
3964
G_SPAWN_ERROR_FAILED,
3965
_("Unknown error executing child process"));
3969
goto cleanup_and_fail;
3972
/* Get child pid from intermediate child pipe. */
3973
if (intermediate_child)
3977
if (!read_ints (child_pid_report_pipe[0],
3978
buf, 1, &n_ints, error))
3979
goto cleanup_and_fail;
3985
G_SPAWN_ERROR_FAILED,
3986
_("Failed to read enough data from child pid pipe (%s)"),
3987
g_strerror (errno));
3988
goto cleanup_and_fail;
3992
/* we have the child pid */
3997
/* Success against all odds! return the information */
4003
*standard_input = stdin_pipe[1];
4004
if (standard_output)
4005
*standard_output = stdout_pipe[0];
4007
*standard_error = stderr_pipe[0];
4013
close_and_invalidate (&child_err_report_pipe[0]);
4014
close_and_invalidate (&child_err_report_pipe[1]);
4015
close_and_invalidate (&child_pid_report_pipe[0]);
4016
close_and_invalidate (&child_pid_report_pipe[1]);
4017
close_and_invalidate (&stdin_pipe[0]);
4018
close_and_invalidate (&stdin_pipe[1]);
4019
close_and_invalidate (&stdout_pipe[0]);
4020
close_and_invalidate (&stdout_pipe[1]);
4021
close_and_invalidate (&stderr_pipe[0]);
4022
close_and_invalidate (&stderr_pipe[1]);
4028
make_pipe (gint p[2],
4035
G_SPAWN_ERROR_FAILED,
4036
_("Failed to create pipe for communicating with child process (%s)"),
4037
g_strerror (errno));
4044
/* Based on execvp from GNU C Library */
4047
script_execute (const gchar *file,
4050
gboolean search_path)
4052
/* Count the arguments. */
4057
/* Construct an argument list for the shell. */
4061
new_argv = g_new0 (gchar*, argc + 1);
4063
new_argv[0] = (char *) "/bin/sh";
4064
new_argv[1] = (char *) file;
4067
new_argv[argc] = argv[argc - 1];
4071
/* Execute the shell. */
4073
execve (new_argv[0], new_argv, envp);
4075
execv (new_argv[0], new_argv);
4082
my_strchrnul (const gchar *str, gchar c)
4084
gchar *p = (gchar*) str;
4085
while (*p && (*p != c))
4092
g_execute (const gchar *file,
4095
gboolean search_path)
4099
/* We check the simple case first. */
4104
if (!search_path || strchr (file, '/') != NULL)
4106
/* Don't search when it contains a slash. */
4108
execve (file, argv, envp);
4112
if (errno == ENOEXEC)
4113
script_execute (file, argv, envp, FALSE);
4117
gboolean got_eacces = 0;
4118
const gchar *path, *p;
4119
gchar *name, *freeme;
4123
path = g_getenv ("PATH");
4126
/* There is no `PATH' in the environment. The default
4127
* search path in libc is the current directory followed by
4128
* the path `confstr' returns for `_CS_PATH'.
4131
/* In GLib we put . last, for security, and don't use the
4132
* unportable confstr(); UNIX98 does not actually specify
4133
* what to search if PATH is unset. POSIX may, dunno.
4136
path = "/bin:/usr/bin:.";
4139
len = strlen (file) + 1;
4140
pathlen = strlen (path);
4141
freeme = name = g_malloc (pathlen + len + 1);
4143
/* Copy the file name at the top, including '\0' */
4144
memcpy (name + pathlen + 1, file, len);
4145
name = name + pathlen;
4146
/* And add the slash before the filename */
4155
p = my_strchrnul (path, ':');
4158
/* Two adjacent colons, or a colon at the beginning or the end
4159
* of `PATH' means to search the current directory.
4163
startp = memcpy (name - (p - path), path, p - path);
4165
/* Try to execute this name. If it works, execv will not return. */
4167
execve (startp, argv, envp);
4169
execv (startp, argv);
4171
if (errno == ENOEXEC)
4172
script_execute (startp, argv, envp, search_path);
4177
/* Record the we got a `Permission denied' error. If we end
4178
* up finding no executable we can use, we want to diagnose
4179
* that we did find one but were denied access.
4192
/* Those errors indicate the file is missing or not executable
4193
* by us, in which case we want to just try the next path
4199
/* Some other error means we found an executable file, but
4200
* something went wrong executing it; return the error to our
4207
while (*p++ != '\0');
4209
/* We tried every element and none of them worked. */
4211
/* At least one failure was due to permissions, so report that
4219
/* Return the error from the last attempt (probably ENOENT). */
4225
#define UTF8_COMPUTE(Char, Mask, Len) \
4231
else if ((Char & 0xe0) == 0xc0) \
4236
else if ((Char & 0xf0) == 0xe0) \
4241
else if ((Char & 0xf8) == 0xf0) \
4246
else if ((Char & 0xfc) == 0xf8) \
4251
else if ((Char & 0xfe) == 0xfc) \
4259
#define UTF8_LENGTH(Char) \
4260
((Char) < 0x80 ? 1 : \
4261
((Char) < 0x800 ? 2 : \
4262
((Char) < 0x10000 ? 3 : \
4263
((Char) < 0x200000 ? 4 : \
4264
((Char) < 0x4000000 ? 5 : 6)))))
4267
#define UTF8_GET(Result, Chars, Count, Mask, Len) \
4268
(Result) = (Chars)[0] & (Mask); \
4269
for ((Count) = 1; (Count) < (Len); ++(Count)) \
4271
if (((Chars)[(Count)] & 0xc0) != 0x80) \
4277
(Result) |= ((Chars)[(Count)] & 0x3f); \
4280
#define UNICODE_VALID(Char) \
4281
((Char) < 0x110000 && \
4282
((Char) < 0xD800 || (Char) >= 0xE000) && \
4283
(Char) != 0xFFFE && (Char) != 0xFFFF)
4286
static const gchar utf8_skip_data[256] = {
4287
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4288
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4289
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4290
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4291
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4292
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4293
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
4294
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0
4297
static const gchar * const gconf_g_utf8_skip = utf8_skip_data;
4299
typedef guint32 gunichar;
4302
gconf_g_utf8_validate (const gchar *str,
4309
g_return_val_if_fail (str != NULL, FALSE);
4316
while ((max_len < 0 || (p - str) < max_len) && *p)
4318
int i, mask = 0, len;
4320
unsigned char c = (unsigned char) *p;
4322
UTF8_COMPUTE (c, mask, len);
4327
/* check that the expected number of bytes exists in str */
4329
((max_len - (p - str)) < len))
4332
UTF8_GET (result, p, i, mask, len);
4334
if (UTF8_LENGTH (result) != len) /* Check for overlong UTF-8 */
4337
if (result == (gunichar)-1)
4340
if (!UNICODE_VALID (result))
4349
/* See that we covered the entire length if a length was
4350
* passed in, or that we ended on a nul if not
4353
p != (str + max_len))
4355
else if (max_len < 0 &&