Print this page
3792 hald.c:371: error: 'g_type_init' is deprecated
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Jon Tibble <meths@btinternet.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/hal/hald/hald.c
+++ new/usr/src/cmd/hal/hald/hald.c
1 1 /***************************************************************************
2 2 * CVSID: $Id$
3 3 *
4 4 * hald.c : main startup for HAL daemon
5 5 *
6 6 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7 7 * Copyright (C) 2005 Danny Kukawka, <danny.kukawka@web.de>
8 8 *
9 9 * Licensed under the Academic Free License version 2.1
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify
12 12 * it under the terms of the GNU General Public License as published by
13 13 * the Free Software Foundation; either version 2 of the License, or
14 14 * (at your option) any later version.
15 15 *
16 16 * This program is distributed in the hope that it will be useful,
17 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 19 * GNU General Public License for more details.
20 20 *
21 21 * You should have received a copy of the GNU General Public License
22 22 * along with this program; if not, write to the Free Software
23 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 24 *
25 25 **************************************************************************/
26 26
27 27 #ifdef HAVE_CONFIG_H
28 28 # include <config.h>
29 29 #endif
30 30
31 31 #include <stdio.h>
32 32 #include <stdlib.h>
33 33 #include <string.h>
34 34 #include <unistd.h>
35 35 #include <getopt.h>
36 36 #include <pwd.h>
37 37 #include <stdint.h>
38 38 #include <sys/stat.h>
39 39 #include <fcntl.h>
40 40 #include <errno.h>
41 41 #include <signal.h>
42 42 #include <grp.h>
43 43 #include <syslog.h>
44 44
45 45 #include <dbus/dbus.h>
46 46 #include <dbus/dbus-glib.h>
47 47 #include <dbus/dbus-glib-lowlevel.h>
48 48
49 49 /*#include "master_slave.h"*/
50 50
51 51 #include "logger.h"
52 52 #include "hald.h"
53 53 #include "device_store.h"
54 54 #include "device_info.h"
55 55 #include "osspec.h"
56 56 #include "hald_dbus.h"
57 57 #include "util.h"
58 58 #include "hald_runner.h"
59 59 #include "util_helper.h"
60 60
61 61 static void delete_pid(void)
62 62 {
63 63 unlink(HALD_PID_FILE);
64 64 }
65 65
66 66 /**
67 67 * @defgroup HalDaemon HAL daemon
68 68 * @brief The HAL daemon manages persistent device objects available through
69 69 * a D-BUS network API
70 70 */
71 71
72 72 static HalDeviceStore *global_device_list = NULL;
73 73
74 74 static HalDeviceStore *temporary_device_list = NULL;
75 75
76 76
77 77 static void
78 78 addon_terminated (HalDevice *device, guint32 exit_type,
79 79 gint return_code, gchar **error,
80 80 gpointer data1, gpointer data2)
81 81 {
82 82 HAL_INFO (("in addon_terminated for udi=%s", device->udi));
83 83
84 84 /* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
85 85
86 86 /* however, the world can stop, mark this addon as ready
87 87 * (TODO: potential bug if the addon crashed after calling libhal_device_addon_is_ready())
88 88 */
89 89 if (hal_device_inc_num_ready_addons (device)) {
90 90 if (hal_device_are_all_addons_ready (device)) {
91 91 manager_send_signal_device_added (device);
92 92 }
93 93 }
94 94 }
95 95
96 96
97 97
98 98
99 99 static void
100 100 gdl_store_changed (HalDeviceStore *store, HalDevice *device,
101 101 gboolean is_added, gpointer user_data)
102 102 {
103 103 if (is_added) {
104 104 GSList *addons;
105 105
106 106 HAL_INFO (("Added device to GDL; udi=%s", hal_device_get_udi(device)));
107 107
108 108 if ((addons = hal_device_property_get_strlist (device, "info.addons")) != NULL) {
109 109 GSList *i;
110 110
111 111 for (i = addons; i != NULL; i = g_slist_next (i)) {
112 112 const gchar *command_line;
113 113 gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
114 114
115 115 command_line = (const gchar *) i->data;
116 116 if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
117 117 HAL_INFO (("Started addon %s for udi %s",
118 118 command_line, hal_device_get_udi(device)));
119 119 hal_device_inc_num_addons (device);
120 120 } else {
121 121 HAL_ERROR (("Cannot start addon %s for udi %s",
122 122 command_line, hal_device_get_udi(device)));
123 123 }
124 124 }
125 125 }
126 126 } else {
127 127 HAL_INFO (("Removed device from GDL; udi=%s", hal_device_get_udi(device)));
128 128 hald_runner_kill_device(device);
129 129 }
130 130
131 131 /*hal_device_print (device);*/
132 132
133 133 if (is_added) {
134 134 if (hal_device_are_all_addons_ready (device)) {
135 135 manager_send_signal_device_added (device);
136 136 }
137 137 } else {
138 138 if (hal_device_are_all_addons_ready (device)) {
139 139 manager_send_signal_device_removed (device);
140 140 }
141 141 }
142 142 }
143 143
144 144 static void
145 145 gdl_property_changed (HalDeviceStore *store, HalDevice *device,
146 146 const char *key, gboolean added, gboolean removed,
147 147 gpointer user_data)
148 148 {
149 149 if (hal_device_are_all_addons_ready (device)) {
150 150 device_send_signal_property_modified (device, key, removed, added);
151 151 }
152 152
153 153 /* only execute the callouts if the property _changed_ */
154 154 if (added == FALSE && removed == FALSE)
155 155 /*hal_callout_property (device, key)*/;
156 156 }
157 157
158 158 static void
159 159 gdl_capability_added (HalDeviceStore *store, HalDevice *device,
160 160 const char *capability, gpointer user_data)
161 161 {
162 162 if (hal_device_are_all_addons_ready (device)) {
163 163 manager_send_signal_new_capability (device, capability);
164 164 }
165 165 /*hal_callout_capability (device, capability, TRUE)*/;
166 166 }
167 167
168 168 HalDeviceStore *
169 169 hald_get_gdl (void)
170 170 {
171 171 if (global_device_list == NULL) {
172 172 global_device_list = hal_device_store_new ();
173 173
174 174 g_signal_connect (global_device_list,
175 175 "store_changed",
176 176 G_CALLBACK (gdl_store_changed), NULL);
177 177 g_signal_connect (global_device_list,
178 178 "device_property_changed",
179 179 G_CALLBACK (gdl_property_changed), NULL);
180 180 g_signal_connect (global_device_list,
181 181 "device_capability_added",
182 182 G_CALLBACK (gdl_capability_added), NULL);
183 183 }
184 184
185 185 return global_device_list;
186 186 }
187 187
188 188 HalDeviceStore *
189 189 hald_get_tdl (void)
190 190 {
191 191 if (temporary_device_list == NULL) {
192 192 temporary_device_list = hal_device_store_new ();
193 193
194 194 }
195 195
196 196 return temporary_device_list;
197 197 }
198 198
199 199 /**
200 200 * @defgroup MainDaemon Basic functions
201 201 * @ingroup HalDaemon
202 202 * @brief Basic functions in the HAL daemon
203 203 * @{
204 204 */
205 205
206 206 /** Print out program usage.
207 207 *
208 208 */
209 209 static void
210 210 usage ()
211 211 {
212 212 fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help]\n");
213 213 fprintf (stderr,
214 214 "\n"
215 215 " --daemon=yes|no Become a daemon\n"
216 216 " --verbose=yes|no Print out debug (overrides HALD_VERBOSE)\n"
217 217 " --use-syslog Print out debug messages to syslog instead of stderr.\n"
218 218 " Use this option to get debug messages if HAL runs as\n"
219 219 " daemon.\n"
220 220 " --help Show this information and exit\n"
221 221 " --version Output version information and exit"
222 222 "\n"
223 223 "The HAL daemon detects devices present in the system and provides the\n"
224 224 "org.freedesktop.Hal service through the system-wide message bus provided\n"
225 225 "by D-BUS.\n"
226 226 "\n"
227 227 "For more information visit http://freedesktop.org/Software/hal\n"
228 228 "\n");
229 229 }
230 230
231 231 /** If #TRUE, we will daemonize */
232 232 static dbus_bool_t opt_become_daemon = TRUE;
233 233
234 234 /** If #TRUE, we will spew out debug */
235 235 dbus_bool_t hald_is_verbose = FALSE;
236 236 dbus_bool_t hald_use_syslog = FALSE;
237 237
238 238 static int sigterm_unix_signal_pipe_fds[2];
239 239 static GIOChannel *sigterm_iochn;
240 240
241 241 static void
242 242 handle_sigterm (int value)
243 243 {
244 244 ssize_t written;
245 245 static char marker[1] = {'S'};
246 246
247 247 /* write a 'S' character to the other end to tell about
248 248 * the signal. Note that 'the other end' is a GIOChannel thingy
249 249 * that is only called from the mainloop - thus this is how we
250 250 * defer this since UNIX signal handlers are evil
251 251 *
252 252 * Oh, and write(2) is indeed reentrant */
253 253 written = write (sigterm_unix_signal_pipe_fds[1], marker, 1);
254 254 }
255 255
256 256 static gboolean
257 257 sigterm_iochn_data (GIOChannel *source,
258 258 GIOCondition condition,
259 259 gpointer user_data)
260 260 {
261 261 GError *err = NULL;
262 262 gchar data[1];
263 263 gsize bytes_read;
264 264
265 265 /* Empty the pipe */
266 266 if (G_IO_STATUS_NORMAL !=
267 267 g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) {
268 268 HAL_ERROR (("Error emptying sigterm pipe: %s",
269 269 err->message));
270 270 g_error_free (err);
271 271 goto out;
272 272 }
273 273
274 274 HAL_INFO (("Caught SIGTERM, initiating shutdown"));
275 275 hald_runner_kill_all();
276 276 exit (0);
277 277
278 278 out:
279 279 return TRUE;
280 280 }
281 281
282 282
283 283 /** This is set to #TRUE if we are probing and #FALSE otherwise */
284 284 dbus_bool_t hald_is_initialising;
285 285
286 286 static int startup_daemonize_pipe[2];
287 287
288 288
289 289 /*--------------------------------------------------------------------------------------------------*/
290 290
291 291 static gboolean child_died = FALSE;
292 292
293 293 static void
294 294 handle_sigchld (int value)
295 295 {
296 296 child_died = TRUE;
297 297 }
298 298
299 299 static int
300 300 parent_wait_for_child (int child_fd, pid_t child_pid)
301 301 {
302 302 fd_set rfds;
303 303 fd_set efds;
304 304 struct timeval tv;
305 305 int retval;
306 306 int ret;
307 307
308 308 signal(SIGCHLD, handle_sigchld);
309 309
310 310 /* wait for either
311 311 *
312 312 * o Child writes something to the child_fd; means that device
313 313 * probing is completed and the parent should exit with success
314 314 *
315 315 * o Child is killed (segfault etc.); means that parent should exit
316 316 * with failure
317 317 *
318 318 * o Timeout; means that we should kill the child and exit with
319 319 * failure
320 320 *
321 321 */
322 322
323 323 FD_ZERO(&rfds);
324 324 FD_SET(child_fd, &rfds);
325 325 FD_ZERO(&efds);
326 326 FD_SET(child_fd, &efds);
327 327 /* Wait up to 250 seconds for device probing */
328 328 tv.tv_sec = 250;
329 329 tv.tv_usec = 0;
330 330
331 331 retval = select (child_fd + 1, &rfds, NULL, &efds, &tv);
332 332
333 333 if (child_died) {
334 334 /* written from handle_sigchld */
335 335 ret = 1;
336 336 goto out;
337 337 }
338 338
339 339 if (retval > 0) {
340 340 /* means child wrote to socket or closed it; all good */
341 341 ret = 0;
342 342 goto out;
343 343 }
344 344
345 345 /* assume timeout; kill child */
346 346 kill (child_pid, SIGTERM);
347 347 ret = 2;
348 348
349 349 out:
350 350 return ret;
351 351 }
352 352
353 353 /*--------------------------------------------------------------------------------------------------*/
354 354
355 355 /** Entry point for HAL daemon
356 356 *
357 357 * @param argc Number of arguments
358 358 * @param argv Array of arguments
359 359 * @return Exit code
↓ open down ↓ |
359 lines elided |
↑ open up ↑ |
360 360 */
361 361 int
362 362 main (int argc, char *argv[])
363 363 {
364 364 GMainLoop *loop;
365 365 guint sigterm_iochn_listener_source_id;
366 366 char *path;
367 367 char newpath[512];
368 368
369 369 openlog ("hald", LOG_PID, LOG_DAEMON);
370 -
370 +#if !GLIB_CHECK_VERSION(2,35,0)
371 371 g_type_init ();
372 -
372 +#endif
373 373 if (getenv ("HALD_VERBOSE"))
374 374 hald_is_verbose = TRUE;
375 375 else
376 376 hald_is_verbose = FALSE;
377 377
378 378 /* our helpers are installed into libexec, so adjust out $PATH
379 379 * to include this at the end (since we want to overide in
380 380 * run-hald.sh and friends)
381 381 */
382 382 path = getenv ("PATH");
383 383 if (path != NULL) {
384 384 g_strlcpy (newpath, path, sizeof (newpath));
385 385 g_strlcat (newpath, ":", sizeof (newpath));
386 386 } else {
387 387 /* No PATH was set */
388 388 newpath[0] = '\0';
389 389 }
390 390
391 391 g_strlcat (newpath, PACKAGE_LIBEXEC_DIR, sizeof (newpath));
392 392 g_strlcat (newpath, ":", sizeof (newpath));
393 393 g_strlcat (newpath, PACKAGE_SCRIPT_DIR, sizeof (newpath));
394 394
395 395 setenv ("PATH", newpath, TRUE);
396 396
397 397 while (1) {
398 398 int c;
399 399 int option_index = 0;
400 400 const char *opt;
401 401 static struct option long_options[] = {
402 402 {"daemon", 1, NULL, 0},
403 403 {"verbose", 1, NULL, 0},
404 404 {"use-syslog", 0, NULL, 0},
405 405 {"help", 0, NULL, 0},
406 406 {"version", 0, NULL, 0},
407 407 {NULL, 0, NULL, 0}
408 408 };
409 409
410 410 c = getopt_long (argc, argv, "",
411 411 long_options, &option_index);
412 412 if (c == -1)
413 413 break;
414 414
415 415 switch (c) {
416 416 case 0:
417 417 opt = long_options[option_index].name;
418 418
419 419 if (strcmp (opt, "help") == 0) {
420 420 usage ();
421 421 return 0;
422 422 } else if (strcmp (opt, "version") == 0) {
423 423 fprintf (stderr, "HAL package version: " PACKAGE_VERSION "\n");
424 424 return 0;
425 425 } else if (strcmp (opt, "daemon") == 0) {
426 426 if (strcmp ("yes", optarg) == 0) {
427 427 opt_become_daemon = TRUE;
428 428 } else if (strcmp ("no", optarg) == 0) {
429 429 opt_become_daemon = FALSE;
430 430 } else {
431 431 usage ();
432 432 return 1;
433 433 }
434 434 } else if (strcmp (opt, "verbose") == 0) {
435 435 if (strcmp ("yes", optarg) == 0) {
436 436 hald_is_verbose = TRUE;
437 437 } else if (strcmp ("no", optarg) == 0) {
438 438 hald_is_verbose = FALSE;
439 439 } else {
440 440 usage ();
441 441 return 1;
442 442 }
443 443 } else if (strcmp (opt, "use-syslog") == 0) {
444 444 hald_use_syslog = TRUE;
445 445 }
446 446
447 447 break;
448 448
449 449 default:
450 450 usage ();
451 451 return 1;
452 452 break;
453 453 }
454 454 }
455 455
456 456 if (hald_is_verbose)
457 457 logger_enable ();
458 458 else
459 459 logger_disable ();
460 460
461 461 if (hald_use_syslog)
462 462 logger_enable_syslog ();
463 463 else
464 464 logger_disable_syslog ();
465 465
466 466 /* will fork into two; only the child will return here if we are successful */
467 467 /*master_slave_setup ();
468 468 sleep (100000000);*/
469 469
470 470 loop = g_main_loop_new (NULL, FALSE);
471 471
472 472 HAL_INFO ((PACKAGE_STRING));
473 473
474 474 if (opt_become_daemon) {
475 475 int child_pid;
476 476 int dev_null_fd;
477 477 int pf;
478 478 ssize_t written;
479 479 char pid[9];
480 480
481 481 HAL_INFO (("Will daemonize"));
482 482 HAL_INFO (("Becoming a daemon"));
483 483
484 484 if (pipe (startup_daemonize_pipe) != 0) {
485 485 fprintf (stderr, "Could not setup pipe: %s\n", strerror(errno));
486 486 exit (1);
487 487 }
488 488
489 489
490 490 if (chdir ("/") < 0) {
491 491 fprintf (stderr, "Could not chdir to /: %s\n", strerror(errno));
492 492 exit (1);
493 493 }
494 494
495 495 child_pid = fork ();
496 496 switch (child_pid) {
497 497 case -1:
498 498 fprintf (stderr, "Cannot fork(): %s\n", strerror(errno));
499 499 break;
500 500
501 501 case 0:
502 502 /* child */
503 503
504 504 dev_null_fd = open ("/dev/null", O_RDWR);
505 505 /* ignore if we can't open /dev/null */
506 506 if (dev_null_fd >= 0) {
507 507 /* attach /dev/null to stdout, stdin, stderr */
508 508 dup2 (dev_null_fd, 0);
509 509 dup2 (dev_null_fd, 1);
510 510 dup2 (dev_null_fd, 2);
511 511 close (dev_null_fd);
512 512 }
513 513
514 514 umask (022);
515 515 break;
516 516
517 517 default:
518 518 /* parent, block until child writes */
519 519 exit (parent_wait_for_child (startup_daemonize_pipe[0], child_pid));
520 520 break;
521 521 }
522 522
523 523 /* Create session */
524 524 setsid ();
525 525
526 526 /* remove old pid file */
527 527 unlink (HALD_PID_FILE);
528 528
529 529 /* Make a new one */
530 530 if ((pf= open (HALD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) {
531 531 snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ());
532 532 written = write (pf, pid, strlen(pid));
533 533 close (pf);
534 534 atexit (delete_pid);
535 535 }
536 536 } else {
537 537 HAL_INFO (("Will not daemonize"));
538 538 }
539 539
540 540
541 541 /* we need to do stuff when we are expected to terminate, thus
542 542 * this involves looking for SIGTERM; UNIX signal handlers are
543 543 * evil though, so set up a pipe to transmit the signal.
544 544 */
545 545
546 546 /* create pipe */
547 547 if (pipe (sigterm_unix_signal_pipe_fds) != 0) {
548 548 DIE (("Could not setup pipe, errno=%d", errno));
549 549 }
550 550
551 551 /* setup glib handler - 0 is for reading, 1 is for writing */
552 552 sigterm_iochn = g_io_channel_unix_new (sigterm_unix_signal_pipe_fds[0]);
553 553 if (sigterm_iochn == NULL)
554 554 DIE (("Could not create GIOChannel"));
555 555
556 556 /* get callback when there is data to read */
557 557 sigterm_iochn_listener_source_id = g_io_add_watch (
558 558 sigterm_iochn, G_IO_IN, sigterm_iochn_data, NULL);
559 559
560 560 /* Finally, setup unix signal handler for TERM */
561 561 signal (SIGTERM, handle_sigterm);
562 562
563 563 /* set up the local dbus server */
564 564 if (!hald_dbus_local_server_init ())
565 565 return 1;
566 566 /* Start the runner helper daemon */
567 567 if (!hald_runner_start_runner ()) {
568 568 return 1;
569 569 }
570 570
571 571 drop_privileges(0);
572 572
573 573 /* initialize operating system specific parts */
574 574 osspec_init ();
575 575
576 576 hald_is_initialising = TRUE;
577 577
578 578 /* detect devices */
579 579 osspec_probe ();
580 580
581 581 /* run the main loop and serve clients */
582 582 g_main_loop_run (loop);
583 583
584 584 return 0;
585 585 }
586 586
587 587 #ifdef HALD_MEMLEAK_DBG
588 588 extern int dbg_hal_device_object_delta;
589 589
590 590 /* useful for valgrinding; see below */
591 591 static gboolean
592 592 my_shutdown (gpointer data)
593 593 {
594 594 HalDeviceStore *gdl;
595 595
596 596 printf ("Num devices in TDL: %d\n", g_slist_length ((hald_get_tdl ())->devices));
597 597 printf ("Num devices in GDL: %d\n", g_slist_length ((hald_get_gdl ())->devices));
598 598
599 599 gdl = hald_get_gdl ();
600 600 next:
601 601 if (g_slist_length (gdl->devices) > 0) {
602 602 HalDevice *d = HAL_DEVICE(gdl->devices->data);
603 603 hal_device_store_remove (gdl, d);
604 604 g_object_unref (d);
605 605 goto next;
606 606 }
607 607
608 608 printf ("hal_device_object_delta = %d (should be zero)\n", dbg_hal_device_object_delta);
609 609 exit (1);
610 610 }
611 611 #endif
612 612
613 613 void
614 614 osspec_probe_done (void)
615 615 {
616 616 ssize_t written;
617 617 char buf[1] = {0};
618 618
619 619 HAL_INFO (("Device probing completed"));
620 620
621 621 if (!hald_dbus_init ()) {
622 622 hald_runner_kill_all();
623 623 exit (1);
624 624 }
625 625
626 626 /* tell parent to exit */
627 627 written = write (startup_daemonize_pipe[1], buf, sizeof (buf));
628 628 close (startup_daemonize_pipe[0]);
629 629 close (startup_daemonize_pipe[1]);
630 630
631 631 hald_is_initialising = FALSE;
632 632
633 633 #ifdef HALD_MEMLEAK_DBG
634 634 g_timeout_add ((HALD_MEMLEAK_DBG) * 1000,
635 635 my_shutdown,
636 636 NULL);
637 637 #endif
638 638 }
639 639
640 640
641 641 /** @} */
↓ open down ↓ |
259 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX