/** * shutdown_now: * * Send a signal to init to shut down the machine. * * This does not return. **/ static void shutdown_now (void) { nih_local char **extra_env = NULL; NihDBusError * dbus_err; if (init_halt) { char *e; e = NIH_MUST (nih_sprintf (NULL, "INIT_HALT=%s", init_halt)); extra_env = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_addp (&extra_env, NULL, NULL, e)); } if (sysv_change_runlevel (runlevel, extra_env, NULL, NULL) < 0) { dbus_err = (NihDBusError *)nih_error_get (); if ((dbus_err->number != NIH_DBUS_ERROR) || strcmp (dbus_err->name, DBUS_ERROR_NO_SERVER)) { nih_fatal ("%s", dbus_err->message); nih_free (dbus_err); exit (1); } nih_free (dbus_err); /* Connection Refused means that init isn't running, this * might mean we've just upgraded to upstart and haven't * yet rebooted ... so try /dev/initctl */ sysvinit_shutdown (); } unlink (ETC_NOLOGIN); nih_main_unlink_pidfile (); exit (0); }
void test_array_addp (void) { char **array, **ret; char *ptr1 = NULL; char *ptr2 = NULL; size_t len; TEST_FUNCTION ("nih_str_array_addn"); /* Check that we can call the function with a NULL array pointer, * and get one allocated automatically. */ TEST_FEATURE ("with no array given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } array = NULL; len = 0; ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); TEST_EQ (len, 0); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can append allocated blocks to a * NULL-terminated array, and that the blocks are automatically * reparented. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); assert (nih_str_array_addp (&array, NULL, NULL, ptr1)); ptr2 = nih_alloc (NULL, 512); memset (ptr2, ' ', 512); } ret = nih_str_array_addp (&array, NULL, NULL, ptr2); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); continue; } TEST_NE_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], ptr2); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[2], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); } }
static void udev_monitor_watcher (struct udev_monitor *udev_monitor, NihIoWatch * watch, NihIoEvents events) { struct udev_device * udev_device; nih_local char * subsystem = NULL; nih_local char * action = NULL; nih_local char * kernel = NULL; nih_local char * devpath = NULL; nih_local char * devname = NULL; nih_local char * name = NULL; nih_local char ** env = NULL; const char * value = NULL; size_t env_len = 0; DBusPendingCall * pending_call; char *(*copy_string)(const void *, const char *) = NULL; udev_device = udev_monitor_receive_device (udev_monitor); if (! udev_device) return; copy_string = no_strip_udev_data ? nih_strdup : make_safe_string; value = udev_device_get_subsystem (udev_device); subsystem = value ? copy_string (NULL, value) : NULL; value = udev_device_get_action (udev_device); action = value ? copy_string (NULL, value) : NULL; value = udev_device_get_sysname (udev_device); kernel = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devpath (udev_device); devpath = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devnode (udev_device); devname = value ? copy_string (NULL, value) : NULL; /* Protect against the "impossible" */ if (! action) goto out; if (! strcmp (action, "add")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-added", subsystem)); } else if (! strcmp (action, "change")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-changed", subsystem)); } else if (! strcmp (action, "remove")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-removed", subsystem)); } else { name = NIH_MUST (nih_sprintf (NULL, "%s-device-%s", subsystem, action)); } env = NIH_MUST (nih_str_array_new (NULL)); if (kernel) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "KERNEL=%s", kernel)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devpath) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVPATH=%s", devpath)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devname) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVNAME=%s", devname)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (subsystem) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "SUBSYSTEM=%s", subsystem)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (action) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "ACTION=%s", action)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } for (struct udev_list_entry *list_entry = udev_device_get_properties_list_entry (udev_device); list_entry != NULL; list_entry = udev_list_entry_get_next (list_entry)) { nih_local char *udev_name = NULL; nih_local char *udev_value = NULL; nih_local char *var = NULL; udev_name = copy_string (NULL, udev_list_entry_get_name (list_entry)); if (! strcmp (udev_name, "DEVPATH")) continue; if (! strcmp (udev_name, "DEVNAME")) continue; if (! strcmp (udev_name, "SUBSYSTEM")) continue; if (! strcmp (udev_name, "ACTION")) continue; udev_value = copy_string (NULL, udev_list_entry_get_value (list_entry)); var = NIH_MUST (nih_sprintf (NULL, "%s=%s", udev_name, udev_value)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } nih_debug ("%s %s", name, devname ? devname : ""); pending_call = upstart_emit_event (upstart, name, env, FALSE, NULL, emit_event_error, NULL, NIH_DBUS_TIMEOUT_NEVER); if (! pending_call) { NihError *err; int saved = errno; err = nih_error_get (); nih_warn ("%s", err->message); if (saved != ENOMEM && subsystem) nih_warn ("Likely that udev '%s' event contains binary garbage", subsystem); nih_free (err); } dbus_pending_call_unref (pending_call); out: udev_device_unref (udev_device); }