Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-11 Thread Samuel Thibault
Zhang Boyang, le ven. 10 juin 2022 17:00:16 +0900, a ecrit:
> Here is a patch for another bug. Please refer to the commit message for
> details.

Applied, thanks for your patches!

Samuel



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-10 Thread Zhang Boyang

Hello,

Here is a patch for another bug. Please refer to the commit message for 
details.


Sorry to disturb you again. 

Best Regards,
Zhang BoyangFrom d569b4fbc4233673032a1c5f7463890d5e2223dd Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Fri, 10 Jun 2022 15:16:33 +0800
Subject: [PATCH v6] Fix crash caused by invalid term->yorig

The SCR(x, y) may return negative value if term->yorig is negative or
too large, causing memory corruption and crash. There are two ways to
trigger this bug.

1) When scrolling up, term->yorig is decremented by one. If term->yorig
   is zero, it can be -1 after the decrement, so SCR(0, 0) will become
   negative, causing crash. Below is the test command:

   bterm -f myfont.bgf -- python3 -c 'print("hello\033Mworld"); input("OK!")'

2) When scrolling down, term->yorig is incremented by one. There is no
   check for integer overflow. When term->yorig is large enough, the
   calculation in SCR(x, y) will overflow and it will return negative
   value, causing crash. Below is the test command:

   bterm -f myfont.bgf -- python3 -c 'print("\n"*22); input("OK!")'

This patch fixes the problem by limiting term->yorig to [0, term->ysize)
so there will be no negative value or overflow anymore.
---
 bogl-term.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bogl-term.c b/bogl-term.c
index 2d35d1d..f7fd735 100644
--- a/bogl-term.c
+++ b/bogl-term.c
@@ -188,7 +188,7 @@ cursor_down (struct bogl_term *term)
 }
 
 dirty_scroll(term);
-++term->yorig;
+term->yorig = (term->yorig + 1) % term->ysize;
 
 for (i = 0; i < term->xsize; i++)
 {
@@ -464,7 +464,7 @@ bogl_term_out (struct bogl_term *term, char *s, int n)
 
 /* Move all other lines down.  Fortunately, this is easy.  */
 dirty_backscroll(term);
-term->yorig--;
+term->yorig = (term->yorig - 1 + term->ysize) % term->ysize;
 
 /* Clear the top line.  */
 for (i = SCR (0, 0); i < SCR (term->xsize, 0); i++)
-- 
2.30.2



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-08 Thread Samuel Thibault
Hello,

Applied, thanks!

Samuel

Zhang Boyang, le mer. 08 juin 2022 17:09:29 +0900, a ecrit:
> Hi,
> 
> Changes in [PATCH v5]:
> 
> Fix-incorrect-signal-handling.patch:
>   Fix compiler warnings about implicit declaration of bogl_signal().
> 
> Font-scaler.patch
>   Use a lookup table to speed up font scaling.
> 
> ===
> 
> I'm sorry for sending a lot of emails to you, but I think this email is
> probably the last one of this email series. :-)
> 
> Best Regards,
> Zhang Boyang

> From 7d399b7223bc194c0b61aab8c6bd252fd0d43ded Mon Sep 17 00:00:00 2001
> From: Zhang Boyang 
> Date: Tue, 24 May 2022 12:58:01 +0800
> Subject: [PATCH v5 2/4] Fix incorrect signal handling
> 
> There are problems in signal handlers. Signal handlers must not call any
> non-async-signal-safe functions, and they must save-restore errno if
> errno is modified inside signal handlers. This patch fixes these
> problems by deferring real tasks to main loop. This patch also
> introduces bogl_signal(), which wraps around sigaction() thus signal
> handlers can be installed in a portable way. Since signal related
> problems are fixed, the previously temporarily disabled font unmapping
> is now re-enabled.
> ---
>  bogl.c  | 50 +-
>  bogl.h  |  2 ++
>  boglP.h |  2 ++
>  bterm.c | 36 ++--
>  4 files changed, 55 insertions(+), 35 deletions(-)
> 
> diff --git a/bogl.c b/bogl.c
> index 6b9996b..86bc1e0 100644
> --- a/bogl.c
> +++ b/bogl.c
> @@ -65,6 +65,7 @@
>  /* Global variables. */
>  int bogl_xres, bogl_yres, bogl_bpp;  /* bogl.h */
>  int bogl_refresh;
> +volatile int vt_switch_pending = 0;
>  volatile char *bogl_frame;   /* boglP.h */
>  int bogl_drawing;
>  int bogl_line_len;
> @@ -120,7 +121,7 @@ static void draw_disable (void);
>  static void kbd_init (void);
>  static void kbd_done (void);
>  
> -static void vt_switch (int);
> +static void sigusr2 (int);
>  
>  static struct fb_fix_screeninfo fb_fix;
>  /* Initialize BOGL. */
> @@ -181,7 +182,7 @@ bogl_init (void)
>mode.relsig = SIGUSR2;
>mode.acqsig = SIGUSR2;
>  
> -  signal (SIGUSR2, vt_switch);
> +  bogl_signal (SIGUSR2, sigusr2);
>  
>if (-1 == ioctl (tty, VT_SETMODE, ))
>  return bogl_fail ("can't set VT mode: %s", strerror (errno));
> @@ -295,7 +296,7 @@ bogl_done (void)
>  
>munmap ((void *) bogl_frame, fb_fix.smem_len);
>
> -  signal (SIGUSR2, SIG_DFL);
> +  bogl_signal (SIGUSR2, SIG_DFL);
>  
>ioctl (tty, KDSETMODE, KD_TEXT);
>  
> @@ -583,32 +584,18 @@ draw_disable (void)
>  /* Signal handler called whenever the kernel wants to switch to or
> from our tty. */
>  static void
> -vt_switch (int sig unused)
> +sigusr2 (int sig unused)
>  {
> -  signal (SIGUSR2, vt_switch);
> +  vt_switch_pending = 1;
> +}
> +void
> +vt_switch (void)
> +{
> +  vt_switch_pending = 0;
>  
> -  /* If a BOGL drawing function is in progress then we cannot mode
> - switch right now because the drawing function would continue to
> - scribble on the screen after the switch.  So disable further
> - drawing and schedule an alarm to try again in .1 second. */
>if (bogl_drawing)
>  {
> -  draw_disable ();
> -
> -  signal (SIGALRM, vt_switch);
> -  
> -  {
> - struct itimerval duration;
> - 
> - duration.it_interval.tv_sec = 0;
> - duration.it_interval.tv_usec = 0;
> - duration.it_value.tv_sec = 0;
> - duration.it_value.tv_usec = 10;
> - if (-1 == setitimer (ITIMER_REAL, , NULL))
> -   bogl_fail ("can't set timer: %s", strerror (errno));
> -  }
> -  
> -  return;
> +  abort();
>  }
>
>if (visible)
> @@ -666,3 +653,16 @@ bogl_cloexec(int fd)
>  
>return 0;
>  }
> +
> +/* Install signal handler in a portable way (i.e. sigaction wrapper) */
> +int
> +bogl_signal(int signum, void (*handler) (int))
> +{
> +  struct sigaction sa;
> +
> +  sa.sa_handler = handler;
> +  sigemptyset (_mask);
> +  sa.sa_flags = SA_RESTART;
> +
> +  return sigaction (signum, , NULL);
> +}
> diff --git a/bogl.h b/bogl.h
> index 3b2cb83..4d99788 100644
> --- a/bogl.h
> +++ b/bogl.h
> @@ -69,6 +69,8 @@ extern int bogl_xres, bogl_yres, bogl_ncols;
>  
>  /* 1=Must refresh screen due to tty change. */
>  extern int bogl_refresh;
> +extern volatile int vt_switch_pending;
> +extern void vt_switch (void);
>  
>  /* Generic routines. */
>  int bogl_init (void);
> diff --git a/boglP.h b/boglP.h
> index be99979..9a2b4aa 100644
> --- a/boglP.h
> +++ b/boglP.h
> @@ -27,4 +27,6 @@ int bogl_fail (const char *, ...);
>  
>  int bogl_cloexec (int fd);
>  
> +int bogl_signal (int signum, void (*handler) (int));
> +
>  #endif /* boglP_h */
> diff --git a/bterm.c b/bterm.c
> index dfae8b9..e86a748 100644
> --- a/bterm.c
> +++ b/bterm.c
> @@ -39,6 +39,7 @@
>  #include 
>  
>  #include "bogl.h"
> +#include "boglP.h"
>  #include "bogl-bgf.h"
>  #include "bogl-term.h"
>  
> @@ -160,7 +161,6 @@ void sigchld(int sig)
>

Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-08 Thread Zhang Boyang

Hi,

Changes in [PATCH v5]:

Fix-incorrect-signal-handling.patch:
  Fix compiler warnings about implicit declaration of bogl_signal().

Font-scaler.patch
  Use a lookup table to speed up font scaling.

===

I'm sorry for sending a lot of emails to you, but I think this email is 
probably the last one of this email series. :-)


Best Regards,
Zhang BoyangFrom 7d399b7223bc194c0b61aab8c6bd252fd0d43ded Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Tue, 24 May 2022 12:58:01 +0800
Subject: [PATCH v5 2/4] Fix incorrect signal handling

There are problems in signal handlers. Signal handlers must not call any
non-async-signal-safe functions, and they must save-restore errno if
errno is modified inside signal handlers. This patch fixes these
problems by deferring real tasks to main loop. This patch also
introduces bogl_signal(), which wraps around sigaction() thus signal
handlers can be installed in a portable way. Since signal related
problems are fixed, the previously temporarily disabled font unmapping
is now re-enabled.
---
 bogl.c  | 50 +-
 bogl.h  |  2 ++
 boglP.h |  2 ++
 bterm.c | 36 ++--
 4 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/bogl.c b/bogl.c
index 6b9996b..86bc1e0 100644
--- a/bogl.c
+++ b/bogl.c
@@ -65,6 +65,7 @@
 /* Global variables. */
 int bogl_xres, bogl_yres, bogl_bpp;	/* bogl.h */
 int bogl_refresh;
+volatile int vt_switch_pending = 0;
 volatile char *bogl_frame;		/* boglP.h */
 int bogl_drawing;
 int bogl_line_len;
@@ -120,7 +121,7 @@ static void draw_disable (void);
 static void kbd_init (void);
 static void kbd_done (void);
 
-static void vt_switch (int);
+static void sigusr2 (int);
 
 static struct fb_fix_screeninfo fb_fix;
 /* Initialize BOGL. */
@@ -181,7 +182,7 @@ bogl_init (void)
   mode.relsig = SIGUSR2;
   mode.acqsig = SIGUSR2;
 
-  signal (SIGUSR2, vt_switch);
+  bogl_signal (SIGUSR2, sigusr2);
 
   if (-1 == ioctl (tty, VT_SETMODE, ))
 return bogl_fail ("can't set VT mode: %s", strerror (errno));
@@ -295,7 +296,7 @@ bogl_done (void)
 
   munmap ((void *) bogl_frame, fb_fix.smem_len);
   
-  signal (SIGUSR2, SIG_DFL);
+  bogl_signal (SIGUSR2, SIG_DFL);
 
   ioctl (tty, KDSETMODE, KD_TEXT);
 
@@ -583,32 +584,18 @@ draw_disable (void)
 /* Signal handler called whenever the kernel wants to switch to or
from our tty. */
 static void
-vt_switch (int sig unused)
+sigusr2 (int sig unused)
 {
-  signal (SIGUSR2, vt_switch);
+  vt_switch_pending = 1;
+}
+void
+vt_switch (void)
+{
+  vt_switch_pending = 0;
 
-  /* If a BOGL drawing function is in progress then we cannot mode
- switch right now because the drawing function would continue to
- scribble on the screen after the switch.  So disable further
- drawing and schedule an alarm to try again in .1 second. */
   if (bogl_drawing)
 {
-  draw_disable ();
-
-  signal (SIGALRM, vt_switch);
-  
-  {
-	struct itimerval duration;
-	
-	duration.it_interval.tv_sec = 0;
-	duration.it_interval.tv_usec = 0;
-	duration.it_value.tv_sec = 0;
-	duration.it_value.tv_usec = 10;
-	if (-1 == setitimer (ITIMER_REAL, , NULL))
-	  bogl_fail ("can't set timer: %s", strerror (errno));
-  }
-  
-  return;
+  abort();
 }
   
   if (visible)
@@ -666,3 +653,16 @@ bogl_cloexec(int fd)
 
   return 0;
 }
+
+/* Install signal handler in a portable way (i.e. sigaction wrapper) */
+int
+bogl_signal(int signum, void (*handler) (int))
+{
+  struct sigaction sa;
+
+  sa.sa_handler = handler;
+  sigemptyset (_mask);
+  sa.sa_flags = SA_RESTART;
+
+  return sigaction (signum, , NULL);
+}
diff --git a/bogl.h b/bogl.h
index 3b2cb83..4d99788 100644
--- a/bogl.h
+++ b/bogl.h
@@ -69,6 +69,8 @@ extern int bogl_xres, bogl_yres, bogl_ncols;
 
 /* 1=Must refresh screen due to tty change. */
 extern int bogl_refresh;
+extern volatile int vt_switch_pending;
+extern void vt_switch (void);
 
 /* Generic routines. */
 int bogl_init (void);
diff --git a/boglP.h b/boglP.h
index be99979..9a2b4aa 100644
--- a/boglP.h
+++ b/boglP.h
@@ -27,4 +27,6 @@ int bogl_fail (const char *, ...);
 
 int bogl_cloexec (int fd);
 
+int bogl_signal (int signum, void (*handler) (int));
+
 #endif /* boglP_h */
diff --git a/bterm.c b/bterm.c
index dfae8b9..e86a748 100644
--- a/bterm.c
+++ b/bterm.c
@@ -39,6 +39,7 @@
 #include 
 
 #include "bogl.h"
+#include "boglP.h"
 #include "bogl-bgf.h"
 #include "bogl-term.h"
 
@@ -160,7 +161,6 @@ void sigchld(int sig)
   quit_status = status;
 quit = 1;
   }
-  signal(SIGCHLD, sigchld);
   errno = errsv;
 }
 
@@ -176,7 +176,7 @@ void spawn_shell(int ptyfd, int ttyfd, char * const *command_args)
   child_pid = fork();
   if (child_pid) {
 /* Change ownership and permissions of ttyfd device! */
-signal(SIGCHLD, sigchld);
+bogl_signal(SIGCHLD, sigchld);
 return;
   }
 
@@ -212,10 +212,16 @@ void set_window_size(int ttyfd, int x, int y)
 
 static char *font_name;
 static struct 

Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-03 Thread Samuel Thibault
Control: tags -1 + pending

Zhang Boyang, le ven. 03 juin 2022 17:04:26 +0900, a ecrit:
> Changes in [PATCH V4]:
> 
> Tiny improvement: detect 8K+ monitors and assign 8x scale factor for them.

Applied, thanks!

Samuel



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-06-03 Thread Zhang Boyang

Hi,

Changes in [PATCH V3]:

Please refer to https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1011609#30

Changes in [PATCH V4]:

Tiny improvement: detect 8K+ monitors and assign 8x scale factor for them.


Best Regards,
Zhang BoyangFrom 540b82ac07c5a582da3d6e6ad1cdc2fd83c36b2e Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Mon, 23 May 2022 14:10:52 +0800
Subject: [PATCH v4 1/4] Better font reload handling

Previous font reload code will leak a mmap on each reload. This patch
adds the ability to munmap old font after reload. However, this also
introduces a bug, if font reload is triggered while drawing in progress,
after signal handler returns, the drawing code will continue to use old
font which has been freed, causing crash. So the munmap is temporarily
disabled until we fix async-signal-safety problems completely.
---
 bogl-bgf.c | 63 +++---
 bogl-bgf.h |  1 +
 bterm.c|  9 
 3 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/bogl-bgf.c b/bogl-bgf.c
index 1032028..beed3c8 100644
--- a/bogl-bgf.c
+++ b/bogl-bgf.c
@@ -5,38 +5,55 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bogl.h"
 #include "boglP.h"
 #include "bogl-font.h"
+#include "bogl-bgf.h"
+
+struct bogl_bgf {
+  void *f;/* mmap area */
+  off_t size; /* size of mmap area */
+  struct bogl_font font; /* font descriptor */
+};
+#define bgf_of(font) \
+  ((struct bogl_bgf *)((char *)(font) - offsetof(struct bogl_bgf, font)))
 
 struct bogl_font *bogl_mmap_font(char *file)
 {
-  int fd;
+  struct bogl_bgf *bgf = NULL;
+  struct bogl_font *font = NULL;
+  int fd = -1;
   struct stat buf;
-  void *f;
-  struct bogl_font *font;
+  void *f = MAP_FAILED;
+
+  bgf = (struct bogl_bgf *)malloc(sizeof(struct bogl_bgf));
+  if (!bgf)
+goto fail;
+  font = >font;
 
   fd = open(file, O_RDONLY);
   if (fd == -1)
-return 0;
+goto fail;
 
   if (bogl_cloexec(fd) < 0)
-return 0;
+goto fail;
 
   if (fstat(fd, ))
-return 0;
+goto fail;
+  bgf->size = buf.st_size;
+
+  if (buf.st_size < 4)
+goto fail;
 
   f = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
-  if (f == (void *)-1)
-return 0;
+  if (f == MAP_FAILED)
+goto fail;
+  bgf->f = f;
 
   if (memcmp("BGF1", f, 4))
-return 0;
-
-  font = (struct bogl_font *)malloc(sizeof(struct bogl_font));
-  if (!font)
-return 0;
+goto fail;
 
   memcpy(font, f + 4, sizeof(*font));
   font->name = ((void *)font->name - (void *)0) + f;
@@ -44,5 +61,25 @@ struct bogl_font *bogl_mmap_font(char *file)
   font->index = ((void *)font->index - (void *)0) + f;
   font->content = ((void *)font->content - (void *)0) + f;
 
+done:
+  if (fd != -1)
+close(fd);
   return font;
+
+fail:
+  if (bgf) {
+free(bgf);
+bgf = NULL;
+font = NULL;
+  }
+  if (f != MAP_FAILED)
+munmap(f, buf.st_size);
+  goto done;
+}
+
+void bogl_munmap_font(struct bogl_font *font)
+{
+  struct bogl_bgf *bgf = bgf_of(font);
+  munmap(bgf->f, bgf->size);
+  free(bgf);
 }
diff --git a/bogl-bgf.h b/bogl-bgf.h
index e9fb994..f14a260 100644
--- a/bogl-bgf.h
+++ b/bogl-bgf.h
@@ -1,2 +1,3 @@
 
 struct bogl_font *bogl_mmap_font(char *file);
+void bogl_munmap_font(struct bogl_font *font);
diff --git a/bterm.c b/bterm.c
index 605644f..dfae8b9 100644
--- a/bterm.c
+++ b/bterm.c
@@ -224,11 +224,10 @@ void reload_font(int sig)
   return;
 }
   
-  /* This leaks a mmap.  Since the font reloading feature is only expected
- to be used once per session (for instance, in debian-installer, after
- the font is replaced with a larger version containing more characters),
- we don't worry about the leak.  */
-  free(term->font);
+  /* BUG: Unmapping old font in this signal handler may cause crash if
+ drawing is in progress, so disable this temporarily until we fix
+ async-signal-safety problems completely. */
+  //bogl_munmap_font(term->font);
 
   term->font = font;
   term->xstep = bogl_font_glyph(term->font, ' ', 0);
-- 
2.30.2

From b222a9a15b0a2706927ecde8ce163243b076bbcb Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Tue, 24 May 2022 12:58:01 +0800
Subject: [PATCH v4 2/4] Fix incorrect signal handling

There are problems in signal handlers. Signal handlers must not call any
non-async-signal-safe functions, and they must save-restore errno if
errno is modified inside signal handlers. This patch fixes these
problems by deferring real tasks to main loop. This patch also
introduces bogl_signal(), which wraps around sigaction() thus signal
handlers can be installed in a portable way. Since signal related
problems are fixed, the previously temporarily disabled font unmapping
is now re-enabled.
---
 bogl.c  | 50 +-
 bogl.h  |  2 ++
 boglP.h |  2 ++
 bterm.c | 35 +--
 4 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/bogl.c b/bogl.c
index 6b9996b..86bc1e0 100644
--- a/bogl.c
+++ b/bogl.c
@@ 

Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-30 Thread Zhang Boyang

Hi,

I forgot to attach the patches in the last mail. Here are the updated 
patches.


Best Regards,
Zhang BoyangFrom 540b82ac07c5a582da3d6e6ad1cdc2fd83c36b2e Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Mon, 23 May 2022 14:10:52 +0800
Subject: [PATCH v3 1/4] Better font reload handling

Previous font reload code will leak a mmap on each reload. This patch
adds the ability to munmap old font after reload. However, this also
introduces a bug, if font reload is triggered while drawing in progress,
after signal handler returns, the drawing code will continue to use old
font which has been freed, causing crash. So the munmap is temporarily
disabled until we fix async-signal-safety problems completely.
---
 bogl-bgf.c | 63 +++---
 bogl-bgf.h |  1 +
 bterm.c|  9 
 3 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/bogl-bgf.c b/bogl-bgf.c
index 1032028..beed3c8 100644
--- a/bogl-bgf.c
+++ b/bogl-bgf.c
@@ -5,38 +5,55 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bogl.h"
 #include "boglP.h"
 #include "bogl-font.h"
+#include "bogl-bgf.h"
+
+struct bogl_bgf {
+  void *f;/* mmap area */
+  off_t size; /* size of mmap area */
+  struct bogl_font font; /* font descriptor */
+};
+#define bgf_of(font) \
+  ((struct bogl_bgf *)((char *)(font) - offsetof(struct bogl_bgf, font)))
 
 struct bogl_font *bogl_mmap_font(char *file)
 {
-  int fd;
+  struct bogl_bgf *bgf = NULL;
+  struct bogl_font *font = NULL;
+  int fd = -1;
   struct stat buf;
-  void *f;
-  struct bogl_font *font;
+  void *f = MAP_FAILED;
+
+  bgf = (struct bogl_bgf *)malloc(sizeof(struct bogl_bgf));
+  if (!bgf)
+goto fail;
+  font = >font;
 
   fd = open(file, O_RDONLY);
   if (fd == -1)
-return 0;
+goto fail;
 
   if (bogl_cloexec(fd) < 0)
-return 0;
+goto fail;
 
   if (fstat(fd, ))
-return 0;
+goto fail;
+  bgf->size = buf.st_size;
+
+  if (buf.st_size < 4)
+goto fail;
 
   f = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
-  if (f == (void *)-1)
-return 0;
+  if (f == MAP_FAILED)
+goto fail;
+  bgf->f = f;
 
   if (memcmp("BGF1", f, 4))
-return 0;
-
-  font = (struct bogl_font *)malloc(sizeof(struct bogl_font));
-  if (!font)
-return 0;
+goto fail;
 
   memcpy(font, f + 4, sizeof(*font));
   font->name = ((void *)font->name - (void *)0) + f;
@@ -44,5 +61,25 @@ struct bogl_font *bogl_mmap_font(char *file)
   font->index = ((void *)font->index - (void *)0) + f;
   font->content = ((void *)font->content - (void *)0) + f;
 
+done:
+  if (fd != -1)
+close(fd);
   return font;
+
+fail:
+  if (bgf) {
+free(bgf);
+bgf = NULL;
+font = NULL;
+  }
+  if (f != MAP_FAILED)
+munmap(f, buf.st_size);
+  goto done;
+}
+
+void bogl_munmap_font(struct bogl_font *font)
+{
+  struct bogl_bgf *bgf = bgf_of(font);
+  munmap(bgf->f, bgf->size);
+  free(bgf);
 }
diff --git a/bogl-bgf.h b/bogl-bgf.h
index e9fb994..f14a260 100644
--- a/bogl-bgf.h
+++ b/bogl-bgf.h
@@ -1,2 +1,3 @@
 
 struct bogl_font *bogl_mmap_font(char *file);
+void bogl_munmap_font(struct bogl_font *font);
diff --git a/bterm.c b/bterm.c
index 605644f..dfae8b9 100644
--- a/bterm.c
+++ b/bterm.c
@@ -224,11 +224,10 @@ void reload_font(int sig)
   return;
 }
   
-  /* This leaks a mmap.  Since the font reloading feature is only expected
- to be used once per session (for instance, in debian-installer, after
- the font is replaced with a larger version containing more characters),
- we don't worry about the leak.  */
-  free(term->font);
+  /* BUG: Unmapping old font in this signal handler may cause crash if
+ drawing is in progress, so disable this temporarily until we fix
+ async-signal-safety problems completely. */
+  //bogl_munmap_font(term->font);
 
   term->font = font;
   term->xstep = bogl_font_glyph(term->font, ' ', 0);
-- 
2.30.2

From b222a9a15b0a2706927ecde8ce163243b076bbcb Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Tue, 24 May 2022 12:58:01 +0800
Subject: [PATCH v3 2/4] Fix incorrect signal handling

There are problems in signal handlers. Signal handlers must not call any
non-async-signal-safe functions, and they must save-restore errno if
errno is modified inside signal handlers. This patch fixes these
problems by deferring real tasks to main loop. This patch also
introduces bogl_signal(), which wraps around sigaction() thus signal
handlers can be installed in a portable way. Since signal related
problems are fixed, the previously temporarily disabled font unmapping
is now re-enabled.
---
 bogl.c  | 50 +-
 bogl.h  |  2 ++
 boglP.h |  2 ++
 bterm.c | 35 +--
 4 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/bogl.c b/bogl.c
index 6b9996b..86bc1e0 100644
--- a/bogl.c
+++ b/bogl.c
@@ -65,6 +65,7 @@
 /* Global variables. */
 int bogl_xres, bogl_yres, bogl_bpp;	/* bogl.h */
 int bogl_refresh;
+volatile int 

Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-30 Thread Zhang Boyang

Hi,

Thanks for reviewing. I did some changes on my patch. I also closed the 
PR on salsa because we are using debian bug tracker instead of gitlab 
pull requests.



On 2022/5/30 03:49, Samuel Thibault wrote:


Then is it not possible to exchange the patch order? So that whatever
the number of patches being applied, things work completely.


The two patch is tightly related. I guess why the original code leak a 
font mmap intentionally is just to avoid the 
font-unmap-during-drawing-will-cause-crash problem. The 
async-signal-safefy patch will defer font reloading to main loop to 
avoid this problem (and fix other problems like calling malloc() in 
signal handlers which is very dangerous).


I updated my patch. The first patch (Better font reload handling) will 
comment out the call to bogl_munmap_font(), avoiding crash but still 
have a leak, just like the original code. So if someone only applies the 
first patch, it will work as before (not crash but still leak memory). 
The second patch (Fix incorrect signal handling) will re-enable the call 
previously commented out in first patch. So if someone want to apply the 
second patch, he/she must apply the first patch first, make dependency 
more clear. So, things are always working if (a) only first patch is 
applied, or (b) both first and second patch are applied, or (c) non of 
these two patch are applied, and (d) it is not possible to only apply 
second patch because the patch command will complain about conflicts.




While at it, please use MAP_FAILED rather than the hardcoded (void*)-1


Fixed. :-)



This looks unrelated and bogus?


This is because I want to maintain a constant look of signal handlers. 
The reason behind it is there is no need to call signal() to install 
handler again because glibc's signal() now provide BSD semantics per man 
page of signal(). I updated my patch and use a sigaction wrapper to 
address this explicitly, and this will make the code more portable.




Do you have a reference that documents this?


Unfortunately there is no document about this, mainly because this is a 
workaround for buggy drivers. I updated comments in code to address this 
more explicitly.




MAP_FAILED here as well.


Fixed. :-)



Please make these an inline function rather than copy/pasting them from
bogl_mmap_font.


Fixed. :-)



Best Regards,
Zhang Boyang



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-29 Thread Samuel Thibault
Hello,

Zhang Boyang, le dim. 29 mai 2022 14:23:19 +0800, a ecrit:
> Subject: [PATCH v2 1/8] Better quit handling

That looks good, applied!

> From 302952c64952197d694039358df407ec3ffa418a Mon Sep 17 00:00:00 2001
> From: Zhang Boyang 
> Date: Mon, 23 May 2022 14:10:52 +0800
> Subject: [PATCH v2 2/8] Better font reload handling
> 
> Previous font reload code will leak a mmap on each reload. This patch
> adds the ability to munmap old font after reload. However, this also
> introduces a bug, if font reload is triggered while drawing in progress,
> after signal handler returns, the drawing code will continue to use old
> font which has been freed, causing crash. This will be fixed in next
> patch.

Then is it not possible to exchange the patch order? So that whatever
the number of patches being applied, things work completely.

> -  void *f;
> -  struct bogl_font *font;
> +  void *f = (void *)-1;
[...]
>f = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
>if (f == (void *)-1)

While at it, please use MAP_FAILED rather than the hardcoded (void*)-1

Otherwise it looks good.

> From 4b2e0651edf19cab4b162c686c21e81682c854a0 Mon Sep 17 00:00:00 2001
> From: Zhang Boyang 
> Date: Tue, 24 May 2022 12:58:01 +0800
> Subject: [PATCH v2 3/8] Fix incorrect signal handling
> 
> There are problems in signal handlers. Signal handlers must not call any
> non-async-signal-safe functions, and they must save-restore errno if
> errno is modified inside signal handlers. This patch fixes these
> problems by deferring real tasks to main loop. This also fixes crashes
> caused by font reloading which was mentioned in previous patch.

> diff --git a/bterm.c b/bterm.c
> index 28ccb53..b0a1189 100644
> --- a/bterm.c
> +++ b/bterm.c
> @@ -160,7 +160,6 @@ void sigchld(int sig)
>quit_status = status;
>  quit = 1;
>}
> -  signal(SIGCHLD, sigchld);
>errno = errsv;
>  }
>  

This looks unrelated and bogus?

Otherwise it looks good.

> From e7fe989fbbda4acfd9971604b7ffa84899cb343a Mon Sep 17 00:00:00 2001
> From: Zhang Boyang 
> Date: Mon, 23 May 2022 22:07:37 +0800
> Subject: [PATCH v2 4/8] Use ioctl(FBIOPAN_DISPLAY) to update screen after
>  drawing
> 
> Some framebuffer driver like i915 need explicit notify after drawing,
> otherwise modifications in graphics buffer will not be reflected on
> screen, so use FBIOPAN_DISPLAY to do this notify.

Do you have a reference that documents this?

Otherwise it looks good.

> From 04d88a6ff7114750c67cdb58e07122bb430763a9 Mon Sep 17 00:00:00 2001
> From: Zhang Boyang 
> Date: Tue, 24 May 2022 23:49:31 +0800
> Subject: [PATCH v2 5/8] Font scaler
[...]
> +bgf_scale_inline(struct bogl_bgf *bgf, int scale)
> +{
> +  void *new_f = (void *)-1;
> +  off_t new_size;
> +  struct bogl_font new_font;
> +
> +  /* old_size*pow(scale,2) should enough and have some waste here */
> +  new_size = bgf->size * scale * scale;
> +
> +  /* Allocate new memory */
> +  new_f = mmap(0, new_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | 
> MAP_ANONYMOUS, -1, 0);
> +  if (new_f == (void *)-1) {

MAP_FAILED here as well.

> +/* If memory allocation failed, skip scaling silently */
> +goto fail;
> +  }
> +
> +  /* Copy old font data to new memory */
> +  memcpy(new_f, bgf->f, bgf->size);
> +
> +  /* Set font metadata */
> +  struct bogl_font *font = _font;

> +  memcpy(font, new_f + 4, sizeof(*font));
> +  font->name = ((void *)font->name - (void *)0) + new_f;
> +  font->offset = ((void *)font->offset - (void *)0) + new_f;
> +  font->index = ((void *)font->index - (void *)0) + new_f;
> +  font->content = ((void *)font->content - (void *)0) + new_f;

Please make these an inline function rather than copy/pasting them from
bogl_mmap_font.

Otherwise it looks good.

> Subject: [PATCH v2 6/8] Fix character occasionally disappears from right edge 
> of screen

That looks good, applied!

> Subject: [PATCH v2 7/8] Fix out-of-bound read in tcfb's cmap_lookup()

That looks good, applied!

> Subject: [PATCH v2 8/8] Fix rightmost pixel of each line not cleared by 
> bogl_vga16_text()

That looks good, applied!

And thanks!
Samuel



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-29 Thread Zhang Boyang
This is the v2 patch series. There are some reordering, squashing, and 
minor changes compared to previously proposed patch series.


An all-in-one patch for quilt is also attached, which can be directly 
applied to the git repo. (Same as the merge request it self)From c8de527c0c0ff5b8e2a3c10c1d26e5674ffccf50 Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Tue, 24 May 2022 01:27:10 +0800
Subject: [PATCH v2 1/8] Better quit handling

Previous SIGCHLD handler is not async-signal-safe because it calls
exit(), and it also doesn't save-restore errno. Using _exit() will be
async-signal-safe safe but will result in unclean quit. In the end, this
patch will set a flag variable in signal handler, then defer real
cleanup and quitting to main loop.
---
 bterm.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/bterm.c b/bterm.c
index d7b574f..605644f 100644
--- a/bterm.c
+++ b/bterm.c
@@ -64,7 +64,7 @@ static const unsigned char palette[16][3] =
 
 static int child_pid = 0;
 static struct termios ttysave;
-static int quit = 0;
+static volatile int quit = 0, quit_status = 0;
 
 /* Out of memory.  Give up. */
 static void out_of_memory (void)
@@ -144,24 +144,29 @@ void send_hangup(void)
 
 void sigchld(int sig)
 {
+  int errsv = errno;
   int status;
   if (waitpid(child_pid, , WNOHANG) > 0) {
 child_pid = 0;
 /* Reset ownership and permissions of ttyfd device? */
 tcsetattr(0, TCSAFLUSH, );
 if (WIFEXITED (status))
-  exit(WEXITSTATUS (status));
-if (WIFSIGNALED (status))
-  exit(128 + WTERMSIG (status));
-if (WIFSTOPPED (status))
-  exit(128 + WSTOPSIG (status));
-exit(status);
+  quit_status = WEXITSTATUS (status);
+else if (WIFSIGNALED (status))
+  quit_status = 128 + WTERMSIG (status);
+else if (WIFSTOPPED (status))
+  quit_status = 128 + WSTOPSIG (status);
+else
+  quit_status = status;
+quit = 1;
   }
   signal(SIGCHLD, sigchld);
+  errno = errsv;
 }
 
 void sigterm(int sig)
 {
+	quit_status = 128 + SIGTERM;
 	quit = 1;
 }
 
@@ -420,5 +425,5 @@ int main(int argc, char *argv[])
 }
   }
 
-  return 0;
+  exit(quit_status);
 }
-- 
2.30.2

From 302952c64952197d694039358df407ec3ffa418a Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Mon, 23 May 2022 14:10:52 +0800
Subject: [PATCH v2 2/8] Better font reload handling

Previous font reload code will leak a mmap on each reload. This patch
adds the ability to munmap old font after reload. However, this also
introduces a bug, if font reload is triggered while drawing in progress,
after signal handler returns, the drawing code will continue to use old
font which has been freed, causing crash. This will be fixed in next
patch.
---
 bogl-bgf.c | 61 +++---
 bogl-bgf.h |  1 +
 bterm.c|  6 +-
 3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/bogl-bgf.c b/bogl-bgf.c
index 1032028..0383f4f 100644
--- a/bogl-bgf.c
+++ b/bogl-bgf.c
@@ -5,38 +5,55 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bogl.h"
 #include "boglP.h"
 #include "bogl-font.h"
+#include "bogl-bgf.h"
+
+struct bogl_bgf {
+  void *f;/* mmap area */
+  off_t size; /* size of mmap area */
+  struct bogl_font font; /* font descriptor */
+};
+#define bgf_of(font) \
+  ((struct bogl_bgf *)((char *)(font) - offsetof(struct bogl_bgf, font)))
 
 struct bogl_font *bogl_mmap_font(char *file)
 {
-  int fd;
+  struct bogl_bgf *bgf = NULL;
+  struct bogl_font *font = NULL;
+  int fd = -1;
   struct stat buf;
-  void *f;
-  struct bogl_font *font;
+  void *f = (void *)-1;
+
+  bgf = (struct bogl_bgf *)malloc(sizeof(struct bogl_bgf));
+  if (!bgf)
+goto fail;
+  font = >font;
 
   fd = open(file, O_RDONLY);
   if (fd == -1)
-return 0;
+goto fail;
 
   if (bogl_cloexec(fd) < 0)
-return 0;
+goto fail;
 
   if (fstat(fd, ))
-return 0;
+goto fail;
+  bgf->size = buf.st_size;
+
+  if (buf.st_size < 4)
+goto fail;
 
   f = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
   if (f == (void *)-1)
-return 0;
+goto fail;
+  bgf->f = f;
 
   if (memcmp("BGF1", f, 4))
-return 0;
-
-  font = (struct bogl_font *)malloc(sizeof(struct bogl_font));
-  if (!font)
-return 0;
+goto fail;
 
   memcpy(font, f + 4, sizeof(*font));
   font->name = ((void *)font->name - (void *)0) + f;
@@ -44,5 +61,25 @@ struct bogl_font *bogl_mmap_font(char *file)
   font->index = ((void *)font->index - (void *)0) + f;
   font->content = ((void *)font->content - (void *)0) + f;
 
+done:
+  if (fd != -1)
+close(fd);
   return font;
+
+fail:
+  if (bgf) {
+free(bgf);
+bgf = NULL;
+font = NULL;
+  }
+  if (f != (void *)-1)
+munmap(f, buf.st_size);
+  goto done;
+}
+
+void bogl_munmap_font(struct bogl_font *font)
+{
+  struct bogl_bgf *bgf = bgf_of(font);
+  munmap(bgf->f, bgf->size);
+  free(bgf);
 }
diff --git a/bogl-bgf.h b/bogl-bgf.h
index e9fb994..f14a260 100644
--- a/bogl-bgf.h
+++ 

Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-28 Thread Zhang Boyang

Hi,

Another small patch. :-)

Best Regards,
Zhang BoyangFrom ae763e89f00575e56a7242e27c9b0789c0de411e Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Sun, 29 May 2022 02:45:32 +0800
Subject: [PATCH] Don't call FBIOPAN_DISPLAY when using the vga16fb driver

When using vga16fb, there is no need to call FBIOPAN_DISPLAY, and it may
cause screen flicker on certain hardwares.
---
 bogl.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/bogl.c b/bogl.c
index 9b628b1..5cbe96e 100644
--- a/bogl.c
+++ b/bogl.c
@@ -462,6 +462,15 @@ bogl_fb_set_palette (int c, int nc, const unsigned char palette[][3])
 void
 bogl_update (void)
 {
+#if BOGL_VGA16_FB
+  if (type == FB_TYPE_VGA_PLANES)
+{
+  /* There is no need to call FBIOPAN_DISPLAY when using vga16fb driver.
+ What's worse, it may cause screen flicker on certain hardwares.
+	 So make bogl_update() a no-op here. */
+  return;
+}
+#endif
   ioctl (fb, FBIOPAN_DISPLAY, _var);
 }
 
-- 
2.30.2



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-28 Thread Zhang Boyang

Hi,

Here is another small patch. Please see the commit message of the patch 
for details. The merge request on salsa is also updated.



Best Regards,
Zhang BoyangFrom 36020995b989563efed3cfe6028cd93c192c0208 Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Sat, 28 May 2022 16:39:23 +0800
Subject: [PATCH] Fix rightmost pixel of each line not cleared by
 bogl_vga16_text()

The bogl_vga16_clear() function use [x1, x2) as clear range, so there is
no need to minus x2 by 1.
---
 bogl-vga16.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bogl-vga16.c b/bogl-vga16.c
index 6c2cbcf..3fcbe51 100644
--- a/bogl-vga16.c
+++ b/bogl-vga16.c
@@ -373,7 +373,7 @@ bogl_vga16_text (int xx, int yy, const char *s, int n, int fg, int bg, int ul,
 {
   int x2 = xx + bogl_metrics (s, n, font);
   if (x2 >= bogl_xres)
-	x2 = bogl_xres - 1;
+	x2 = bogl_xres;
   
   bogl_vga16_clear (xx, yy, x2, yy + h, bg);
 }
-- 
2.30.2



Bug#1011609: bogl-bterm: [PATCH] Several improvements

2022-05-25 Thread Zhang Boyang

Package: bogl-bterm

Hello,

I made several improvements to bterm. Please see these patches for 
details. For convenience, I also created a merge request at 
https://salsa.debian.org/debian/bogl/-/merge_requests/2



Best Regards,
Zhang BoyangFrom 1e253d724658ffc22f1339212af3d2754249b251 Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Mon, 23 May 2022 14:10:52 +0800
Subject: [PATCH 1/7] Better font reload handling

Previous font reload code will leak a mmap on each reload. This patch
adds the ability to munmap old font after reload. However, this also
introduces a bug, if font reload is triggered while drawing in progress,
after signal handler returns, the drawing code will continue to use old
font which has been freed, causing crash. This will be fixed in later
patches.
---
 bogl-bgf.c | 61 +++---
 bogl-bgf.h |  1 +
 bterm.c| 10 -
 3 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/bogl-bgf.c b/bogl-bgf.c
index 1032028..0383f4f 100644
--- a/bogl-bgf.c
+++ b/bogl-bgf.c
@@ -5,38 +5,55 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bogl.h"
 #include "boglP.h"
 #include "bogl-font.h"
+#include "bogl-bgf.h"
+
+struct bogl_bgf {
+  void *f;/* mmap area */
+  off_t size; /* size of mmap area */
+  struct bogl_font font; /* font descriptor */
+};
+#define bgf_of(font) \
+  ((struct bogl_bgf *)((char *)(font) - offsetof(struct bogl_bgf, font)))
 
 struct bogl_font *bogl_mmap_font(char *file)
 {
-  int fd;
+  struct bogl_bgf *bgf = NULL;
+  struct bogl_font *font = NULL;
+  int fd = -1;
   struct stat buf;
-  void *f;
-  struct bogl_font *font;
+  void *f = (void *)-1;
+
+  bgf = (struct bogl_bgf *)malloc(sizeof(struct bogl_bgf));
+  if (!bgf)
+goto fail;
+  font = >font;
 
   fd = open(file, O_RDONLY);
   if (fd == -1)
-return 0;
+goto fail;
 
   if (bogl_cloexec(fd) < 0)
-return 0;
+goto fail;
 
   if (fstat(fd, ))
-return 0;
+goto fail;
+  bgf->size = buf.st_size;
+
+  if (buf.st_size < 4)
+goto fail;
 
   f = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
   if (f == (void *)-1)
-return 0;
+goto fail;
+  bgf->f = f;
 
   if (memcmp("BGF1", f, 4))
-return 0;
-
-  font = (struct bogl_font *)malloc(sizeof(struct bogl_font));
-  if (!font)
-return 0;
+goto fail;
 
   memcpy(font, f + 4, sizeof(*font));
   font->name = ((void *)font->name - (void *)0) + f;
@@ -44,5 +61,25 @@ struct bogl_font *bogl_mmap_font(char *file)
   font->index = ((void *)font->index - (void *)0) + f;
   font->content = ((void *)font->content - (void *)0) + f;
 
+done:
+  if (fd != -1)
+close(fd);
   return font;
+
+fail:
+  if (bgf) {
+free(bgf);
+bgf = NULL;
+font = NULL;
+  }
+  if (f != (void *)-1)
+munmap(f, buf.st_size);
+  goto done;
+}
+
+void bogl_munmap_font(struct bogl_font *font)
+{
+  struct bogl_bgf *bgf = bgf_of(font);
+  munmap(bgf->f, bgf->size);
+  free(bgf);
 }
diff --git a/bogl-bgf.h b/bogl-bgf.h
index e9fb994..f14a260 100644
--- a/bogl-bgf.h
+++ b/bogl-bgf.h
@@ -1,2 +1,3 @@
 
 struct bogl_font *bogl_mmap_font(char *file);
+void bogl_munmap_font(struct bogl_font *font);
diff --git a/bterm.c b/bterm.c
index d7b574f..22cbef5 100644
--- a/bterm.c
+++ b/bterm.c
@@ -215,15 +215,13 @@ void reload_font(int sig)
   font = bogl_mmap_font (font_name);
   if (font == NULL)
 {
-  fprintf(stderr, "Bad font\n");
+  /* Fail silently. To simplify implementation, debian-installer may
+ trigger redundant font reload requests, and the font file may not
+ available at that time, so handle it gracefully. */
   return;
 }
   
-  /* This leaks a mmap.  Since the font reloading feature is only expected
- to be used once per session (for instance, in debian-installer, after
- the font is replaced with a larger version containing more characters),
- we don't worry about the leak.  */
-  free(term->font);
+  bogl_munmap_font(term->font);
 
   term->font = font;
   term->xstep = bogl_font_glyph(term->font, ' ', 0);
-- 
2.30.2

From 0f1b0b57a2b36ae4e04a5a32c9a55634a1cbae39 Mon Sep 17 00:00:00 2001
From: Zhang Boyang 
Date: Mon, 23 May 2022 22:07:37 +0800
Subject: [PATCH 2/7] Use ioctl(FBIOPAN_DISPLAY) to update screen after drawing

Some framebuffer driver like i915 need explicit notify after drawing,
otherwise modifications in graphics buffer will not be reflected on
screen, so use FBIOPAN_DISPLAY to do this notify.
---
 bogl-term.c |  1 +
 bogl.c  | 10 +-
 bogl.h  |  1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/bogl-term.c b/bogl-term.c
index d5780d3..1f68523 100644
--- a/bogl-term.c
+++ b/bogl-term.c
@@ -863,4 +863,5 @@ bogl_term_redraw (struct bogl_term *term)
 {
 show_cursor(term, 1);
 }
+bogl_update();
 }
diff --git a/bogl.c b/bogl.c
index 6b9996b..a3014e8 100644
--- a/bogl.c
+++ b/bogl.c
@@ -123,12 +123,12 @@ static void kbd_done (void);
 static void vt_switch