From c2f2c51c53e91232e6f2aa686d734728ad703f9f Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: don't do GIO_SCRNMAP / GIO_UNISCRNMAP GIO_SCRNMAP / GIO_UNISCRNMAP are related to what setfont does with -m option - namely setting intermediate map from 8bit values into unicode values. This map is global, so single setfont invocation sets it for all applicable consoles. Furthermore calling GIO_SCRNMAP before GIO_UNISCRNMAP causes issues as the former corrupts values > 255 (UNI alone would be sufficient). The bug can be easily tested with the following conf: KEYMAP=pl FONT=LatArCyrHeb-16 FONT_MAP=8859-2 --- src/vconsole/vconsole-setup.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 1118118450..abf3871fd8 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -192,8 +192,6 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, */ static void font_copy_to_all_vcs(int fd) { struct vt_stat vcs = {}; - unsigned char map8[E_TABSZ]; - unsigned short map16[E_TABSZ]; struct unimapdesc unimapd; _cleanup_free_ struct unipair* unipairs = NULL; int i, r; @@ -234,14 +232,6 @@ static void font_copy_to_all_vcs(int fd) { cfo.height = vcs.v_active-1; /* tty1 == index 0 */ (void) ioctl(vcfd, KDFONTOP, &cfo); - /* copy map of 8bit chars */ - if (ioctl(fd, GIO_SCRNMAP, map8) >= 0) - (void) ioctl(vcfd, PIO_SCRNMAP, map8); - - /* copy map of 8bit chars -> 16bit Unicode values */ - if (ioctl(fd, GIO_UNISCRNMAP, map16) >= 0) - (void) ioctl(vcfd, PIO_UNISCRNMAP, map16); - /* copy unicode translation table */ /* unimapd is a ushort count and a pointer to an array of struct unipair { ushort, ushort } */ -- cgit v1.2.3-54-g00ecf From 9fa71843bbb31c89f81976819eec009335b09f2d Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: copy font to 63 consoles instead of 15 We copy only to allocated consoles, so the cost of looping over all possible ones is minuscule. --- src/vconsole/vconsole-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index abf3871fd8..df18c231e0 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -209,7 +209,7 @@ static void font_copy_to_all_vcs(int fd) { return; } - for (i = 1; i <= 15; i++) { + for (i = 1; i <= 63; i++) { char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)]; _cleanup_close_ int vcfd = -1; struct console_font_op cfo = {}; -- cgit v1.2.3-54-g00ecf From 042d7f5065c9c19b3f96804f9403b14d910e46d1 Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: add two new toggle functions, remove old enable/disable ones Add toggle_utf8() and toggle_utf8_sysfs() and use them in place of old enable/disable functions. toggle_utf8() also adds iutf8 setting and is set up to be called per-console (in subsequent patches). Note, that old disable_utf8() didn't bother checking if it was ok to change the kbdmode. --- src/vconsole/vconsole-setup.c | 73 ++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 46 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index df18c231e0..016cf004a0 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "alloc-util.h" @@ -50,56 +51,38 @@ static bool is_vconsole(int fd) { return ioctl(fd, TIOCLINUX, data) >= 0; } -static int disable_utf8(int fd) { - int r = 0, k; - - if (ioctl(fd, KDSKBMODE, K_XLATE) < 0) - r = -errno; - - k = loop_write(fd, "\033%@", 3, false); - if (k < 0) - r = k; - - k = write_string_file("/sys/module/vt/parameters/default_utf8", "0", 0); - if (k < 0) - r = k; +static int toggle_utf8(int fd, bool utf8) { + int r; + struct termios tc = {}; + r = ioctl(fd, KDSKBMODE, utf8 ? K_UNICODE : K_XLATE); if (r < 0) - log_warning_errno(r, "Failed to disable UTF-8: %m"); - - return r; -} + return log_warning_errno(errno, "Failed to %s UTF-8 kbdmode: %m", utf8 ? "enable" : "disable"); -static int enable_utf8(int fd) { - int r = 0, k; - long current = 0; - - if (ioctl(fd, KDGKBMODE, ¤t) < 0 || current == K_XLATE) { - /* - * Change the current keyboard to unicode, unless it - * is currently in raw or off mode anyway. We - * shouldn't interfere with X11's processing of the - * key events. - * - * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html - * - */ - - if (ioctl(fd, KDSKBMODE, K_UNICODE) < 0) - r = -errno; + r = loop_write(fd, utf8 ? "\033%G" : "\033%@", 3, false); + if (r < 0) + return log_warning_errno(r, "Failed to %s UTF-8 term processing: %m", utf8 ? "enable" : "disable"); + + r = tcgetattr(fd, &tc); + if (r >= 0) { + if (utf8) + tc.c_iflag |= IUTF8; + else + tc.c_iflag &= ~IUTF8; + r = tcsetattr(fd, TCSANOW, &tc); } + if (r < 0) + return log_warning_errno(errno, "Failed to %s iutf8 flag: %m", utf8 ? "enable" : "disable"); - k = loop_write(fd, "\033%G", 3, false); - if (k < 0) - r = k; + return 0; +} - k = write_string_file("/sys/module/vt/parameters/default_utf8", "1", 0); - if (k < 0) - r = k; +static int toggle_utf8_sysfs(bool utf8) { + int r; + r = write_string_file("/sys/module/vt/parameters/default_utf8", one_zero(utf8), 0); if (r < 0) - log_warning_errno(r, "Failed to enable UTF-8: %m"); - + log_warning_errno(r, "Failed to %s sysfs UTF-8 flag: %m", utf8 ? "enable" : "disable"); return r; } @@ -306,10 +289,8 @@ int main(int argc, char **argv) { log_warning_errno(r, "Failed to read /proc/cmdline: %m"); } - if (utf8) - (void) enable_utf8(fd); - else - (void) disable_utf8(fd); + toggle_utf8_sysfs(utf8); + toggle_utf8(fd, utf8); font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) > 0; keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) > 0; -- cgit v1.2.3-54-g00ecf From 03044059bfff8b79d47efc53e2468e122f502a72 Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: Add generic is_*() functions is_allocated() and is_allocated_byfd(): Checks if the console is allocated by its index (first function) or its open descriptor (second function). is_settable(): Checks if the console is in xlate or unicode mode, so we can adjust is safely without interfering with X. --- src/vconsole/vconsole-setup.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 016cf004a0..15e7ed39b4 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -51,6 +51,37 @@ static bool is_vconsole(int fd) { return ioctl(fd, TIOCLINUX, data) >= 0; } +static bool is_allocated(unsigned int idx) { + char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)]; + + xsprintf(vcname, "/dev/vcs%i", idx); + return access(vcname, F_OK) == 0; +} + +static bool is_allocated_byfd(int fd) { + struct vt_stat vcs = {}; + + if (ioctl(fd, VT_GETSTATE, &vcs) < 0) { + log_warning_errno(errno, "VT_GETSTATE failed: %m"); + return false; + } + return is_allocated(vcs.v_active); +} + +static bool is_settable(int fd) { + int r, curr_mode; + + r = ioctl(fd, KDGKBMODE, &curr_mode); + /* + * Make sure we only adjust consoles in K_XLATE or K_UNICODE mode. + * Oterwise we would (likely) interfere with X11's processing of the + * key events. + * + * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html + */ + return r == 0 && IN_SET(curr_mode, K_XLATE, K_UNICODE); +} + static int toggle_utf8(int fd, bool utf8) { int r; struct termios tc = {}; @@ -262,6 +293,16 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } + if (!is_allocated_byfd(fd)) { + log_error("Virtual console %s is not allocated.", vc); + return EXIT_FAILURE; + } + + if (!is_settable(fd)) { + log_error("Virtual console %s is not in K_XLATE or K_UNICODE.", vc); + return EXIT_FAILURE; + } + utf8 = is_locale_utf8(); r = parse_env_file("/etc/vconsole.conf", NEWLINE, -- cgit v1.2.3-54-g00ecf From c9d2b3d0f00a00049aeb8a6dba78200e6df48244 Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: updates of keyboard/font loading functions Change return convention to -errno/==0 and use isempty() instead of just pointer tests. --- src/vconsole/vconsole-setup.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 15e7ed39b4..c98c699922 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -119,12 +119,12 @@ static int toggle_utf8_sysfs(bool utf8) { static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) { const char *args[8]; - int i = 0, r; + int i = 0; pid_t pid; /* An empty map means kernel map */ if (isempty(map)) - return 1; + return 0; args[i++] = KBD_LOADKEYS; args[i++] = "-q"; @@ -149,34 +149,31 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m _exit(EXIT_FAILURE); } - r = wait_for_terminate_and_warn(KBD_LOADKEYS, pid, true); - if (r < 0) - return r; - - return r == 0; + return wait_for_terminate_and_warn(KBD_LOADKEYS, pid, true); } static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) { const char *args[9]; - int i = 0, r; + int i = 0; pid_t pid; - /* An empty font means kernel font */ - if (isempty(font)) - return 1; + /* Any part can be set independently */ + if (isempty(font) && isempty(map) && isempty(unimap)) + return 0; args[i++] = KBD_SETFONT; args[i++] = "-C"; args[i++] = vc; - args[i++] = font; - if (map) { + if (!isempty(map)) { args[i++] = "-m"; args[i++] = map; } - if (unimap) { + if (!isempty(unimap)) { args[i++] = "-u"; args[i++] = unimap; } + if (!isempty(font)) + args[i++] = font; args[i++] = NULL; pid = fork(); @@ -191,11 +188,7 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, _exit(EXIT_FAILURE); } - r = wait_for_terminate_and_warn(KBD_SETFONT, pid, true); - if (r < 0) - return r; - - return r == 0; + return wait_for_terminate_and_warn(KBD_SETFONT, pid, true); } /* @@ -333,8 +326,8 @@ int main(int argc, char **argv) { toggle_utf8_sysfs(utf8); toggle_utf8(fd, utf8); - font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) > 0; - keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) > 0; + font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0; + keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0; /* Only copy the font when we executed setfont successfully */ if (font_copy && font_ok) -- cgit v1.2.3-54-g00ecf From eb22d84b47f16bedb60824b441900715fd79841d Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: use KD_FONT_OP_GET/SET to handle copying We now use KD_FONT_OP_GET & KD_FONT_OP_SET instead of problematic KD_FONT_OP_COPY. --- src/vconsole/vconsole-setup.c | 93 ++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 27 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index c98c699922..5da807bf17 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -196,11 +196,21 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, * we update all possibly already allocated VTs with the configured * font. It also allows to restart systemd-vconsole-setup.service, * to apply a new font to all VTs. + * + * We also setup per-console utf8 related stuff: kbdmode, term + * processing, stty iutf8. */ -static void font_copy_to_all_vcs(int fd) { +static void setup_remaining_vcs(int fd, bool utf8) { + struct console_font_op cfo = { + .op = KD_FONT_OP_GET, .flags = 0, + .width = 32, .height = 32, + .charcount = 512, + }; struct vt_stat vcs = {}; + struct unimapinit adv = {}; struct unimapdesc unimapd; _cleanup_free_ struct unipair* unipairs = NULL; + _cleanup_free_ void *fontbuf = NULL; int i, r; unipairs = new(struct unipair, USHRT_MAX); @@ -209,46 +219,73 @@ static void font_copy_to_all_vcs(int fd) { return; } + fontbuf = malloc(cfo.width * cfo.height * cfo.charcount / 8); + if (!fontbuf) { + log_oom(); + return; + } + /* get active, and 16 bit mask of used VT numbers */ r = ioctl(fd, VT_GETSTATE, &vcs); if (r < 0) { - log_debug_errno(errno, "VT_GETSTATE failed, ignoring: %m"); + log_warning_errno(errno, "VT_GETSTATE failed, ignoring remaining consoles: %m"); return; } + /* get fonts from source console */ + cfo.data = fontbuf; + r = ioctl(fd, KDFONTOP, &cfo); + if (r < 0) + log_warning_errno(errno, "KD_FONT_OP_GET failed, fonts will not be copied: %m"); + else { + unimapd.entries = unipairs; + unimapd.entry_ct = USHRT_MAX; + r = ioctl(fd, GIO_UNIMAP, &unimapd); + if (r < 0) + log_warning_errno(errno, "GIO_UNIMAP failed, fonts will not be copied: %m"); + else + cfo.op = KD_FONT_OP_SET; + } + for (i = 1; i <= 63; i++) { - char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)]; - _cleanup_close_ int vcfd = -1; - struct console_font_op cfo = {}; + char ttyname[strlen("/dev/tty") + DECIMAL_STR_MAX(int)]; + _cleanup_close_ int fd_d = -1; - if (i == vcs.v_active) + if (i == vcs.v_active || !is_allocated(i)) continue; - /* skip non-allocated ttys */ - xsprintf(vcname, "/dev/vcs%i", i); - if (access(vcname, F_OK) < 0) + /* try to open terminal */ + xsprintf(ttyname, "/dev/tty%i", i); + fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC); + if (fd_d < 0) { + log_warning_errno(fd_d, "Unable to open tty%i, fonts will not be copied: %m", i); continue; + } - xsprintf(vcname, "/dev/tty%i", i); - vcfd = open_terminal(vcname, O_RDWR|O_CLOEXEC); - if (vcfd < 0) + if (!is_settable(fd_d)) continue; - /* copy font from active VT, where the font was uploaded to */ - cfo.op = KD_FONT_OP_COPY; - cfo.height = vcs.v_active-1; /* tty1 == index 0 */ - (void) ioctl(vcfd, KDFONTOP, &cfo); + toggle_utf8(fd_d, utf8); + + if (cfo.op != KD_FONT_OP_SET) + continue; + + r = ioctl(fd_d, KDFONTOP, &cfo); + if (r < 0) { + log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%i: %m", i); + continue; + } /* copy unicode translation table */ /* unimapd is a ushort count and a pointer to an array of struct unipair { ushort, ushort } */ - unimapd.entries = unipairs; - unimapd.entry_ct = USHRT_MAX; - if (ioctl(fd, GIO_UNIMAP, &unimapd) >= 0) { - struct unimapinit adv = { 0, 0, 0 }; - - (void) ioctl(vcfd, PIO_UNIMAPCLR, &adv); - (void) ioctl(vcfd, PIO_UNIMAP, &unimapd); + r = ioctl(fd_d, PIO_UNIMAPCLR, &adv); + if (r < 0) + log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%i: %m", i); + else { + r = ioctl(fd_d, PIO_UNIMAP, &unimapd); + if (r < 0) + log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i); } } } @@ -325,13 +362,15 @@ int main(int argc, char **argv) { toggle_utf8_sysfs(utf8); toggle_utf8(fd, utf8); - font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0; keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0; - /* Only copy the font when we executed setfont successfully */ - if (font_copy && font_ok) - (void) font_copy_to_all_vcs(fd); + if (font_copy) { + if (font_ok) + setup_remaining_vcs(fd, utf8); + else + log_warning("Setting source virtual console failed, ignoring remaining ones."); + } return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE; } -- cgit v1.2.3-54-g00ecf From af7a5213f13051b5c399787d8a88ab640382192c Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: add copyright line --- src/vconsole/vconsole-setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 5da807bf17..a8f4f05771 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -2,6 +2,7 @@ This file is part of systemd. Copyright 2010 Kay Sievers + Copyright 2016 Michal Soltys 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 -- cgit v1.2.3-54-g00ecf From 9e303250acafe284a3406b71dbe9a7620ee71fcc Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 27 Jul 2016 00:57:01 +0200 Subject: vconsole: correct kernel command line namespace --- src/vconsole/vconsole-setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index a8f4f05771..59e6c90c9a 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -351,8 +351,12 @@ int main(int argc, char **argv) { if (detect_container() <= 0) { r = parse_env_file("/proc/cmdline", WHITESPACE, "vconsole.keymap", &vc_keymap, - "vconsole.keymap.toggle", &vc_keymap_toggle, + "vconsole.keymap_toggle", &vc_keymap_toggle, "vconsole.font", &vc_font, + "vconsole.font_map", &vc_font_map, + "vconsole.font_unimap", &vc_font_unimap, + /* compatibility with obsolete multiple-dot scheme */ + "vconsole.keymap.toggle", &vc_keymap_toggle, "vconsole.font.map", &vc_font_map, "vconsole.font.unimap", &vc_font_unimap, NULL); -- cgit v1.2.3-54-g00ecf From aaa709bbaa6b909278f3ec0679b49a484423d913 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 24 Jul 2016 14:14:20 -0400 Subject: vconsole-setup: add lots of debug messages For error messages, make them more meaningful by printing the tty name. Follow-up for #3742. --- src/vconsole/vconsole-setup.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 59e6c90c9a..c0d76f9685 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -83,17 +83,19 @@ static bool is_settable(int fd) { return r == 0 && IN_SET(curr_mode, K_XLATE, K_UNICODE); } -static int toggle_utf8(int fd, bool utf8) { +static int toggle_utf8(const char *name, int fd, bool utf8) { int r; struct termios tc = {}; + assert(name); + r = ioctl(fd, KDSKBMODE, utf8 ? K_UNICODE : K_XLATE); if (r < 0) - return log_warning_errno(errno, "Failed to %s UTF-8 kbdmode: %m", utf8 ? "enable" : "disable"); + return log_warning_errno(errno, "Failed to %s UTF-8 kbdmode on %s: %m", enable_disable(utf8), name); r = loop_write(fd, utf8 ? "\033%G" : "\033%@", 3, false); if (r < 0) - return log_warning_errno(r, "Failed to %s UTF-8 term processing: %m", utf8 ? "enable" : "disable"); + return log_warning_errno(r, "Failed to %s UTF-8 term processing on %s: %m", enable_disable(utf8), name); r = tcgetattr(fd, &tc); if (r >= 0) { @@ -104,8 +106,9 @@ static int toggle_utf8(int fd, bool utf8) { r = tcsetattr(fd, TCSANOW, &tc); } if (r < 0) - return log_warning_errno(errno, "Failed to %s iutf8 flag: %m", utf8 ? "enable" : "disable"); + return log_warning_errno(errno, "Failed to %s iutf8 flag on %s: %m", enable_disable(utf8), name); + log_debug("UTF-8 kbdmode %sd on %s", enable_disable(utf8), name); return 0; } @@ -114,8 +117,10 @@ static int toggle_utf8_sysfs(bool utf8) { r = write_string_file("/sys/module/vt/parameters/default_utf8", one_zero(utf8), 0); if (r < 0) - log_warning_errno(r, "Failed to %s sysfs UTF-8 flag: %m", utf8 ? "enable" : "disable"); - return r; + return log_warning_errno(r, "Failed to %s sysfs UTF-8 flag: %m", enable_disable(utf8)); + + log_debug("Sysfs UTF-8 flag %sd", enable_disable(utf8)); + return 0; } static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) { @@ -266,7 +271,7 @@ static void setup_remaining_vcs(int fd, bool utf8) { if (!is_settable(fd_d)) continue; - toggle_utf8(fd_d, utf8); + toggle_utf8(ttyname, fd_d, utf8); if (cfo.op != KD_FONT_OP_SET) continue; @@ -281,13 +286,18 @@ static void setup_remaining_vcs(int fd, bool utf8) { /* unimapd is a ushort count and a pointer to an array of struct unipair { ushort, ushort } */ r = ioctl(fd_d, PIO_UNIMAPCLR, &adv); - if (r < 0) + if (r < 0) { log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%i: %m", i); - else { - r = ioctl(fd_d, PIO_UNIMAP, &unimapd); - if (r < 0) - log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i); + continue; } + + r = ioctl(fd_d, PIO_UNIMAP, &unimapd); + if (r < 0) { + log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i); + continue; + } + + log_debug("Font and unimap successfully copied to %s", ttyname); } } @@ -366,7 +376,7 @@ int main(int argc, char **argv) { } toggle_utf8_sysfs(utf8); - toggle_utf8(fd, utf8); + toggle_utf8(vc, fd, utf8); font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0; keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0; @@ -374,7 +384,7 @@ int main(int argc, char **argv) { if (font_ok) setup_remaining_vcs(fd, utf8); else - log_warning("Setting source virtual console failed, ignoring remaining ones."); + log_warning("Setting source virtual console failed, ignoring remaining ones"); } return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE; -- cgit v1.2.3-54-g00ecf From d23a0044a3ba9ebff5e4e304152fd24ecf113524 Mon Sep 17 00:00:00 2001 From: Torstein Husebø Date: Mon, 26 Sep 2016 11:32:47 +0200 Subject: treewide: fix typos (#4217) --- man/systemd.netdev.xml | 2 +- src/nspawn/nspawn.c | 2 +- src/vconsole/vconsole-setup.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index c8b5a057f8..68ebd5c9f4 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -329,7 +329,7 @@ AgeingTimeSec= This specifies the number of seconds a MAC Address will be kept in - the forwaring database after having a packet received from this MAC Address. + the forwarding database after having a packet received from this MAC Address. diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0d61d34ebf..5e0207adf0 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1222,7 +1222,7 @@ static int setup_timezone(const char *dest) { if (r < 0) { log_warning("host's /etc/localtime is not a symlink, not updating container timezone."); /* to handle warning, delete /etc/localtime and replace it - * it /w a symbolic link to a time zone data file. + * with a symbolic link to a time zone data file. * * Example: * ln -s /usr/share/zoneinfo/UTC /etc/localtime diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index c0d76f9685..ac4ceb1486 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -75,7 +75,7 @@ static bool is_settable(int fd) { r = ioctl(fd, KDGKBMODE, &curr_mode); /* * Make sure we only adjust consoles in K_XLATE or K_UNICODE mode. - * Oterwise we would (likely) interfere with X11's processing of the + * Otherwise we would (likely) interfere with X11's processing of the * key events. * * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html -- cgit v1.2.3-54-g00ecf From 5297577f2748cef98486161b86d9c37312d4470b Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Wed, 12 Oct 2016 18:20:50 +0200 Subject: vconsole: setup_remaining_vcs() - more sanity checks Check if values filled up by KD_FONT_OP_GET ioctl make sense - dummy driver for example doesn't implement required functionality at all. --- src/vconsole/vconsole-setup.c | 59 +++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'src/vconsole/vconsole-setup.c') diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index ac4ceb1486..185b041a1c 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -208,9 +208,9 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, */ static void setup_remaining_vcs(int fd, bool utf8) { struct console_font_op cfo = { - .op = KD_FONT_OP_GET, .flags = 0, - .width = 32, .height = 32, - .charcount = 512, + .op = KD_FONT_OP_GET, + .width = UINT_MAX, .height = UINT_MAX, + .charcount = UINT_MAX, }; struct vt_stat vcs = {}; struct unimapinit adv = {}; @@ -225,12 +225,6 @@ static void setup_remaining_vcs(int fd, bool utf8) { return; } - fontbuf = malloc(cfo.width * cfo.height * cfo.charcount / 8); - if (!fontbuf) { - log_oom(); - return; - } - /* get active, and 16 bit mask of used VT numbers */ r = ioctl(fd, VT_GETSTATE, &vcs); if (r < 0) { @@ -238,19 +232,46 @@ static void setup_remaining_vcs(int fd, bool utf8) { return; } - /* get fonts from source console */ - cfo.data = fontbuf; + /* get metadata of the current font (width, height, count) */ r = ioctl(fd, KDFONTOP, &cfo); if (r < 0) - log_warning_errno(errno, "KD_FONT_OP_GET failed, fonts will not be copied: %m"); + log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m"); else { - unimapd.entries = unipairs; - unimapd.entry_ct = USHRT_MAX; - r = ioctl(fd, GIO_UNIMAP, &unimapd); - if (r < 0) - log_warning_errno(errno, "GIO_UNIMAP failed, fonts will not be copied: %m"); - else - cfo.op = KD_FONT_OP_SET; + /* sanitize parameters first */ + if (cfo.width > 32 || cfo.height > 32 || cfo.charcount > 512) + log_warning("Invalid font metadata - width: %u (max 32), height: %u (max 32), count: %u (max 512)", + cfo.width, cfo.height, cfo.charcount); + else { + /* + * Console fonts supported by the kernel are limited in size to 32 x 32 and maximum 512 + * characters. Thus with 1 bit per pixel it requires up to 65536 bytes. The height always + * requries 32 per glyph, regardless of the actual height - see the comment above #define + * max_font_size 65536 in drivers/tty/vt/vt.c for more details. + */ + fontbuf = malloc((cfo.width + 7) / 8 * 32 * cfo.charcount); + if (!fontbuf) { + log_oom(); + return; + } + /* get fonts from source console */ + cfo.data = fontbuf; + r = ioctl(fd, KDFONTOP, &cfo); + if (r < 0) + log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to read the font data: %m"); + else { + unimapd.entries = unipairs; + unimapd.entry_ct = USHRT_MAX; + r = ioctl(fd, GIO_UNIMAP, &unimapd); + if (r < 0) + log_warning_errno(errno, "GIO_UNIMAP failed while trying to read unicode mappings: %m"); + else + cfo.op = KD_FONT_OP_SET; + } + } + } + + if (cfo.op != KD_FONT_OP_SET) { + log_warning("Fonts will not be copied to remaining consoles"); } for (i = 1; i <= 63; i++) { -- cgit v1.2.3-54-g00ecf