]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/sleep/sleep.c
util: unify implementation of NOP signal handler
[thirdparty/systemd.git] / src / sleep / sleep.c
CommitLineData
6edd7d0a
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
19adb8a3 7 Copyright 2013 Zbigniew Jędrzejewski-Szmek
6edd7d0a
LP
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <stdio.h>
24#include <errno.h>
19adb8a3 25#include <getopt.h>
6edd7d0a 26
aa62a893 27#include "sd-messages.h"
19adb8a3
ZJS
28#include "log.h"
29#include "util.h"
30#include "strv.h"
a5c32cff 31#include "fileio.h"
19adb8a3
ZJS
32#include "build.h"
33#include "sleep-config.h"
aa62a893 34#include "def.h"
19adb8a3
ZJS
35
36static char* arg_verb = NULL;
37
38static int write_mode(char **modes) {
39 int r = 0;
40 char **mode;
41
42 STRV_FOREACH(mode, modes) {
aa62a893
LP
43 int k;
44
4c1fc3e4 45 k = write_string_file("/sys/power/disk", *mode, 0);
19adb8a3
ZJS
46 if (k == 0)
47 return 0;
aa62a893 48
c33b3297
MS
49 log_debug_errno(k, "Failed to write '%s' to /sys/power/disk: %m",
50 *mode);
19adb8a3
ZJS
51 if (r == 0)
52 r = k;
53 }
6edd7d0a 54
19adb8a3 55 if (r < 0)
c33b3297 56 log_error_errno(r, "Failed to write mode to /sys/power/disk: %m");
6edd7d0a 57
19adb8a3
ZJS
58 return r;
59}
6edd7d0a 60
2fd069b1 61static int write_state(FILE **f, char **states) {
19adb8a3
ZJS
62 char **state;
63 int r = 0;
64
65 STRV_FOREACH(state, states) {
66 int k;
67
40beecdb 68 k = write_string_stream(*f, *state, true);
19adb8a3
ZJS
69 if (k == 0)
70 return 0;
c33b3297
MS
71 log_debug_errno(k, "Failed to write '%s' to /sys/power/state: %m",
72 *state);
19adb8a3
ZJS
73 if (r == 0)
74 r = k;
75
2fd069b1
ZJS
76 fclose(*f);
77 *f = fopen("/sys/power/state", "we");
4a62c710
MS
78 if (!*f)
79 return log_error_errno(errno, "Failed to open /sys/power/state: %m");
6edd7d0a
LP
80 }
81
19adb8a3
ZJS
82 return r;
83}
6edd7d0a 84
19adb8a3 85static int execute(char **modes, char **states) {
e2cc6eca
LP
86
87 char *arguments[] = {
88 NULL,
89 (char*) "pre",
90 arg_verb,
91 NULL
92 };
e801700e 93 static const char* const dirs[] = {SYSTEM_SLEEP_PATH, NULL};
e2cc6eca 94
19adb8a3 95 int r;
2fd069b1 96 _cleanup_fclose_ FILE *f = NULL;
6524990f 97
19adb8a3 98 /* This file is opened first, so that if we hit an error,
09692409 99 * we can abort before modifying any state. */
6edd7d0a 100 f = fopen("/sys/power/state", "we");
4a62c710
MS
101 if (!f)
102 return log_error_errno(errno, "Failed to open /sys/power/state: %m");
6edd7d0a 103
19adb8a3
ZJS
104 /* Configure the hibernation mode */
105 r = write_mode(modes);
106 if (r < 0)
107 return r;
108
e801700e 109 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
6edd7d0a 110
19adb8a3 111 log_struct(LOG_INFO,
e2cc6eca
LP
112 LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_START),
113 LOG_MESSAGE("Suspending system..."),
114 "SLEEP=%s", arg_verb,
19adb8a3
ZJS
115 NULL);
116
2fd069b1 117 r = write_state(&f, states);
19adb8a3
ZJS
118 if (r < 0)
119 return r;
120
121 log_struct(LOG_INFO,
e2cc6eca 122 LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_STOP),
a5ccdb98 123 LOG_MESSAGE("System resumed."),
e2cc6eca 124 "SLEEP=%s", arg_verb,
19adb8a3 125 NULL);
eb267289 126
6edd7d0a 127 arguments[1] = (char*) "post";
e801700e 128 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
6edd7d0a 129
19adb8a3
ZJS
130 return r;
131}
6edd7d0a 132
601185b4 133static void help(void) {
19adb8a3
ZJS
134 printf("%s COMMAND\n\n"
135 "Suspend the system, hibernate the system, or both.\n\n"
136 "Commands:\n"
137 " -h --help Show this help and exit\n"
138 " --version Print version string and exit\n"
139 " suspend Suspend the system\n"
140 " hibernate Hibernate the system\n"
141 " hybrid-sleep Both hibernate and suspend the system\n"
601185b4 142 , program_invocation_short_name);
19adb8a3 143}
6edd7d0a 144
19adb8a3
ZJS
145static int parse_argv(int argc, char *argv[]) {
146 enum {
147 ARG_VERSION = 0x100,
148 };
149
150 static const struct option options[] = {
151 { "help", no_argument, NULL, 'h' },
152 { "version", no_argument, NULL, ARG_VERSION },
eb9da376 153 {}
19adb8a3
ZJS
154 };
155
156 int c;
157
158 assert(argc >= 0);
159 assert(argv);
160
601185b4 161 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
19adb8a3
ZJS
162 switch(c) {
163 case 'h':
601185b4
ZJS
164 help();
165 return 0; /* done */
19adb8a3
ZJS
166
167 case ARG_VERSION:
168 puts(PACKAGE_STRING);
169 puts(SYSTEMD_FEATURES);
170 return 0 /* done */;
171
172 case '?':
173 return -EINVAL;
174
175 default:
eb9da376 176 assert_not_reached("Unhandled option");
19adb8a3
ZJS
177 }
178
179 if (argc - optind != 1) {
180 log_error("Usage: %s COMMAND",
181 program_invocation_short_name);
182 return -EINVAL;
183 }
184
185 arg_verb = argv[optind];
6edd7d0a 186
19adb8a3
ZJS
187 if (!streq(arg_verb, "suspend") &&
188 !streq(arg_verb, "hibernate") &&
189 !streq(arg_verb, "hybrid-sleep")) {
190 log_error("Unknown command '%s'.", arg_verb);
191 return -EINVAL;
192 }
193
194 return 1 /* work to do */;
195}
196
197int main(int argc, char *argv[]) {
198 _cleanup_strv_free_ char **modes = NULL, **states = NULL;
199 int r;
200
201 log_set_target(LOG_TARGET_AUTO);
202 log_parse_environment();
203 log_open();
204
205 r = parse_argv(argc, argv);
206 if (r <= 0)
207 goto finish;
208
209 r = parse_sleep_config(arg_verb, &modes, &states);
210 if (r < 0)
211 goto finish;
212
213 r = execute(modes, states);
214
215finish:
216 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
6edd7d0a 217}