X-Git-Url: https://git.xinqibao.xyz/st.git/blobdiff_plain/177d888dff2fdf987dfa7fc3eb8495fa107879ad..83dea7fd7bb5f6e8a11a7ac8a734d8016d1ed0cb:/st.c?ds=sidebyside

diff --git a/st.c b/st.c
index 0e228a7..6165119 100644
--- a/st.c
+++ b/st.c
@@ -70,7 +70,7 @@ char *argv0;
 #define LEN(a)     (sizeof(a) / sizeof(a)[0])
 #define DEFAULT(a, b)     (a) = (a) ? (a) : (b)
 #define BETWEEN(x, a, b)  ((a) <= (x) && (x) <= (b))
-#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f))
+#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
 #define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
@@ -88,17 +88,17 @@ char *argv0;
 
 enum glyph_attribute {
 	ATTR_NULL      = 0,
-	ATTR_BOLD      = 1,
-	ATTR_FAINT     = 2,
-	ATTR_ITALIC    = 4,
-	ATTR_UNDERLINE = 8,
-	ATTR_BLINK     = 16,
-	ATTR_REVERSE   = 32,
-	ATTR_INVISIBLE = 64,
-	ATTR_STRUCK    = 128,
-	ATTR_WRAP      = 256,
-	ATTR_WIDE      = 512,
-	ATTR_WDUMMY    = 1024,
+	ATTR_BOLD      = 1 << 0,
+	ATTR_FAINT     = 1 << 1,
+	ATTR_ITALIC    = 1 << 2,
+	ATTR_UNDERLINE = 1 << 3,
+	ATTR_BLINK     = 1 << 4,
+	ATTR_REVERSE   = 1 << 5,
+	ATTR_INVISIBLE = 1 << 6,
+	ATTR_STRUCK    = 1 << 7,
+	ATTR_WRAP      = 1 << 8,
+	ATTR_WIDE      = 1 << 9,
+	ATTR_WDUMMY    = 1 << 10,
 };
 
 enum cursor_movement {
@@ -113,27 +113,27 @@ enum cursor_state {
 };
 
 enum term_mode {
-	MODE_WRAP        = 1,
-	MODE_INSERT      = 2,
-	MODE_APPKEYPAD   = 4,
-	MODE_ALTSCREEN   = 8,
-	MODE_CRLF        = 16,
-	MODE_MOUSEBTN    = 32,
-	MODE_MOUSEMOTION = 64,
-	MODE_REVERSE     = 128,
-	MODE_KBDLOCK     = 256,
-	MODE_HIDE        = 512,
-	MODE_ECHO        = 1024,
-	MODE_APPCURSOR   = 2048,
-	MODE_MOUSESGR    = 4096,
-	MODE_8BIT        = 8192,
-	MODE_BLINK       = 16384,
-	MODE_FBLINK      = 32768,
-	MODE_FOCUS       = 65536,
-	MODE_MOUSEX10    = 131072,
-	MODE_MOUSEMANY   = 262144,
-	MODE_BRCKTPASTE  = 524288,
-	MODE_PRINT       = 1048576,
+	MODE_WRAP        = 1 << 0,
+	MODE_INSERT      = 1 << 1,
+	MODE_APPKEYPAD   = 1 << 2,
+	MODE_ALTSCREEN   = 1 << 3,
+	MODE_CRLF        = 1 << 4,
+	MODE_MOUSEBTN    = 1 << 5,
+	MODE_MOUSEMOTION = 1 << 6,
+	MODE_REVERSE     = 1 << 7,
+	MODE_KBDLOCK     = 1 << 8,
+	MODE_HIDE        = 1 << 9,
+	MODE_ECHO        = 1 << 10,
+	MODE_APPCURSOR   = 1 << 11,
+	MODE_MOUSESGR    = 1 << 12,
+	MODE_8BIT        = 1 << 13,
+	MODE_BLINK       = 1 << 14,
+	MODE_FBLINK      = 1 << 15,
+	MODE_FOCUS       = 1 << 16,
+	MODE_MOUSEX10    = 1 << 17,
+	MODE_MOUSEMANY   = 1 << 18,
+	MODE_BRCKTPASTE  = 1 << 19,
+	MODE_PRINT       = 1 << 20,
 	MODE_MOUSE       = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
 	                  |MODE_MOUSEMANY,
 };
@@ -356,6 +356,7 @@ static void csidump(void);
 static void csihandle(void);
 static void csiparse(void);
 static void csireset(void);
+static int eschandle(uchar ascii);
 static void strdump(void);
 static void strhandle(void);
 static void strparse(void);
@@ -1139,23 +1140,29 @@ die(const char *errstr, ...) {
 
 void
 execsh(void) {
-	char **args;
-	char *envshell = getenv("SHELL");
-	const struct passwd *pass = getpwuid(getuid());
+	char **args, *sh;
+	const struct passwd *pw;
 	char buf[sizeof(long) * 8 + 1];
 
+	errno = 0;
+	if((pw = getpwuid(getuid())) == NULL) {
+		if(errno)
+			die("getpwuid:%s\n", strerror(errno));
+		else
+			die("who are you?\n");
+	}
 	unsetenv("COLUMNS");
 	unsetenv("LINES");
 	unsetenv("TERMCAP");
 
-	if(pass) {
-		setenv("LOGNAME", pass->pw_name, 1);
-		setenv("USER", pass->pw_name, 1);
-		setenv("SHELL", pass->pw_shell, 0);
-		setenv("HOME", pass->pw_dir, 0);
-	}
-
+	sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
 	snprintf(buf, sizeof(buf), "%lu", xw.win);
+
+	setenv("LOGNAME", pw->pw_name, 1);
+	setenv("USER", pw->pw_name, 1);
+	setenv("SHELL", sh, 1);
+	setenv("HOME", pw->pw_dir, 1);
+	setenv("TERM", termname, 1);
 	setenv("WINDOWID", buf, 1);
 
 	signal(SIGCHLD, SIG_DFL);
@@ -1165,9 +1172,7 @@ execsh(void) {
 	signal(SIGTERM, SIG_DFL);
 	signal(SIGALRM, SIG_DFL);
 
-	DEFAULT(envshell, shell);
-	setenv("TERM", termname, 1);
-	args = opt_cmd ? opt_cmd : (char *[]){envshell, "-i", NULL};
+	args = opt_cmd ? opt_cmd : (char *[]){sh, "-i", NULL};
 	execvp(args[0], args);
 	exit(EXIT_FAILURE);
 }
@@ -2343,6 +2348,19 @@ tdeftran(char ascii) {
 	}
 }
 
+void
+tdectest(char c) {
+	static char E[UTF_SIZ] = "E";
+	int x, y;
+
+	if(c == '8') { /* DEC screen alignment test. */
+		for(x = 0; x < term.col; ++x) {
+			for(y = 0; y < term.row; ++y)
+				tsetchar(E, &term.c.attr, x, y);
+		}
+	}
+}
+
 void
 tstrsequence(uchar c) {
 	if (c & 0x80) {
@@ -2451,17 +2469,83 @@ tcontrolcode(uchar ascii) {
 	return;
 }
 
-void
-tdectest(char c) {
-	static char E[UTF_SIZ] = "E";
-	int x, y;
-
-	if(c == '8') { /* DEC screen alignment test. */
-		for(x = 0; x < term.col; ++x) {
-			for(y = 0; y < term.row; ++y)
-				tsetchar(E, &term.c.attr, x, y);
+/*
+ * returns 1 when the sequence is finished and it hasn't to read
+ * more characters for this sequence, otherwise 0
+ */
+int
+eschandle(uchar ascii) {
+	switch(ascii) {
+	case '[':
+		term.esc |= ESC_CSI;
+		return 0;
+	case '#':
+		term.esc |= ESC_TEST;
+		return 0;
+	case 'P': /* DCS -- Device Control String */
+	case '_': /* APC -- Application Program Command */
+	case '^': /* PM -- Privacy Message */
+	case ']': /* OSC -- Operating System Command */
+	case 'k': /* old title set compatibility */
+		tstrsequence(ascii);
+		return 0;
+	case '(': /* set primary charset G0 */
+	case ')': /* set secondary charset G1 */
+	case '*': /* set tertiary charset G2 */
+	case '+': /* set quaternary charset G3 */
+		term.icharset = ascii - '(';
+		term.esc |= ESC_ALTCHARSET;
+		return 0;
+	case 'D': /* IND -- Linefeed */
+		if(term.c.y == term.bot) {
+			tscrollup(term.top, 1);
+		} else {
+			tmoveto(term.c.x, term.c.y+1);
 		}
+		break;
+	case 'E': /* NEL -- Next line */
+		tnewline(1); /* always go to first col */
+		break;
+	case 'H': /* HTS -- Horizontal tab stop */
+		term.tabs[term.c.x] = 1;
+		break;
+	case 'M': /* RI -- Reverse index */
+		if(term.c.y == term.top) {
+			tscrolldown(term.top, 1);
+		} else {
+			tmoveto(term.c.x, term.c.y-1);
+		}
+		break;
+	case 'Z': /* DECID -- Identify Terminal */
+		ttywrite(vtiden, sizeof(vtiden) - 1);
+		break;
+	case 'c': /* RIS -- Reset to inital state */
+		treset();
+		xresettitle();
+		xloadcols();
+		break;
+	case '=': /* DECPAM -- Application keypad */
+		term.mode |= MODE_APPKEYPAD;
+		break;
+	case '>': /* DECPNM -- Normal keypad */
+		term.mode &= ~MODE_APPKEYPAD;
+		break;
+	case '7': /* DECSC -- Save Cursor */
+		tcursor(CURSOR_SAVE);
+		break;
+	case '8': /* DECRC -- Restore Cursor */
+		tcursor(CURSOR_LOAD);
+		break;
+	case '\\': /* ST -- String Terminator */
+		if(term.esc & ESC_STR_END)
+			strhandle();
+		break;
+	default:
+		fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
+			(uchar) ascii, isprint(ascii)? ascii:'.');
+		break;
 	}
+	return 1;
 }
 
 void
@@ -2548,76 +2632,9 @@ tputc(char *c, int len) {
 		} else if(term.esc & ESC_TEST) {
 			tdectest(ascii);
 		} else {
-			switch(ascii) {
-			case '[':
-				term.esc |= ESC_CSI;
+			if (!eschandle(ascii))
 				return;
-			case '#':
-				term.esc |= ESC_TEST;
-				return;
-			case 'P': /* DCS -- Device Control String */
-			case '_': /* APC -- Application Program Command */
-			case '^': /* PM -- Privacy Message */
-			case ']': /* OSC -- Operating System Command */
-			case 'k': /* old title set compatibility */
-				tstrsequence(ascii);
-				return;
-			case '(': /* set primary charset G0 */
-			case ')': /* set secondary charset G1 */
-			case '*': /* set tertiary charset G2 */
-			case '+': /* set quaternary charset G3 */
-				term.icharset = ascii - '(';
-				term.esc |= ESC_ALTCHARSET;
-				return;
-			case 'D': /* IND -- Linefeed */
-				if(term.c.y == term.bot) {
-					tscrollup(term.top, 1);
-				} else {
-					tmoveto(term.c.x, term.c.y+1);
-				}
-				break;
-			case 'E': /* NEL -- Next line */
-				tnewline(1); /* always go to first col */
-				break;
-			case 'H': /* HTS -- Horizontal tab stop */
-				term.tabs[term.c.x] = 1;
-				break;
-			case 'M': /* RI -- Reverse index */
-				if(term.c.y == term.top) {
-					tscrolldown(term.top, 1);
-				} else {
-					tmoveto(term.c.x, term.c.y-1);
-				}
-				break;
-			case 'Z': /* DECID -- Identify Terminal */
-				ttywrite(vtiden, sizeof(vtiden) - 1);
-				break;
-			case 'c': /* RIS -- Reset to inital state */
-				treset();
-				xresettitle();
-				xloadcols();
-				break;
-			case '=': /* DECPAM -- Application keypad */
-				term.mode |= MODE_APPKEYPAD;
-				break;
-			case '>': /* DECPNM -- Normal keypad */
-				term.mode &= ~MODE_APPKEYPAD;
-				break;
-			case '7': /* DECSC -- Save Cursor */
-				tcursor(CURSOR_SAVE);
-				break;
-			case '8': /* DECRC -- Restore Cursor */
-				tcursor(CURSOR_LOAD);
-				break;
-			case '\\': /* ST -- String Terminator */
-				if(term.esc & ESC_STR_END)
-					strhandle();
-				break;
-			default:
-				fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
-					(uchar) ascii, isprint(ascii)? ascii:'.');
-				break;
-			}
+			/* sequence already finished */
 		}
 		term.esc = 0;
 		/*