X-Git-Url: https://jasonwoof.com/gitweb/?p=st.git;a=blobdiff_plain;f=st.c;h=f15e868829a3be5247f24c8bd8249ad6d7b30996;hp=65473f01b0cd9952d793a4199601f1f1eb6b152b;hb=e5f6736ee0a0f29a14afec5494a5b3f204cedc1c;hpb=fa04911c91a049f397337d3436c4a5692da558fa diff --git a/st.c b/st.c index 65473f0..f15e868 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) @@ -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); } @@ -1356,9 +1361,12 @@ treset(void) { memset(term.trantbl, sizeof(term.trantbl), CS_USA); term.charset = 0; - tclearregion(0, 0, term.col-1, term.row-1); - tmoveto(0, 0); - tcursor(CURSOR_SAVE); + for(i = 0; i < 2; i++) { + tmoveto(0, 0); + tcursor(CURSOR_SAVE); + tclearregion(0, 0, term.col-1, term.row-1); + tswapscreen(); + } } void @@ -2341,6 +2349,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) { switch (c) { @@ -2448,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 @@ -2545,76 +2632,9 @@ tputc(char *c, int len) { } else if(term.esc & ESC_TEST) { tdectest(ascii); } else { - switch(ascii) { - case '[': - term.esc |= ESC_CSI; - 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); + if (!eschandle(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; /*