script.c (4459abe334eb4dbd416fa8094a64afc065ccd1cc) | script.c (8ceac8e13dccbe4e177c8f2f443b87b7d2e3edb3) |
---|---|
1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2010, 2012 David E. O'Brien 5 * Copyright (c) 1980, 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 63 unchanged lines hidden (view full) --- 72static FILE *fscript; 73static int master, slave; 74static int child; 75static const char *fname; 76static char *fmfname; 77static int fflg, qflg, ttyflg; 78static int usesleep, rawout, showexit; 79static TAILQ_HEAD(, buf_elm) obuf_list = TAILQ_HEAD_INITIALIZER(obuf_list); | 1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2010, 2012 David E. O'Brien 5 * Copyright (c) 1980, 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 63 unchanged lines hidden (view full) --- 72static FILE *fscript; 73static int master, slave; 74static int child; 75static const char *fname; 76static char *fmfname; 77static int fflg, qflg, ttyflg; 78static int usesleep, rawout, showexit; 79static TAILQ_HEAD(, buf_elm) obuf_list = TAILQ_HEAD_INITIALIZER(obuf_list); |
80static volatile sig_atomic_t doresize; |
|
80 81static struct termios tt; 82 83#ifndef TSTAMP_FMT 84/* useful for tool and human reading */ 85# define TSTAMP_FMT "%n@ %s [%Y-%m-%d %T]%n" 86#endif 87static const char *tstamp_fmt = TSTAMP_FMT; 88static int tflg; 89 90static void done(int) __dead2; 91static void doshell(char **); 92static void finish(void); 93static void record(FILE *, char *, size_t, int); 94static void consume(FILE *, off_t, char *, int); 95static void playback(FILE *) __dead2; 96static void usage(void) __dead2; | 81 82static struct termios tt; 83 84#ifndef TSTAMP_FMT 85/* useful for tool and human reading */ 86# define TSTAMP_FMT "%n@ %s [%Y-%m-%d %T]%n" 87#endif 88static const char *tstamp_fmt = TSTAMP_FMT; 89static int tflg; 90 91static void done(int) __dead2; 92static void doshell(char **); 93static void finish(void); 94static void record(FILE *, char *, size_t, int); 95static void consume(FILE *, off_t, char *, int); 96static void playback(FILE *) __dead2; 97static void usage(void) __dead2; |
98static void resizeit(int); |
|
97 98int 99main(int argc, char *argv[]) 100{ 101 struct termios rtt, stt; 102 struct winsize win; | 99 100int 101main(int argc, char *argv[]) 102{ 103 struct termios rtt, stt; 104 struct winsize win; |
103 struct timeval tv, *tvp; | 105 struct timespec tv, *tvp; |
104 time_t tvec, start; 105 char obuf[BUFSIZ]; 106 char ibuf[BUFSIZ]; | 106 time_t tvec, start; 107 char obuf[BUFSIZ]; 108 char ibuf[BUFSIZ]; |
109 sigset_t *pselmask, selmask; |
|
107 fd_set rfd, wfd; 108 struct buf_elm *be; 109 ssize_t cc; | 110 fd_set rfd, wfd; 111 struct buf_elm *be; 112 ssize_t cc; |
110 int aflg, Fflg, kflg, pflg, ch, k, n, fcm; | 113 int aflg, Fflg, kflg, pflg, wflg, ch, k, n, fcm; |
111 int flushtime, readstdin; 112 int fm_fd, fm_log; 113 | 114 int flushtime, readstdin; 115 int fm_fd, fm_log; 116 |
114 aflg = Fflg = kflg = pflg = 0; | 117 aflg = Fflg = kflg = pflg = wflg = 0; 118 doresize = 0; |
115 usesleep = 1; 116 rawout = 0; 117 flushtime = 30; 118 fm_fd = -1; 119 showexit = 0; 120 | 119 usesleep = 1; 120 rawout = 0; 121 flushtime = 30; 122 fm_fd = -1; 123 showexit = 0; 124 |
121 while ((ch = getopt(argc, argv, "adeFfkpqrT:t:")) != -1) | 125 /* 126 * For normal operation, we'll leave pselmask == NULL so that pselect(2) 127 * leaves the signal mask alone. If -w is specified, we'll restore the 128 * process signal mask upon entry with SIGWINCH unblocked so that we can 129 * forward resize events properly. 130 */ 131 sigemptyset(&selmask); 132 pselmask = NULL; 133 134 while ((ch = getopt(argc, argv, "adeFfkpqrT:t:w")) != -1) |
122 switch (ch) { 123 case 'a': 124 aflg = 1; 125 break; 126 case 'd': 127 usesleep = 0; 128 break; 129 case 'e': --- 22 unchanged lines hidden (view full) --- 152 if (flushtime < 0) 153 err(1, "invalid flush time %d", flushtime); 154 break; 155 case 'T': 156 tflg = pflg = 1; 157 if (strchr(optarg, '%')) 158 tstamp_fmt = optarg; 159 break; | 135 switch (ch) { 136 case 'a': 137 aflg = 1; 138 break; 139 case 'd': 140 usesleep = 0; 141 break; 142 case 'e': --- 22 unchanged lines hidden (view full) --- 165 if (flushtime < 0) 166 err(1, "invalid flush time %d", flushtime); 167 break; 168 case 'T': 169 tflg = pflg = 1; 170 if (strchr(optarg, '%')) 171 tstamp_fmt = optarg; 172 break; |
173 case 'w': 174 wflg = 1; 175 break; |
|
160 case '?': 161 default: 162 usage(); 163 } 164 argc -= optind; 165 argv += optind; 166 167 if (argc > 0) { --- 87 unchanged lines hidden (view full) --- 255 if (ioctl(fm_fd, FILEMON_SET_PID, &pid) < 0) 256 err(1, "Cannot set filemon PID"); 257 } 258 259 doshell(argv); 260 } 261 close(slave); 262 | 176 case '?': 177 default: 178 usage(); 179 } 180 argc -= optind; 181 argv += optind; 182 183 if (argc > 0) { --- 87 unchanged lines hidden (view full) --- 271 if (ioctl(fm_fd, FILEMON_SET_PID, &pid) < 0) 272 err(1, "Cannot set filemon PID"); 273 } 274 275 doshell(argv); 276 } 277 close(slave); 278 |
279 if (wflg) { 280 struct sigaction sa = { .sa_handler = resizeit }; 281 sigset_t smask; 282 283 sigaction(SIGWINCH, &sa, NULL); 284 285 sigemptyset(&smask); 286 sigaddset(&smask, SIGWINCH); 287 288 if (sigprocmask(SIG_BLOCK, &smask, &selmask) != 0) 289 err(1, "Failed to block SIGWINCH"); 290 291 /* Just in case SIGWINCH was blocked before we came in. */ 292 sigdelset(&selmask, SIGWINCH); 293 pselmask = &selmask; 294 } 295 |
|
263 start = tvec = time(0); 264 readstdin = 1; 265 for (;;) { 266 FD_ZERO(&rfd); 267 FD_ZERO(&wfd); 268 FD_SET(master, &rfd); 269 if (readstdin) 270 FD_SET(STDIN_FILENO, &rfd); 271 if (!TAILQ_EMPTY(&obuf_list)) 272 FD_SET(master, &wfd); 273 if (!readstdin && ttyflg) { 274 tv.tv_sec = 1; | 296 start = tvec = time(0); 297 readstdin = 1; 298 for (;;) { 299 FD_ZERO(&rfd); 300 FD_ZERO(&wfd); 301 FD_SET(master, &rfd); 302 if (readstdin) 303 FD_SET(STDIN_FILENO, &rfd); 304 if (!TAILQ_EMPTY(&obuf_list)) 305 FD_SET(master, &wfd); 306 if (!readstdin && ttyflg) { 307 tv.tv_sec = 1; |
275 tv.tv_usec = 0; | 308 tv.tv_nsec = 0; |
276 tvp = &tv; 277 readstdin = 1; 278 } else if (flushtime > 0) { 279 tv.tv_sec = flushtime - (tvec - start); | 309 tvp = &tv; 310 readstdin = 1; 311 } else if (flushtime > 0) { 312 tv.tv_sec = flushtime - (tvec - start); |
280 tv.tv_usec = 0; | 313 tv.tv_nsec = 0; |
281 tvp = &tv; 282 } else { 283 tvp = NULL; 284 } | 314 tvp = &tv; 315 } else { 316 tvp = NULL; 317 } |
285 n = select(master + 1, &rfd, &wfd, NULL, tvp); | 318 n = pselect(master + 1, &rfd, &wfd, NULL, tvp, pselmask); |
286 if (n < 0 && errno != EINTR) 287 break; | 319 if (n < 0 && errno != EINTR) 320 break; |
321 322 if (doresize) { 323 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) != -1) 324 ioctl(master, TIOCSWINSZ, &win); 325 doresize = 0; 326 } 327 |
|
288 if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) { 289 cc = read(STDIN_FILENO, ibuf, BUFSIZ); 290 if (cc < 0) 291 break; 292 if (cc == 0) { 293 if (tcgetattr(master, &stt) == 0 && 294 (stt.c_lflag & ICANON) != 0) { 295 (void)write(master, &stt.c_cc[VEOF], 1); --- 58 unchanged lines hidden (view full) --- 354 finish(); 355 done(0); 356} 357 358static void 359usage(void) 360{ 361 (void)fprintf(stderr, | 328 if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) { 329 cc = read(STDIN_FILENO, ibuf, BUFSIZ); 330 if (cc < 0) 331 break; 332 if (cc == 0) { 333 if (tcgetattr(master, &stt) == 0 && 334 (stt.c_lflag & ICANON) != 0) { 335 (void)write(master, &stt.c_cc[VEOF], 1); --- 58 unchanged lines hidden (view full) --- 394 finish(); 395 done(0); 396} 397 398static void 399usage(void) 400{ 401 (void)fprintf(stderr, |
362 "usage: script [-aeFfkpqr] [-t time] [file [command ...]]\n"); | 402 "usage: script [-aeFfkpqrw] [-t time] [file [command ...]]\n"); |
363 (void)fprintf(stderr, 364 " script -p [-deq] [-T fmt] [file]\n"); 365 exit(1); 366} 367 368static void 369finish(void) 370{ --- 229 unchanged lines hidden (view full) --- 600 break; 601 default: 602 errx(1, "invalid direction"); 603 } 604 } 605 (void)fclose(fp); 606 exit(0); 607} | 403 (void)fprintf(stderr, 404 " script -p [-deq] [-T fmt] [file]\n"); 405 exit(1); 406} 407 408static void 409finish(void) 410{ --- 229 unchanged lines hidden (view full) --- 640 break; 641 default: 642 errx(1, "invalid direction"); 643 } 644 } 645 (void)fclose(fp); 646 exit(0); 647} |
648 649static void 650resizeit(int signo __unused) 651{ 652 doresize = 1; 653} |
|