char* FAST_FUNC bb_askpass(int timeout, const char *prompt) { /* Was static char[BIGNUM] */ enum { sizeof_passwd = 128 }; static char *passwd; char *ret; int i; struct sigaction sa, oldsa; struct termios tio, oldtio; if (!passwd) passwd = xmalloc(sizeof_passwd); memset(passwd, 0, sizeof_passwd); tcgetattr(STDIN_FILENO, &oldtio); tcflush(STDIN_FILENO, TCIFLUSH); tio = oldtio; tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); tcsetattr(STDIN_FILENO, TCSANOW, &tio); memset(&sa, 0, sizeof(sa)); /* sa.sa_flags = 0; - no SA_RESTART! */ /* SIGINT and SIGALRM will interrupt read below */ sa.sa_handler = askpass_timeout; sigaction(SIGINT, &sa, &oldsa); if (timeout) { sigaction_set(SIGALRM, &sa); alarm(timeout); } fputs(prompt, stdout); fflush(stdout); ret = NULL; /* On timeout or Ctrl-C, read will hopefully be interrupted, * and we return NULL */ if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) { ret = passwd; i = 0; /* Last byte is guaranteed to be 0 (read did not overwrite it) */ do { if (passwd[i] == '\r' || passwd[i] == '\n') passwd[i] = '\0'; } while (passwd[i++]); } if (timeout) { alarm(0); } sigaction_set(SIGINT, &oldsa); tcsetattr(STDIN_FILENO, TCSANOW, &oldtio); bb_putchar('\n'); fflush(stdout); return ret; }
void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); /*sigemptyset(&sa.sa_mask);*/ sa.sa_flags = SA_RESTART; sa.sa_handler = handler; sigaction_set(sig, &sa); }
void bb_signals_recursive(int sigs, void (*f)(int)) { int sig_no = 0; int bit = 1; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = f; /*sa.sa_flags = 0;*/ /*sigemptyset(&sa.sa_mask); - hope memset did it*/ while (sigs) { if (sigs & bit) { sigs &= ~bit; sigaction_set(sig_no, &sa); } sig_no++; bit <<= 1; } }
char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) { /* Was static char[BIGNUM] */ enum { sizeof_passwd = 128 }; static char *passwd; char *ret; int i; struct sigaction sa, oldsa; struct termios tio, oldtio; tcgetattr(fd, &oldtio); tcflush(fd, TCIFLUSH); tio = oldtio; #ifndef IUCLC # define IUCLC 0 #endif tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); tcsetattr(fd, TCSANOW, &tio); memset(&sa, 0, sizeof(sa)); /* sa.sa_flags = 0; - no SA_RESTART! */ /* SIGINT and SIGALRM will interrupt reads below */ sa.sa_handler = askpass_timeout; sigaction(SIGINT, &sa, &oldsa); if (timeout) { sigaction_set(SIGALRM, &sa); alarm(timeout); } fputs(prompt, stdout); fflush_all(); if (!passwd) passwd = xmalloc(sizeof_passwd); ret = passwd; i = 0; while (1) { int r = read(fd, &ret[i], 1); if (r < 0) { /* read is interrupted by timeout or ^C */ ret = NULL; break; } if (r == 0 /* EOF */ || ret[i] == '\r' || ret[i] == '\n' /* EOL */ || ++i == sizeof_passwd-1 /* line limit */ ) { ret[i] = '\0'; break; } } if (timeout) { alarm(0); } sigaction_set(SIGINT, &oldsa); tcsetattr(fd, TCSANOW, &oldtio); bb_putchar('\n'); fflush_all(); return ret; }