Anonymous avatar Anonymous committed f611bf2

better signal handling

Comments (0)

Files changed (1)

 #define cursor_fwd(n) printf("\033[%dC", MAX(1, (n)))
 #define cursor_org()  printf("\033[1;1H")
 
+void erase_usr(void);
+void my_write(int fd, const char *buf, size_t count);
+void print_usr(void);
+void quit(int sig);
+void run(void);
+void sigchld(int sig);
+int  start_pos(int start, int cur, int len, int cols);
+void stop(int unused);
+void term_set(int unused);
+void usage(void);
+
+struct sig {
+	int sig;
+	char *name;
+	void (*func)(int);
+};
+
+struct sig sig_table[] = {
+	{SIGINT,  "SIGINT" , quit    },
+	{SIGTERM, "SIGTERM", quit    },
+	{SIGTSTP, "SIGTSTP", stop    },
+	{SIGCONT, "SIGCONT", term_set},
+	{SIGCHLD, "SIGCHLD", sigchld },
+	{0},
+};
+
 char  buf[4096], usrbuf[4096];
 char  scrl_prompt_left[]  = "<";
 char  scrl_prompt_right[] = ">";
 int mfd;
 pid_t child;
 
-struct termios set;
+struct termios set, dfl;
 
 void usage(void)
 {
 	exit(1);
 }
 
-void sigcont(int unused)
+void term_set(int unused)
 {
 	tcsetattr(0, TCSANOW, &set);
+	print_usr();
 }
 
-void sigchld(int unused)
+void quit(int sig)
+{
+	tcsetattr(0, TCSANOW, &dfl);
+	exit(sig);
+}
+
+void sigchld(int sig)
 {
 	pid_t pid;
 
 		if (pid == child) {
 			printf("\n");
 			warnx("subprocess died");
-			kill(getpid(), SIGINT);
+			quit(sig);
 		}
 	}
 }
 
+void stop(int unused)
+{
+	tcsetattr(0, TCSANOW, &dfl);
+	kill(-getpid(), SIGSTOP);
+}
+
 void my_write(int fd, const char *buf, size_t count)
 {
 	int i, wrlen;
 	fflush(stdout);
 }
 
-void run()
+void run(void)
 {
 	static int escape = 0;
 	int rdlen, i;
 	if (i >= argc)
 		usage();
 
-	tcgetattr(0, &set);
+	tcgetattr(0, &dfl);
+	memcpy(&set, &dfl, sizeof(set));
 	set.c_lflag &= ~ECHO;
 
-	if (signal(SIGCHLD, sigchld) == SIG_ERR)
-		err(1, "failed to install SIGCHLD handler");
-
-	if (signal(SIGCONT, sigcont) == SIG_ERR)
-		err(1, "failed to install SIGCONT handler");
-
 	if ((child = forkpty(&mfd, NULL, &set, NULL)) == 0) { //child
 		execvp(argv[i], &argv[i]);
 		err(1, "failed execvp %s", argv[i]);
 	set.c_cc[VTIME] = 0;
 	tcsetattr(0, TCSANOW, &set);
 
+	for (i = 0; sig_table[i].sig; i++)
+		if (signal(sig_table[i].sig, sig_table[i].func) == SIG_ERR)
+			err(1, "failed to install %s handler", sig_table[i].name);
+
 	print_usr();
 	run();
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.