File: Better-quit-handling.patch

package info (click to toggle)
bogl 0.1.18-23
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,760 kB
  • sloc: ansic: 7,872; makefile: 217; perl: 26; sh: 10
file content (73 lines) | stat: -rw-r--r-- 1,962 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From c8de527c0c0ff5b8e2a3c10c1d26e5674ffccf50 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
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, &status, WNOHANG) > 0) {
     child_pid = 0;
     /* Reset ownership and permissions of ttyfd device? */
     tcsetattr(0, TCSAFLUSH, &ttysave);
     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