+/*
+ * A newly allocated VT uses the font from the active VT. Here
+ * 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.
+ */
+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;
+ struct unipair unipairs[USHRT_MAX];
+ int i, r;
+
+ /* get active, and 16 bit mask of used VT numbers */
+ r = ioctl(fd, VT_GETSTATE, &vcs);
+ if (r < 0)
+ return;
+
+ for (i = 1; i <= 15; i++) {
+ char vcname[16];
+ _cleanup_close_ int vcfd = -1;
+ struct console_font_op cfo = {};
+
+ if (i == vcs.v_active)
+ continue;
+
+ /* skip non-allocated ttys */
+ snprintf(vcname, sizeof(vcname), "/dev/vcs%i", i);
+ if (access(vcname, F_OK) < 0)
+ continue;
+
+ snprintf(vcname, sizeof(vcname), "/dev/tty%i", i);
+ vcfd = open_terminal(vcname, O_RDWR|O_CLOEXEC);
+ if (vcfd < 0)
+ 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 */
+ ioctl(vcfd, KDFONTOP, &cfo);
+
+ /* copy map of 8bit chars */
+ if (ioctl(fd, GIO_SCRNMAP, map8) >= 0)
+ ioctl(vcfd, PIO_SCRNMAP, map8);
+
+ /* copy map of 8bit chars -> 16bit Unicode values */
+ if (ioctl(fd, GIO_UNISCRNMAP, map16) >= 0)
+ 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 } */
+ unimapd.entries = unipairs;
+ unimapd.entry_ct = USHRT_MAX;
+ if (ioctl(fd, GIO_UNIMAP, &unimapd) >= 0) {
+ struct unimapinit adv = { 0, 0, 0 };
+
+ ioctl(vcfd, PIO_UNIMAPCLR, &adv);
+ ioctl(vcfd, PIO_UNIMAP, &unimapd);
+ }
+ }
+}
+