/*termial signal handler*/ static void term_sig_handler(int sig) { switch (sig) { case SIGINT: if (cmd_promptp) printf("\n%s", cmd_promptp); while (cmd_strlen-- > 0) cmd_strp[cmd_strlen] = '\0'; cmd_strp[0] = '\0'; cmd_strlen = 0; term_cursor = strlen(cmd_promptp); cmd_cursor = 0; fflush(stdout); break; case SIGUSR1: case SIGKILL: case SIGABRT: case SIGTERM: case SIGHUP: printf("exit.\n"); term_restore(); exit(0); default: break; } }
void safe_exit(int code) { char *dummy, *dammy; dump_close(); #ifdef HAVE_TERMIOS if(param.term_ctrl) term_restore(); #endif if(have_output) exit_output(ao, intflag); if(mh != NULL) mpg123_delete(mh); if(cleanup_mpg123) mpg123_exit(); httpdata_free(&htd); #ifdef WANT_WIN32_UNICODE win32_cmdline_free(argc, argv); /* This handles the premature argv == NULL, too. */ #endif #if defined (WANT_WIN32_SOCKETS) win32_net_deinit(); #endif /* It's ugly... but let's just fix this still-reachable memory chunk of static char*. */ split_dir_file("", &dummy, &dammy); exit(code); }
si_t application_exit() { struct object * addr; si_t i, n; /** * release focus list **/ list_exit(&(global_application.focus_list)); /* 有多少个窗口 */ n = vector_size(&(global_application.window_vector)); /* 依次删除窗口 */ for(i = n - 1; i >= 0; -- i) { addr = vector_at(&(global_application.window_vector), i); /* 这里没有逐个注销窗口类对象或者它的派生类对象。 因为窗口管理程序收到用户应用程序的退出请求后, 会释放关于这个用户应用程序的所有资源。 */ /* 释放这棵树 */ object_tree_free(addr->parent); /* 从窗口向量中删除这个节点 */ vector_erase(&(global_application.window_vector), i); } vector_exit(&(global_application.window_vector)); if(0 != cancel_application()) { EGUI_PRINT_ERROR("failed to cancle application"); } event_listener_exit(&global_application.app_event_listener); queue_exit(&global_application.message_queue); uds_exit(&global_application.uds); free(global_application.name); free(global_application.icon_root_path); term_restore(); return 0; }
int PMAPI PM_getch(void) { int c; if (term_raw() == -1) return (0); c = getc(stdin); #if defined(__QNX__) && !defined(__QNXNTO__) if (c == 0xA) c = 0x0D; else if (c == 0x7F) c = 0x08; #endif term_restore(); return c; }
int PMAPI PM_kbhit(void) { int blocking, c; if (term_raw() == -1) return 0; /* Go into non blocking mode */ blocking = fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK; fcntl(STDIN_FILENO, F_SETFL, blocking); c = getc(stdin); /* restore blocking mode */ fcntl(STDIN_FILENO, F_SETFL, blocking & ~O_NONBLOCK); term_restore(); if (c != EOF) { ungetc(c, stdin); return c; } clearerr(stdin); return 0; }
/*call by main*/ int next_cmd(char *out_cmd) { unsigned char c = 0; int key_no = 0; int seq_char = 0; int str_valid = 0; /*set terminal new attrib */ term_config(); /*termial initial */ term_init(out_cmd); /*main loop */ while ((c = getc(stdin)) != '\n') { key_no = 0; seq_char = 0; if (!_isspace(c)) { str_valid = 1; } if (c == 27) { /*escape sequence */ if ((c = getc(stdin)) == '[' || c == 'O') { c = getc(stdin); seq_char = 1; } } /*search for bind key handle function */ while (key_no < sizeof (key_bind) / sizeof (key_bind[0])) { if ((seq_char == key_bind[key_no].is_eseq) && (c == key_bind[key_no].key_last)) { key_bind[key_no].func(); break; } key_no++; } if (key_no == sizeof (key_bind) / sizeof (key_bind[0])) handle_normal(out_cmd, c); } /*handle enter when at the end of a line */ if (term_cursor) putchar('\n'); /* record command history without '\n' */ history_record(out_cmd); #if 0 /* add '\n' to out_cmd */ if (str_valid) { out_cmd[cmd_strlen++] = '\n'; } else { cmd_strlen = 0; out_cmd[cmd_strlen++] = '\n'; } if (cmd_strlen > 1 && out_cmd[cmd_strlen - 1] == '\n') out_cmd[cmd_strlen - 1] = 0; #else if (!str_valid) cmd_strlen = 0; #endif /*retore terminal to orginal status */ term_restore(); fflush(stdout); return cmd_strlen; }
void tty_detached(struct ttys *ttyp, int exiting) { struct ttys *ttyp_tmp, *ttyp_last = 0; DEBUG_CALL("tty_detached"); DEBUG_ARG("ttyp = %lx", (long)ttyp); DEBUG_ARG("exiting = %d", exiting); /* First, remove ttyp from the queue */ if (ttyp == ttys) { ttys = ttys->next; } else { for (ttyp_tmp = ttys; ttyp_tmp; ttyp_tmp = ttyp_tmp->next) { if (ttyp_tmp == ttyp) break; ttyp_last = ttyp_tmp; } if (!ttyp_last) { /* XXX */ /* Can't find it *shrug* */ return; } ttyp_last->next = ttyp->next; } term_restore(ttyp); #ifdef FULL_BOLT fd_block(ttyp->fd); #endif /* Restore device mode */ if (ttyp->mode) fchmod(ttyp->fd, ttyp->mode); /* Bring the link down */ #ifdef USE_PPP /* * Call lcp_lowerdown if it's ppp */ if (ttyp->proto == PROTO_PPP) { lcp_lowerdown(ttyp->unit); phase = PHASE_DEAD; /* XXXXX */ } #endif /* * Kill the guardian, if it exists */ if (ttyp->pid) kill(ttyp->pid, SIGQUIT); /* * If this was the last tty and we're not restarting, exit */ if (!ttys && slirp_socket < 0 && !exiting) slirp_exit(0); close(ttyp->fd); if (ttyp->m) m_free(ttyp->m); /* * If this was the controlling tty, call ctty_detached */ if ((ttyp->flags & TTY_CTTY) && !exiting) ctty_detached(); #ifdef USE_PPP /* Deallocate compress data */ ppp_ccp_closed(ttyp); #endif ttys_unit[ttyp->unit] = 0; /* * If you love it, set it free() ... * If it comes back, we have a memory leak */ free(ttyp); detach_time = curtime; }
int main(int argc, char *argv[]) { int ch, idx, plen, nready, interactive = 0, listonly = 0; const char *id, *user = NULL, *pattern = NULL, *tty = NULL, *decimal = "."; char path[PATH_MAX], buf[LINE_MAX], *cp, *ep; double seconds, to_wait, speed = 1.0, max_wait = 0; FILE *lfile; fd_set *fdsw; sigaction_t sa; size_t len, nbytes, nread, off; ssize_t nwritten; #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME) setprogname(argc > 0 ? argv[0] : "sudoreplay"); #endif #ifdef HAVE_SETLOCALE setlocale(LC_ALL, ""); decimal = localeconv()->decimal_point; #endif while ((ch = getopt(argc, argv, "d:f:hlm:s:V")) != -1) { switch(ch) { case 'd': session_dir = optarg; break; case 'f': /* Set the replay filter. */ replay_filter = 0; for (cp = strtok(optarg, ","); cp; cp = strtok(NULL, ",")) { if (strcmp(cp, "stdout") == 0) SET(replay_filter, 1 << IOFD_STDOUT); else if (strcmp(cp, "stderr") == 0) SET(replay_filter, 1 << IOFD_STDERR); else if (strcmp(cp, "ttyout") == 0) SET(replay_filter, 1 << IOFD_TTYOUT); else errorx(1, "invalid filter option: %s", optarg); } break; case 'h': help(); /* NOTREACHED */ case 'l': listonly = 1; break; case 'm': errno = 0; max_wait = strtod(optarg, &ep); if (*ep != '\0' || errno != 0) errorx(1, "invalid max wait: %s", optarg); break; case 's': errno = 0; speed = strtod(optarg, &ep); if (*ep != '\0' || errno != 0) errorx(1, "invalid speed factor: %s", optarg); break; case 'V': (void) printf("%s version %s\n", getprogname(), PACKAGE_VERSION); exit(0); default: usage(1); /* NOTREACHED */ } } argc -= optind; argv += optind; if (listonly) exit(list_sessions(argc, argv, pattern, user, tty)); if (argc != 1) usage(1); /* 6 digit ID in base 36, e.g. 01G712AB */ id = argv[0]; if (!VALID_ID(id)) errorx(1, "invalid ID %s", id); plen = snprintf(path, sizeof(path), "%s/%.2s/%.2s/%.2s/timing", session_dir, id, &id[2], &id[4]); if (plen <= 0 || plen >= sizeof(path)) errorx(1, "%s/%.2s/%.2s/%.2s/%.2s/timing: %s", session_dir, id, &id[2], &id[4], strerror(ENAMETOOLONG)); plen -= 7; /* Open files for replay, applying replay filter for the -f flag. */ for (idx = 0; idx < IOFD_MAX; idx++) { if (ISSET(replay_filter, 1 << idx) || idx == IOFD_TIMING) { io_fds[idx].v = open_io_fd(path, plen, io_fnames[idx]); if (io_fds[idx].v == NULL) error(1, "unable to open %s", path); } } /* Read log file. */ path[plen] = '\0'; strlcat(path, "/log", sizeof(path)); lfile = fopen(path, "r"); if (lfile == NULL) error(1, "unable to open %s", path); cp = NULL; len = 0; /* Pull out command (third line). */ if (getline(&cp, &len, lfile) == -1 || getline(&cp, &len, lfile) == -1 || getline(&cp, &len, lfile) == -1) { errorx(1, "invalid log file %s", path); } printf("Replaying sudo session: %s", cp); free(cp); fclose(lfile); fflush(stdout); zero_bytes(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESETHAND; sa.sa_handler = cleanup; (void) sigaction(SIGINT, &sa, NULL); (void) sigaction(SIGKILL, &sa, NULL); (void) sigaction(SIGTERM, &sa, NULL); (void) sigaction(SIGHUP, &sa, NULL); sa.sa_flags = SA_RESTART; sa.sa_handler = SIG_IGN; (void) sigaction(SIGTSTP, &sa, NULL); (void) sigaction(SIGQUIT, &sa, NULL); /* XXX - read user input from /dev/tty and set STDOUT to raw if not a pipe */ /* Set stdin to raw mode if it is a tty */ interactive = isatty(STDIN_FILENO); if (interactive) { ch = fcntl(STDIN_FILENO, F_GETFL, 0); if (ch != -1) (void) fcntl(STDIN_FILENO, F_SETFL, ch | O_NONBLOCK); if (!term_raw(STDIN_FILENO, 1)) error(1, "cannot set tty to raw mode"); } fdsw = (fd_set *)emalloc2(howmany(STDOUT_FILENO + 1, NFDBITS), sizeof(fd_mask)); /* * Timing file consists of line of the format: "%f %d\n" */ #ifdef HAVE_ZLIB_H while (gzgets(io_fds[IOFD_TIMING].g, buf, sizeof(buf)) != NULL) { #else while (fgets(buf, sizeof(buf), io_fds[IOFD_TIMING].f) != NULL) { #endif if (!parse_timing(buf, decimal, &idx, &seconds, &nbytes)) errorx(1, "invalid timing file line: %s", buf); if (interactive) check_input(STDIN_FILENO, &speed); /* Adjust delay using speed factor and clamp to max_wait */ to_wait = seconds / speed; if (max_wait && to_wait > max_wait) to_wait = max_wait; delay(to_wait); /* Even if we are not relaying, we still have to delay. */ if (io_fds[idx].v == NULL) continue; /* All output is sent to stdout. */ while (nbytes != 0) { if (nbytes > sizeof(buf)) len = sizeof(buf); else len = nbytes; #ifdef HAVE_ZLIB_H nread = gzread(io_fds[idx].g, buf, len); #else nread = fread(buf, 1, len, io_fds[idx].f); #endif nbytes -= nread; off = 0; do { /* no stdio, must be unbuffered */ nwritten = write(STDOUT_FILENO, buf + off, nread - off); if (nwritten == -1) { if (errno == EINTR) continue; if (errno == EAGAIN) { FD_SET(STDOUT_FILENO, fdsw); do { nready = select(STDOUT_FILENO + 1, NULL, fdsw, NULL, NULL); } while (nready == -1 && errno == EINTR); if (nready == 1) continue; } error(1, "writing to standard output"); } off += nwritten; } while (nread > off); } } term_restore(STDIN_FILENO, 1); exit(0); } static void delay(double secs) { struct timespec ts, rts; int rval; /* * Typical max resolution is 1/HZ but we can't portably check that. * If the interval is small enough, just ignore it. */ if (secs < 0.0001) return; rts.tv_sec = secs; rts.tv_nsec = (secs - (double) rts.tv_sec) * 1000000000.0; do { memcpy(&ts, &rts, sizeof(ts)); rval = nanosleep(&ts, &rts); } while (rval == -1 && errno == EINTR); if (rval == -1) error(1, "nanosleep: tv_sec %ld, tv_nsec %ld", ts.tv_sec, ts.tv_nsec); } static void * open_io_fd(char *path, int len, const char *suffix) { path[len] = '\0'; strlcat(path, suffix, PATH_MAX); #ifdef HAVE_ZLIB_H return gzopen(path, "r"); #else return fopen(path, "r"); #endif }