Skip to content

Commit f5695d3

Browse files
committed
setfont: check whether console is suitable for font operations
Signed-off-by: Alexey Gladkov <legion@kernel.org>
1 parent 48b557d commit f5695d3

4 files changed

Lines changed: 60 additions & 7 deletions

File tree

src/include/kbd/kfont.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ int kfont_put_font(struct kfont_context *ctx, int consolefd, unsigned char *buf,
188188
unsigned int kfont_get_fontsize(struct kfont_context *ctx, int consolefd)
189189
KBD_ATTR_NONNULL(1);
190190

191+
/*
192+
* Check whether CONSOLEFD refers to a text-mode console suitable for
193+
* font operations through KDFONTOP. The check is silent and returns 1
194+
* if the console can be used, 0 otherwise.
195+
*/
196+
int kfont_is_font_console(struct kfont_context *ctx, int consolefd)
197+
KBD_ATTR_NONNULL(1);
198+
191199
/*
192200
* Restore font (doesn't work).
193201
*/

src/libkfont/kdfontop.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,30 @@
2121
#endif
2222

2323
static int
24-
is_kd_text(struct kfont_context *ctx, int fd)
24+
is_kd_text_mode(struct kfont_context *ctx, int fd, int report_errors)
2525
{
2626
unsigned int kd_mode;
2727

2828
if (ioctl(fd, KDGETMODE, &kd_mode)) {
29-
KFONT_ERR(ctx, "ioctl(KDGETMODE): %m");
29+
if (report_errors)
30+
KFONT_ERR(ctx, "ioctl(KDGETMODE): %m");
3031
return 0;
3132
}
3233

3334
if (kd_mode == KD_TEXT)
3435
return 1;
3536

36-
KFONT_ERR(ctx, _("Console is not in text mode"));
37+
if (report_errors)
38+
KFONT_ERR(ctx, _("Console is not in text mode"));
3739
return 0;
3840
}
3941

42+
static inline int
43+
is_kd_text(struct kfont_context *ctx, int fd)
44+
{
45+
return is_kd_text_mode(ctx, fd, 1);
46+
}
47+
4048
int
4149
kfont_restore_font(struct kfont_context *ctx, int fd)
4250
{
@@ -176,6 +184,27 @@ kfont_get_fontsize(struct kfont_context *ctx, int fd)
176184
return 256;
177185
}
178186

187+
int
188+
kfont_is_font_console(struct kfont_context *ctx, int fd)
189+
{
190+
if (!is_kd_text_mode(ctx, fd, 0))
191+
return 0;
192+
193+
struct console_font_op cfo = {
194+
.op = KD_FONT_OP_GET,
195+
.flags = 0,
196+
.width = 32,
197+
.height = 32,
198+
.charcount = (sizeof(unsigned char) * MAXFONTSIZE) / (64 * 128 / 8),
199+
.data = NULL,
200+
};
201+
202+
errno = 0;
203+
ioctl(fd, KDFONTOP, &cfo);
204+
205+
return (errno != ENOSYS && errno != ENOTTY);
206+
}
207+
179208
static int
180209
put_font_kdfontop(struct kfont_context *ctx, int consolefd, unsigned char *buf,
181210
unsigned int count,

src/libkfont/libkfont.map

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,12 @@ KFONT_1.0 {
3636
local:
3737
*;
3838
};
39+
40+
/*
41+
* symbols since kbd 2.9.0
42+
*/
43+
KFONT_2.9 {
44+
global:
45+
kfont_is_font_console;
46+
47+
} KFONT_1.0;

src/setfont.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,8 @@ int main(int argc, char *argv[])
166166
{
167167
const char *ifiles[MAXIFILES];
168168
char *mfil, *ufil, *Ofil, *ofil, *omfil, *oufil, *console;
169-
int ifilct = 0, fd, no_m, no_u;
169+
int ifilct, fd, no_m, no_u, restore, check_console, ret, c;
170170
unsigned int iunit, hwunit;
171-
int restore = 0;
172-
int ret, c;
173171

174172
struct kfont_context *kfont;
175173

@@ -183,6 +181,7 @@ int main(int argc, char *argv[])
183181
{ "-m, --consolemap <FILE>", _("load console screen map ('none' means don't load it).") },
184182
{ "-u, --unicodemap <FILE>", _("load font unicode map ('none' means don't load it).") },
185183
{ "-C, --console <DEV>", _("the console device to be used.") },
184+
{ "-c, --check", _("check whether console is suitable for font operations.") },
186185
{ "-d, --double", _("double size of font horizontally and vertically.") },
187186
{ "-f, --force", _("force load unicode map.") },
188187
{ "-R, --reset", _("reset the screen font, size, and unicode map to the bootup defaults.") },
@@ -193,6 +192,7 @@ int main(int argc, char *argv[])
193192
};
194193

195194
const struct kbd_option opts[] = {
195+
{ "=c", "check", kbd_no_argument, 'c' },
196196
{ "=d", "double", kbd_no_argument, 'd' },
197197
{ "=f", "force", kbd_no_argument, 'f' },
198198
{ "=R", "reset", kbd_no_argument, 'R' },
@@ -218,7 +218,8 @@ int main(int argc, char *argv[])
218218

219219
ifiles[0] = mfil = ufil = Ofil = ofil = omfil = oufil = NULL;
220220
iunit = hwunit = 0;
221-
no_m = no_u = 0;
221+
ifilct = no_m = no_u = 0;
222+
restore = check_console = 0;
222223
console = NULL;
223224

224225
while ((c = kbd_getopt(argc, argv, opts)) != -1) {
@@ -271,6 +272,9 @@ int main(int argc, char *argv[])
271272
case 'R':
272273
restore = 1;
273274
break;
275+
case 'c':
276+
check_console = 1;
277+
break;
274278
case 'd':
275279
kfont_set_option(kfont, kfont_double_size);
276280
break;
@@ -316,6 +320,9 @@ int main(int argc, char *argv[])
316320
if ((fd = getfd(console)) < 0)
317321
kbd_error(EX_OSERR, 0, _("Couldn't get a file descriptor referring to the console."));
318322

323+
if (check_console)
324+
return kfont_is_font_console(kfont, fd) ? EX_OK : EXIT_FAILURE;
325+
319326
int kd_mode = -1;
320327
if (!ioctl(fd, KDGETMODE, &kd_mode) && (kd_mode == KD_GRAPHICS)) {
321328
/*

0 commit comments

Comments
 (0)