diff options
Diffstat (limited to 'src/sleep/sleep.c')
-rw-r--r-- | src/sleep/sleep.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c new file mode 100644 index 0000000000..218de3a567 --- /dev/null +++ b/src/sleep/sleep.c @@ -0,0 +1,127 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "log.h" +#include "util.h" +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" + +int main(int argc, char *argv[]) { + const char *verb; + char* arguments[4]; + int r; + FILE *f; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc != 2) { + log_error("Invalid number of arguments."); + r = -EINVAL; + goto finish; + } + + if (streq(argv[1], "suspend")) + verb = "mem"; + else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep")) + verb = "disk"; + else { + log_error("Unknown action '%s'.", argv[1]); + r = -EINVAL; + goto finish; + } + + /* Configure the hibernation mode */ + if (streq(argv[1], "hibernate")) { + if (write_one_line_file("/sys/power/disk", "platform") < 0) + write_one_line_file("/sys/power/disk", "shutdown"); + } else if (streq(argv[1], "hybrid-sleep")) { + if (write_one_line_file("/sys/power/disk", "suspend") < 0) + if (write_one_line_file("/sys/power/disk", "platform") < 0) + write_one_line_file("/sys/power/disk", "shutdown"); + } + + f = fopen("/sys/power/state", "we"); + if (!f) { + log_error("Failed to open /sys/power/state: %m"); + r = -errno; + goto finish; + } + + arguments[0] = NULL; + arguments[1] = (char*) "pre"; + arguments[2] = argv[1]; + arguments[3] = NULL; + execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments); + + if (streq(argv[1], "suspend")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Suspending system...", + "SLEEP=suspend", + NULL); + else if (streq(argv[1], "hibernate")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Hibernating system...", + "SLEEP=hibernate", + NULL); + else + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Hibernating and suspending system...", + "SLEEP=hybrid-sleep", + NULL); + + fputs(verb, f); + fputc('\n', f); + fflush(f); + + r = ferror(f) ? -errno : 0; + + if (streq(argv[1], "suspend")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_STOP), + "MESSAGE=System resumed.", + "SLEEP=suspend", + NULL); + else + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_STOP), + "MESSAGE=System thawed.", + "SLEEP=hibernate", + NULL); + + arguments[1] = (char*) "post"; + execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments); + + fclose(f); + +finish: + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +} |