HelenOS sources
This source file includes following definitions.
- sd_shutdown_complete
- sd_shutdown_failed
- choose_action
- main
- syntax_print
#include <fibril_synch.h>
#include <nchoice.h>
#include <stdio.h>
#include <stdbool.h>
#include <str.h>
#include <system.h>
#include "shutdown.h"
#define NAME "shutdown"
static void syntax_print(void);
static sd_action_t action;
static void sd_shutdown_complete(void *);
static void sd_shutdown_failed(void *);
static system_cb_t sd_system_cb = {
.shutdown_complete = sd_shutdown_complete,
.shutdown_failed = sd_shutdown_failed
};
static void sd_shutdown_complete(void *arg)
{
shutdown_t *shutdown = (shutdown_t *)arg;
fibril_mutex_lock(&shutdown->lock);
shutdown->stopped = true;
shutdown->failed = false;
fibril_condvar_broadcast(&shutdown->cv);
fibril_mutex_unlock(&shutdown->lock);
}
static void sd_shutdown_failed(void *arg)
{
shutdown_t *shutdown = (shutdown_t *)arg;
fibril_mutex_lock(&shutdown->lock);
shutdown->stopped = true;
shutdown->failed = true;
fibril_condvar_broadcast(&shutdown->cv);
fibril_mutex_unlock(&shutdown->lock);
}
static errno_t choose_action(void)
{
errno_t rc;
nchoice_t *nchoice = NULL;
void *choice;
rc = nchoice_create(&nchoice);
if (rc != EOK) {
printf(NAME ": Out of memory.\n");
goto error;
}
rc = nchoice_set_prompt(nchoice, "Select action");
if (rc != EOK) {
printf(NAME ": Out of memory.\n");
goto error;
}
rc = nchoice_add(nchoice, "Power off", (void *)(uintptr_t)sd_poweroff,
0);
if (rc != EOK) {
printf(NAME ": Out of memory.\n");
goto error;
}
rc = nchoice_add(nchoice, "Cancel", (void *)(uintptr_t)sd_cancel,
ncf_default);
if (rc != EOK) {
printf(NAME ": Out of memory.\n");
goto error;
}
rc = nchoice_get(nchoice, &choice);
if (rc != EOK) {
if (rc != ENOENT)
printf(NAME ": Error getting user choice.\n");
goto error;
}
action = (sd_action_t)choice;
nchoice_destroy(nchoice);
return EOK;
error:
if (nchoice != NULL)
nchoice_destroy(nchoice);
return rc;
}
int main(int argc, char **argv)
{
errno_t rc;
system_t *system = NULL;
shutdown_t shutdown;
--argc;
++argv;
while (*argv != NULL && *argv[0] == '-') {
if (str_cmp(*argv, "-p") == 0) {
--argc;
++argv;
action = sd_poweroff;
continue;
}
printf(NAME ": Error, invalid option.\n");
syntax_print();
return 1;
}
if (argc >= 1) {
printf(NAME ": Error, unexpected argument.\n");
syntax_print();
return 1;
}
if (action == 0)
choose_action();
if (action == sd_cancel)
return 0;
fibril_mutex_initialize(&shutdown.lock);
fibril_condvar_initialize(&shutdown.cv);
shutdown.stopped = false;
shutdown.failed = false;
rc = system_open(SYSTEM_DEFAULT, &sd_system_cb, &shutdown, &system);
if (rc != EOK) {
printf(NAME ": Failed opening system control service.\n");
return 1;
}
rc = system_shutdown(system);
if (rc != EOK) {
system_close(system);
printf(NAME ": Failed requesting system shutdown.\n");
return 1;
}
fibril_mutex_lock(&shutdown.lock);
printf("System is shutting down...\n");
while (!shutdown.stopped)
fibril_condvar_wait(&shutdown.cv, &shutdown.lock);
if (shutdown.failed) {
printf("Shutdown failed.\n");
system_close(system);
return 1;
}
printf("Shutdown complete. It is now safe to remove power.\n");
while (true)
fibril_condvar_wait(&shutdown.cv, &shutdown.lock);
fibril_mutex_unlock(&shutdown.lock);
system_close(system);
return 0;
}
static void syntax_print(void)
{
printf("syntax:\n"
"\tshutdown [<options>]\n"
"options:\n"
"\t-p Power off\n");
}
HelenOS homepage, sources at GitHub