/** * cancel_callback: * @data: not used, * @signal: signal caught. * * This callback is run whenever one of the "cancel running shutdown" * signals is sent to us. * * This does not return. **/ static void cancel_callback (void *data, NihSignal *signal) { nih_error (_("Shutdown cancelled")); unlink (ETC_NOLOGIN); nih_main_unlink_pidfile (); exit (0); }
void test_read_pidfile (void) { FILE *f; char filename[PATH_MAX]; TEST_FUNCTION ("nih_main_read_pidfile"); TEST_FILENAME (filename); nih_main_set_pidfile (filename); /* Check that reading from a valid pid file will return the pid * stored there. */ TEST_FEATURE ("with valid pid file"); f = fopen (filename, "w"); fprintf (f, "1234\n"); fclose (f); TEST_EQ (nih_main_read_pidfile (), 1234); /* Check that reading from a pid file without a newline will still * return the pid stored there. */ TEST_FEATURE ("with no newline in pid file"); f = fopen (filename, "w"); fprintf (f, "1234"); fclose (f); TEST_EQ (nih_main_read_pidfile (), 1234); /* Check that reading from an invalid pid file returns -1. */ TEST_FEATURE ("with invalid pid file"); f = fopen (filename, "w"); fprintf (f, "foo\n1234\n"); fclose (f); TEST_EQ (nih_main_read_pidfile (), -1); /* Check that reading from a non-existant pid file returns -1. */ TEST_FEATURE ("with non-existant pid file"); nih_main_unlink_pidfile (); TEST_EQ (nih_main_read_pidfile (), -1); nih_main_set_pidfile (NULL); }
/** * 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); }
int main (int argc, char *argv[]) { char ** args; int ret; DBusServer * server; struct stat sb; struct rlimit newrlimit; nih_main_init (argv[0]); nih_option_set_synopsis (_("Control group manager")); nih_option_set_help (_("The cgroup manager daemon")); args = nih_option_parser (NULL, argc, argv, options, FALSE); if (! args) exit (1); if (!setup_cgroup_dir()) { nih_fatal("Failed to set up cgmanager socket"); exit(1); } /* Setup the DBus server */ server = nih_dbus_server (CGMANAGER_DBUS_PATH, client_connect, client_disconnect); nih_assert (server != NULL); if (!setup_base_run_path()) { nih_fatal("Error setting up base cgroup path"); return -1; } if (collect_subsystems(extra_cgroup_mounts) < 0) { nih_fatal("failed to collect cgroup subsystems"); exit(1); } if (!create_agent_symlinks()) { nih_fatal("Error creating release agent symlinks"); exit(1); } if (setup_cgroup_mounts() < 0) { nih_fatal ("Failed to set up cgroup mounts"); exit(1); } if (!move_self_to_root()) { nih_fatal ("Failed to move self to root cgroup"); exit(1); } if (stat("/proc/self/ns/pid", &sb) == 0) { mypidns = read_pid_ns_link(getpid()); setns_pid_supported = true; } if (stat("/proc/self/ns/user", &sb) == 0) { myuserns = read_user_ns_link(getpid()); setns_user_supported = true; } newrlimit.rlim_cur = 10000; newrlimit.rlim_max = 10000; if (setrlimit(RLIMIT_NOFILE, &newrlimit) < 0) nih_warn("Failed to increase open file limit: %s", strerror(errno)); /* Become daemon */ if (daemonise) { if (nih_main_daemonise () < 0) { NihError *err; err = nih_error_get (); nih_fatal ("%s: %s", _("Unable to become daemon"), err->message); nih_free (err); exit (1); } } if (sigstop) raise(SIGSTOP); ret = nih_main_loop (); /* Destroy any PID file we may have created */ if (daemonise) { nih_main_unlink_pidfile(); } return ret; }
void test_write_pidfile (void) { FILE *f; NihError *err; char dirname[PATH_MAX], filename[PATH_MAX], tmpname[PATH_MAX]; int ret; TEST_FUNCTION ("nih_main_write_pidfile"); TEST_FILENAME (dirname); mkdir (dirname, 0755); strcpy (filename, dirname); strcat (filename, "/test.pid"); strcpy (tmpname, dirname); strcat (tmpname, "/.test.pid.tmp"); nih_main_set_pidfile (filename); /* Check that we can write a pid to the file, and have it appaer * on disk where we expect. */ TEST_FEATURE ("with successful write"); ret = nih_main_write_pidfile (1234); TEST_EQ (ret, 0); f = fopen (filename, "r"); TEST_FILE_EQ (f, "1234\n"); fclose (f); /* Check that we can overwrite an existing pid file with a new * value. */ TEST_FEATURE ("with overwrite of existing pid"); ret = nih_main_write_pidfile (5678); TEST_EQ (ret, 0); f = fopen (filename, "r"); TEST_FILE_EQ (f, "5678\n"); fclose (f); /* Check that an error writing to the temporary file does not result * in the replacement of the existing file and does not result in * the unlinking of the temporary file. */ TEST_FEATURE ("with failure to write to temporary file"); f = fopen (tmpname, "w"); fclose (f); chmod (tmpname, 0000); ret = nih_main_write_pidfile (1234); TEST_LT (ret, 0); err = nih_error_get (); TEST_EQ (err->number, EACCES); nih_free (err); f = fopen (filename, "r"); TEST_FILE_EQ (f, "5678\n"); fclose (f); TEST_EQ (chmod (tmpname, 0644), 0); nih_main_unlink_pidfile (); unlink (tmpname); rmdir (dirname); nih_main_set_pidfile (NULL); }