X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=c7589f490daecc4c806011b4eb392907af2ac681;hb=c27c731b9f77c1b1c99f3bde737be53996809fcb;hp=40840ce58f515b6fd115d4f01f1a4116ce2df1e8;hpb=83e73c6242fc309a3859c12b996ab88d36c7e838;p=st.git diff --git a/st.c b/st.c index 40840ce..c7589f4 100644 --- a/st.c +++ b/st.c @@ -352,6 +352,7 @@ static void draw(void); static void redraw(void); static void drawregion(int, int, int, int); static void execsh(void); +static void stty(void); static void sigchld(int); static void run(void); @@ -508,6 +509,7 @@ static char *opt_title = NULL; static char *opt_embed = NULL; static char *opt_class = NULL; static char *opt_font = NULL; +static char *opt_line = NULL; static int oldbutton = 3; /* button event on startup: 3 = release */ static char *usedfont = NULL; @@ -671,7 +673,8 @@ y2row(int y) { return LIMIT(y, 0, term.row-1); } -int tlinelen(int y) { +int +tlinelen(int y) { int i = term.col; if(term.line[y][i - 1].mode & ATTR_WRAP) @@ -1253,11 +1256,55 @@ sigchld(int a) { exit(EXIT_SUCCESS); } + +void +stty(void) +{ + char cmd[_POSIX_ARG_MAX], **p, *q, *s; + size_t n, siz; + + if((n = strlen(stty_args)) > sizeof(cmd)-1) + die("incorrect stty parameters\n"); + memcpy(cmd, stty_args, n); + q = cmd + n; + siz = sizeof(cmd) - n; + for(p = opt_cmd; p && (s = *p); ++p) { + if((n = strlen(s)) > siz-1) + die("stty parameter length too long\n"); + *q++ = ' '; + q = memcpy(q, s, n); + q += n; + siz-= n + 1; + } + *q = '\0'; + system(cmd); +} + void ttynew(void) { int m, s; struct winsize w = {term.row, term.col, 0, 0}; + if(opt_io) { + term.mode |= MODE_PRINT; + iofd = (!strcmp(opt_io, "-")) ? + STDOUT_FILENO : + open(opt_io, O_WRONLY | O_CREAT, 0666); + if(iofd < 0) { + fprintf(stderr, "Error opening %s:%s\n", + opt_io, strerror(errno)); + } + } + + if (opt_line) { + if((cmdfd = open(opt_line, O_RDWR)) < 0) + die("open line failed: %s\n", strerror(errno)); + close(STDIN_FILENO); + dup(cmdfd); + stty(); + return; + } + /* seems to work fine on linux, openbsd and freebsd */ if(openpty(&m, &s, NULL, NULL, &w) < 0) die("openpty failed: %s\n", strerror(errno)); @@ -1267,6 +1314,7 @@ ttynew(void) { die("fork failed\n"); break; case 0: + close(iofd); setsid(); /* create a new process group */ dup2(s, STDIN_FILENO); dup2(s, STDOUT_FILENO); @@ -1281,16 +1329,6 @@ ttynew(void) { close(s); cmdfd = m; signal(SIGCHLD, sigchld); - if(opt_io) { - term.mode |= MODE_PRINT; - iofd = (!strcmp(opt_io, "-")) ? - STDOUT_FILENO : - open(opt_io, O_WRONLY | O_CREAT, 0666); - if(iofd < 0) { - fprintf(stderr, "Error opening %s:%s\n", - opt_io, strerror(errno)); - } - } break; } } @@ -2788,8 +2826,11 @@ tresize(int col, int row) { free(term.line[i]); free(term.alt[i]); } - memmove(term.line, term.line + i, row * sizeof(Line)); - memmove(term.alt, term.alt + i, row * sizeof(Line)); + /* ensure that both src and dst are not NULL */ + if (i > 0) { + memmove(term.line, term.line + i, row * sizeof(Line)); + memmove(term.alt, term.alt + i, row * sizeof(Line)); + } for(i += row; i < term.row; i++) { free(term.line[i]); free(term.alt[i]); @@ -3962,8 +4003,7 @@ run(void) { dodraw = 1; } deltatime = TIMEDIFF(now, last); - if(deltatime > (xev? (1000/xfps) : (1000/actionfps)) - || deltatime < 0) { + if(deltatime > 1000 / (xev ? xfps : actionfps)) { dodraw = 1; last = now; } @@ -4006,9 +4046,12 @@ run(void) { void usage(void) { - die("%s " VERSION " (c) 2010-2015 st engineers\n" \ + die("%s " VERSION " (c) 2010-2015 st engineers\n" "usage: st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" - " [-i] [-t title] [-w windowid] [-e command ...]\n", argv0); + " [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n" + " st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" + " [-i] [-t title] [-w windowid] [-l line] [stty_args ...]\n", + argv0); } int @@ -4027,12 +4070,8 @@ main(int argc, char *argv[]) { opt_class = EARGF(usage()); break; case 'e': - /* eat all remaining arguments */ - if(argc > 1) { - opt_cmd = &argv[1]; - if(argv[1] != NULL && opt_title == NULL) - opt_title = basename(xstrdup(argv[1])); - } + if(argc > 1) + --argc, ++argv; goto run; case 'f': opt_font = EARGF(usage()); @@ -4047,6 +4086,9 @@ main(int argc, char *argv[]) { case 'o': opt_io = EARGF(usage()); break; + case 'l': + opt_line = EARGF(usage()); + break; case 't': opt_title = EARGF(usage()); break; @@ -4059,6 +4101,12 @@ main(int argc, char *argv[]) { } ARGEND; run: + if(argc > 0) { + /* eat all remaining arguments */ + opt_cmd = argv; + if(!opt_title) + opt_title = basename(xstrdup(argv[0])); + } setlocale(LC_CTYPE, ""); XSetLocaleModifiers(""); tnew(MAX(cols, 1), MAX(rows, 1));