140
142
#ifdef HAVE_SIGNAL_H
141
143
static void sighandler(int sig);
144
* Reap all our dead children. Sometimes libpurple forks off a separate
145
* process to do some stuff. When that process exits we are
146
* informed about it so that we can call waitpid() and let it
147
* stop being a zombie.
149
* We used to do this immediately when our signal handler was
150
* called, but because of GStreamer we now wait one second before
151
* reaping anything. Why? For some reason GStreamer fork()s
152
* during their initialization process. I don't understand why...
153
* but they do it, and there's nothing we can do about it.
155
* Anyway, so then GStreamer waits for its child to die and then
156
* it continues with the initialization process. This means that
157
* we have a race condition where GStreamer is waitpid()ing for its
158
* child to die and we're catching the SIGCHLD signal. If GStreamer
159
* is awarded the zombied process then everything is ok. But if libpurple
160
* reaps the zombie process then the GStreamer initialization sequence
163
* So the ugly solution is to wait a second to give GStreamer time to
166
* GStreamer 0.10.10 and newer have a gst_register_fork_set_enabled()
167
* function that can be called by applications to disable forking
168
* during initialization. But it's not in 0.10.0, so we shouldn't
171
* All of this child process reaping stuff is currently only used for
172
* processes that were forked to play sounds. It's not needed for
173
* forked DNS child, which have their own waitpid() call. It might
174
* be wise to move this code into gtksound.c.
146
* This child process reaping stuff is currently only used for processes that
147
* were forked to play sounds. It's not needed for forked DNS child, which
148
* have their own waitpid() call. It might be wise to move this code into
188
163
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
192
/* Restore signal catching */
193
signal(SIGALRM, sighandler);
196
168
char *segfault_message;
219
191
fprintf(stderr, "%s", segfault_message);
194
#if defined(USE_GSTREAMER) && !defined(GST_CAN_DISABLE_FORKING)
195
/* By default, gstreamer forks when you initialize it, and waitpids for the
196
* child. But if libpurple reaps the child rather than leaving it to
197
* gstreamer, gstreamer's initialization fails. So, we wait a second before
198
* reaping child processes, to give gst a chance to reap it if it wants to.
200
* This is not needed in later gstreamers, which let us disable the forking.
201
* And, it breaks the world on some Real Unices.
223
204
/* Restore signal catching */
224
205
signal(SIGCHLD, sighandler);
213
/* Restore signal catching */
214
signal(SIGCHLD, sighandler);
231
217
purple_debug_warning("sighandler", "Caught signal %d\n", sig);
275
261
icons = g_list_append(icons,icon);
277
263
purple_debug_error("ui_main",
278
"Failed to load the default window icon (%spx version)!\n", icon_sizes[i]);
264
"Failed to load the default window icon (%spx version)!\n", icon_sizes[i].dir);
281
267
if(NULL == icons) {
406
392
" -h, --help display this help and exit\n"
407
393
" -m, --multiple do not ensure single instance\n"
408
394
" -n, --nologin don't automatically login\n"
409
" -l, --login[=NAME] automatically login (optional argument NAME specifies\n"
410
" account(s) to use, separated by commas)\n"
395
" -l, --login[=NAME] enable specified account(s) (optional argument NAME\n"
396
" specifies account(s) to use, separated by commas.\n"
397
" Without this only the first account will be enabled).\n"
411
398
" --display=DISPLAY X display to use\n"
412
399
" -v, --version display the current version and exit\n"), PIDGIN_NAME, DISPLAY_VERSION, name);
418
405
" -h, --help display this help and exit\n"
419
406
" -m, --multiple do not ensure single instance\n"
420
407
" -n, --nologin don't automatically login\n"
421
" -l, --login[=NAME] automatically login (optional argument NAME specifies\n"
422
" account(s) to use, separated by commas)\n"
408
" -l, --login[=NAME] enable specified account(s) (optional argument NAME\n"
409
" specifies account(s) to use, separated by commas.\n"
410
" Without this only the first account will be enabled).\n"
423
411
" -v, --version display the current version and exit\n"), PIDGIN_NAME, DISPLAY_VERSION, name);
476
464
gboolean opt_help = FALSE;
477
465
gboolean opt_login = FALSE;
478
466
gboolean opt_nologin = FALSE;
467
gboolean opt_nocrash = FALSE;
479
468
gboolean opt_version = FALSE;
480
469
gboolean opt_si = TRUE; /* Check for single instance? */
481
470
char *opt_config_dir_arg = NULL;
506
495
{"login", optional_argument, NULL, 'l'},
507
496
{"multiple", no_argument, NULL, 'm'},
508
497
{"nologin", no_argument, NULL, 'n'},
498
{"nocrash", no_argument, NULL, 'x'},
509
499
{"session", required_argument, NULL, 's'},
510
500
{"version", no_argument, NULL, 'v'},
511
501
{"display", required_argument, NULL, 'D'},