Merge pull request #8199 from keszybz/small-things

Sundry small cleanups
This commit is contained in:
Lennart Poettering 2018-02-19 16:55:10 +01:00 committed by GitHub
commit 30663b6c25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 258 additions and 220 deletions

View file

@ -554,6 +554,17 @@ int tmp_dir(const char **ret) {
return tmp_dir_internal("/tmp", ret);
}
int unlink_or_warn(const char *filename) {
if (unlink(filename) < 0 && errno != ENOENT)
/* If the file doesn't exist and the fs simply was read-only (in which
* case unlink() returns EROFS even if the file doesn't exist), don't
* complain */
if (errno != EROFS || access(filename, F_OK) >= 0)
return log_error_errno(errno, "Failed to remove \"%s\": %m", filename);
return 0;
}
int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
int r;

View file

@ -64,6 +64,8 @@ int get_files_in_directory(const char *path, char ***list);
int tmp_dir(const char **ret);
int var_tmp_dir(const char **ret);
int unlink_or_warn(const char *filename);
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \

View file

@ -179,6 +179,7 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i
}
char ***strv_free_free(char ***l);
DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free);
char **strv_skip(char **l, size_t n);

View file

@ -387,8 +387,8 @@ int acquire_terminal(
*
* Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
* whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure to
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which they
* probably should not do anyway.) */
if ((flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_WAIT) {
@ -731,7 +731,7 @@ int get_kernel_consoles(char ***ret) {
assert(ret);
/* If we /sys is mounted read-only this means we are running in some kind of container environment. In that
/* If /sys is mounted read-only this means we are running in some kind of container environment. In that
* case /sys would reflect the host system, not us, hence ignore the data we can read from it. */
if (path_is_read_only_fs("/sys") > 0)
goto fallback;
@ -1242,7 +1242,7 @@ bool terminal_is_dumb(void) {
bool colors_enabled(void) {
/* Returns true if colors are considered supported on our stdout. For that we check $SYSTEMD_COLORS first
* (which is the explicit way to turn off/on colors). If that didn't work we turn off colors unless we are on a
* (which is the explicit way to turn colors on/off). If that didn't work we turn colors off unless we are on a
* TTY. And if we are on a TTY we turn it off if $TERM is set to "dumb". There's one special tweak though: if
* we are PID 1 then we do not check whether we are connected to a TTY, because we don't keep /dev/console open
* continously due to fear of SAK, and hence things are a bit weird. */
@ -1270,8 +1270,8 @@ bool dev_console_colors_enabled(void) {
/* Returns true if we assume that color is supported on /dev/console.
*
* For that we first check if we explicitly got told to use colors or not, by checking $SYSTEMD_COLORS. If that
* didn't tell us anything we check whether PID 1 has $TERM set, and if not whether $TERM is set on the kernel
* command line. If we find $TERM set we assume color if it's not set to "dumb", similar to regular
* isn't set we check whether PID 1 has $TERM set, and if not, whether TERM is set on the kernel command
* line. If we find $TERM set we assume color if it's not set to "dumb", similarly to how regular
* colors_enabled() operates. */
b = getenv_bool("SYSTEMD_COLORS");

View file

@ -652,107 +652,6 @@ static int config_parse_crash_chvt(
return 0;
}
static int config_parse_join_controllers(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
const char *whole_rvalue = rvalue;
unsigned n = 0;
assert(filename);
assert(lvalue);
assert(rvalue);
arg_join_controllers = strv_free_free(arg_join_controllers);
for (;;) {
_cleanup_free_ char *word = NULL;
char **l;
int r;
r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
return r;
}
if (r == 0)
break;
l = strv_split(word, ",");
if (!l)
return log_oom();
strv_uniq(l);
if (strv_length(l) <= 1) {
strv_free(l);
continue;
}
if (!arg_join_controllers) {
arg_join_controllers = new(char**, 2);
if (!arg_join_controllers) {
strv_free(l);
return log_oom();
}
arg_join_controllers[0] = l;
arg_join_controllers[1] = NULL;
n = 1;
} else {
char ***a;
char ***t;
t = new0(char**, n+2);
if (!t) {
strv_free(l);
return log_oom();
}
n = 0;
for (a = arg_join_controllers; *a; a++) {
if (strv_overlap(*a, l)) {
if (strv_extend_strv(&l, *a, false) < 0) {
strv_free(l);
strv_free_free(t);
return log_oom();
}
} else {
char **c;
c = strv_copy(*a);
if (!c) {
strv_free(l);
strv_free_free(t);
return log_oom();
}
t[n++] = c;
}
}
t[n++] = strv_uniq(l);
strv_free_free(arg_join_controllers);
arg_join_controllers = t;
}
}
if (!isempty(rvalue))
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
return 0;
}
static int parse_config_file(void) {
const ConfigTableItem items[] = {
@ -1314,32 +1213,6 @@ static void test_usr(void) {
"Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
}
static int initialize_join_controllers(void) {
/* By default, mount "cpu" + "cpuacct" together, and "net_cls"
* + "net_prio". We'd like to add "cpuset" to the mix, but
* "cpuset" doesn't really work for groups with no initialized
* attributes. */
arg_join_controllers = new(char**, 3);
if (!arg_join_controllers)
return -ENOMEM;
arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
if (!arg_join_controllers[0])
goto oom;
arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
if (!arg_join_controllers[1])
goto oom;
arg_join_controllers[2] = NULL;
return 0;
oom:
arg_join_controllers = strv_free_free(arg_join_controllers);
return -ENOMEM;
}
static int enforce_syscall_archs(Set *archs) {
#if HAVE_SECCOMP
int r;
@ -2094,12 +1967,6 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess
assert(ret_error_message);
r = initialize_join_controllers();
if (r < 0) {
*ret_error_message = "Failed to initialize cgroup controller joining table";
return r;
}
arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
r = parse_config_file();

View file

@ -2725,7 +2725,6 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
}
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
log_error_errno(errno, "connect() failed: %m");
return;

View file

@ -253,6 +253,19 @@ int mount_cgroup_controllers(char ***join_controllers) {
/* Mount all available cgroup controllers that are built into the kernel. */
if (!join_controllers)
/* The defaults:
* mount "cpu" + "cpuacct" together, and "net_cls" + "net_prio".
*
* We'd like to add "cpuset" to the mix, but "cpuset" doesn't really
* work for groups with no initialized attributes.
*/
join_controllers = (char**[]) {
STRV_MAKE("cpu", "cpuacct"),
STRV_MAKE("net_cls", "net_prio"),
NULL,
};
r = cg_kernel_controllers(&controllers);
if (r < 0)
return log_error_errno(r, "Failed to enumerate cgroup controllers: %m");
@ -271,10 +284,9 @@ int mount_cgroup_controllers(char ***join_controllers) {
if (!controller)
break;
if (join_controllers)
for (k = join_controllers; *k; k++)
if (strv_find(*k, controller))
break;
for (k = join_controllers; *k; k++)
if (strv_find(*k, controller))
break;
if (k && *k) {
char **i, **j;

View file

@ -2458,7 +2458,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
}
}
/* Some names are special */
if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
if (u->type == UNIT_SERVICE &&

View file

@ -778,7 +778,9 @@ int server_restore_streams(Server *s, FDSet *fds) {
if (!found) {
/* No file descriptor? Then let's delete the state file */
log_debug("Cannot restore stream file %s", de->d_name);
unlinkat(dirfd(d), de->d_name, 0);
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
log_warning("Failed to remove /run/systemd/journal/streams/%s: %m",
de->d_name);
continue;
}

View file

@ -2010,7 +2010,7 @@ static void reset_scheduled_shutdown(Manager *m) {
m->shutdown_dry_run = false;
if (m->unlink_nologin) {
(void) unlink("/run/nologin");
(void) unlink_or_warn("/run/nologin");
m->unlink_nologin = false;
}

View file

@ -35,6 +35,7 @@
#include "dirent-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
#include "logind.h"
#include "process-util.h"
#include "selinux-util.h"
@ -183,7 +184,7 @@ static void manager_free(Manager *m) {
udev_unref(m->udev);
if (m->unlink_nologin)
(void) unlink("/run/nologin");
(void) unlink_or_warn("/run/nologin");
bus_verify_polkit_async_registry_free(m->polkit_registry);
@ -322,7 +323,9 @@ static int manager_enumerate_seats(Manager *m) {
s = hashmap_get(m->seats, de->d_name);
if (!s) {
unlinkat(dirfd(d), de->d_name, 0);
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
log_warning("Failed to remove /run/systemd/seats/%s: %m",
de->d_name);
continue;
}

View file

@ -209,7 +209,7 @@ static void backspace_string(int ttyfd, const char *str) {
if (ttyfd < 0)
return;
/* Backspaces back for enough characters to entirely undo printing of the specified string. */
/* Backspaces through enough characters to entirely undo printing of the specified string. */
m = utf8_n_codepoints(str);
if (m == (size_t) -1)

View file

@ -1021,3 +1021,119 @@ int config_parse_ip_port(
return 0;
}
int config_parse_join_controllers(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char ****ret = data;
const char *whole_rvalue = rvalue;
unsigned n = 0;
_cleanup_(strv_free_freep) char ***controllers = NULL;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(ret);
for (;;) {
_cleanup_free_ char *word = NULL;
char **l;
int r;
r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
return r;
}
if (r == 0)
break;
l = strv_split(word, ",");
if (!l)
return log_oom();
strv_uniq(l);
if (strv_length(l) <= 1) {
strv_free(l);
continue;
}
if (!controllers) {
controllers = new(char**, 2);
if (!controllers) {
strv_free(l);
return log_oom();
}
controllers[0] = l;
controllers[1] = NULL;
n = 1;
} else {
char ***a;
char ***t;
t = new0(char**, n+2);
if (!t) {
strv_free(l);
return log_oom();
}
n = 0;
for (a = controllers; *a; a++)
if (strv_overlap(*a, l)) {
if (strv_extend_strv(&l, *a, false) < 0) {
strv_free(l);
strv_free_free(t);
return log_oom();
}
} else {
char **c;
c = strv_copy(*a);
if (!c) {
strv_free(l);
strv_free_free(t);
return log_oom();
}
t[n++] = c;
}
t[n++] = strv_uniq(l);
strv_free_free(controllers);
controllers = t;
}
}
if (!isempty(rvalue))
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
/* As a special case, return a single empty strv, to override the default */
if (!controllers) {
controllers = new(char**, 2);
if (!controllers)
return log_oom();
controllers[0] = strv_new(NULL, NULL);
if (!controllers[0])
return log_oom();
controllers[1] = NULL;
}
strv_free_free(*ret);
*ret = controllers;
controllers = NULL;
return 0;
}

View file

@ -121,44 +121,46 @@ int config_parse_many(
void *userdata);
/* Generic parsers */
int config_parse_int(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unsigned(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_long(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_uint8(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_uint16(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_uint32(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_double(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_iec_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_iec_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_tristate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_signal(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_personality(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ifname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ip_port(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
#define GENERIC_PARSER_ARGS \
const char *unit, \
const char *filename, \
unsigned line, \
const char *section, \
unsigned section_line, \
const char *lvalue, \
int ltype, \
const char *rvalue, \
void *data, \
void *userdata
int config_parse_int(GENERIC_PARSER_ARGS);
int config_parse_unsigned(GENERIC_PARSER_ARGS);
int config_parse_long(GENERIC_PARSER_ARGS);
int config_parse_uint8(GENERIC_PARSER_ARGS);
int config_parse_uint16(GENERIC_PARSER_ARGS);
int config_parse_uint32(GENERIC_PARSER_ARGS);
int config_parse_uint64(GENERIC_PARSER_ARGS);
int config_parse_double(GENERIC_PARSER_ARGS);
int config_parse_iec_size(GENERIC_PARSER_ARGS);
int config_parse_si_size(GENERIC_PARSER_ARGS);
int config_parse_iec_uint64(GENERIC_PARSER_ARGS);
int config_parse_bool(GENERIC_PARSER_ARGS);
int config_parse_tristate(GENERIC_PARSER_ARGS);
int config_parse_string(GENERIC_PARSER_ARGS);
int config_parse_path(GENERIC_PARSER_ARGS);
int config_parse_strv(GENERIC_PARSER_ARGS);
int config_parse_sec(GENERIC_PARSER_ARGS);
int config_parse_nsec(GENERIC_PARSER_ARGS);
int config_parse_mode(GENERIC_PARSER_ARGS);
int config_parse_log_facility(GENERIC_PARSER_ARGS);
int config_parse_log_level(GENERIC_PARSER_ARGS);
int config_parse_signal(GENERIC_PARSER_ARGS);
int config_parse_personality(GENERIC_PARSER_ARGS);
int config_parse_ifname(GENERIC_PARSER_ARGS);
int config_parse_ip_port(GENERIC_PARSER_ARGS);
int config_parse_join_controllers(GENERIC_PARSER_ARGS);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
int function(const char *unit, \
const char *filename, \
unsigned line, \
const char *section, \
unsigned section_line, \
const char *lvalue, \
int ltype, \
const char *rvalue, \
void *data, \
void *userdata) { \
\
int function(GENERIC_PARSER_ARGS) { \
type *i = data, x; \
\
assert(filename); \
@ -177,17 +179,7 @@ int config_parse_ip_port(const char *unit, const char *filename, unsigned line,
}
#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
int function(const char *unit, \
const char *filename, \
unsigned line, \
const char *section, \
unsigned section_line, \
const char *lvalue, \
int ltype, \
const char *rvalue, \
void *data, \
void *userdata) { \
\
int function(GENERIC_PARSER_ARGS) { \
type **enums = data, x, *ys; \
_cleanup_free_ type *xs = NULL; \
const char *word, *state; \

View file

@ -226,6 +226,45 @@ static void test_config_parse_iec_uint64(void) {
assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
}
static void test_config_parse_join_controllers(void) {
int r;
_cleanup_(strv_free_freep) char ***c = NULL;
char ***c2;
/* Test normal operation */
r = config_parse_join_controllers(NULL, "example.conf", 11, "Section", 10, "JoinControllers", 0, "cpu,cpuacct net_cls,netprio", &c, NULL);
assert_se(r == 0);
assert_se(c);
assert_se(strv_length(c[0]) == 2);
assert_se(strv_equal(c[0], STRV_MAKE("cpu", "cpuacct")));
assert_se(strv_length(c[1]) == 2);
assert_se(strv_equal(c[1], STRV_MAKE("net_cls", "netprio")));
assert_se(c[2] == NULL);
/* Test special case of no mounted controllers */
r = config_parse_join_controllers(NULL, "example.conf", 12, "Section", 10, "JoinControllers", 0, "", &c, NULL);
assert_se(r == 0);
assert_se(c);
assert_se(strv_equal(c[0], STRV_MAKE_EMPTY));
assert_se(c[1] == NULL);
/* Test merging of overlapping lists */
r = config_parse_join_controllers(NULL, "example.conf", 13, "Section", 10, "JoinControllers", 0, "a,b b,c", &c, NULL);
assert_se(r == 0);
assert_se(c);
assert_se(strv_length(c[0]) == 3);
assert_se(strv_contains(c[0], "a"));
assert_se(strv_contains(c[0], "b"));
assert_se(strv_contains(c[0], "c"));
assert_se(c[1] == NULL);
/* Test ignoring of bad lines */
c2 = c;
r = config_parse_join_controllers(NULL, "example.conf", 14, "Section", 10, "JoinControllers", 0, "a,\"b ", &c, NULL);
assert_se(r < 0);
assert_se(c == c2);
}
#define x10(x) x x x x x x x x x x
#define x100(x) x10(x10(x))
#define x1000(x) x10(x100(x))
@ -365,6 +404,7 @@ int main(int argc, char **argv) {
test_config_parse_sec();
test_config_parse_nsec();
test_config_parse_iec_uint64();
test_config_parse_join_controllers();
for (i = 0; i < ELEMENTSOF(config_file); i++)
test_config_parse(i, config_file[i]);

View file

@ -100,7 +100,7 @@ static void test_get_process_comm(pid_t pid) {
if (!detect_container())
assert_se(get_ctty_devnr(pid, &h) == -ENXIO || pid != 1);
getenv_for_pid(pid, "PATH", &i);
(void) getenv_for_pid(pid, "PATH", &i);
log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
}

View file

@ -106,6 +106,15 @@ static void test_utf16_to_utf8(void) {
free(a);
}
static void test_utf8_n_codepoints(void) {
assert_se(utf8_n_codepoints("abc") == 3);
assert_se(utf8_n_codepoints("zażółcić gęślą jaźń") == 19);
assert_se(utf8_n_codepoints("") == 1);
assert_se(utf8_n_codepoints("") == 0);
assert_se(utf8_n_codepoints("…👊🔪💐…") == 5);
assert_se(utf8_n_codepoints("\xF1") == (size_t) -1);
}
int main(int argc, char *argv[]) {
test_utf8_is_valid();
test_utf8_is_printable();
@ -114,6 +123,7 @@ int main(int argc, char *argv[]) {
test_utf8_escaping();
test_utf8_escaping_printable();
test_utf16_to_utf8();
test_utf8_n_codepoints();
return 0;
}

View file

@ -79,7 +79,7 @@ void udev_watch_restore(struct udev *udev) {
udev_watch_begin(udev, dev);
udev_device_unref(dev);
unlink:
unlinkat(dirfd(dir), ent->d_name, 0);
(void) unlinkat(dirfd(dir), ent->d_name, 0);
}
closedir(dir);

View file

@ -23,12 +23,14 @@
#include "fileio.h"
#include "fileio-label.h"
#include "fs-util.h"
#include "log.h"
#include "selinux-util.h"
#include "string-util.h"
#include "util.h"
int main(int argc, char*argv[]) {
int r, k;
if (argc != 2) {
log_error("This program requires one argument.");
@ -44,30 +46,12 @@ int main(int argc, char*argv[]) {
mac_selinux_init();
if (streq(argv[1], "start")) {
int r = 0;
if (unlink("/run/nologin") < 0 && errno != ENOENT)
r = log_error_errno(errno,
"Failed to remove /run/nologin file: %m");
if (unlink("/etc/nologin") < 0 && errno != ENOENT) {
/* If the file doesn't exist and /etc simply
* was read-only (in which case unlink()
* returns EROFS even if the file doesn't
* exist), don't complain */
if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) {
log_error_errno(errno, "Failed to remove /etc/nologin file: %m");
return EXIT_FAILURE;
}
}
if (r < 0)
r = unlink_or_warn("/run/nologin");
k = unlink_or_warn("/etc/nologin");
if (r < 0 || k < 0)
return EXIT_FAILURE;
} else if (streq(argv[1], "stop")) {
int r;
r = write_string_file_atomic_label("/run/nologin", "System is going down.");
if (r < 0) {
log_error_errno(r, "Failed to create /run/nologin: %m");