read_string.c revision 55682
1/* 2 * Copyright (c) 1997 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "login_locl.h" 35 36RCSID("$Id: read_string.c,v 1.3 1999/12/02 17:04:56 joda Exp $"); 37 38static sig_atomic_t intr_flag; 39 40static void 41intr(int sig) 42{ 43 intr_flag++; 44} 45 46int 47read_string(const char *prompt, char *buf, size_t len, int echo) 48{ 49 struct sigaction sigs[47]; 50 struct sigaction sa; 51 FILE *tty; 52 int ret = 0; 53 int of = 0; 54 int i; 55 int c; 56 char *p; 57 58 struct termios t_new, t_old; 59 60 memset(&sa, 0, sizeof(sa)); 61 sa.sa_handler = intr; 62 sigemptyset(&sa.sa_mask); 63 sa.sa_flags = 0; 64 for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++) 65 sigaction(i, &sa, &sigs[i]); 66 67 if((tty = fopen("/dev/tty", "r")) == NULL) 68 tty = stdin; 69 70 fprintf(stderr, "%s", prompt); 71 fflush(stderr); 72 73 if(echo == 0){ 74 tcgetattr(fileno(tty), &t_old); 75 memcpy(&t_new, &t_old, sizeof(t_new)); 76 t_new.c_lflag &= ~ECHO; 77 tcsetattr(fileno(tty), TCSANOW, &t_new); 78 } 79 intr_flag = 0; 80 p = buf; 81 while(intr_flag == 0){ 82 c = getc(tty); 83 if(c == EOF){ 84 if(!ferror(tty)) 85 ret = 1; 86 break; 87 } 88 if(c == '\n') 89 break; 90 if(of == 0) 91 *p++ = c; 92 of = (p == buf + len); 93 } 94 if(of) 95 p--; 96 *p = 0; 97 98 if(echo == 0){ 99 printf("\n"); 100 tcsetattr(fileno(tty), TCSANOW, &t_old); 101 } 102 103 if(tty != stdin) 104 fclose(tty); 105 106 for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++) 107 sigaction(i, &sigs[i], NULL); 108 109 if(ret) 110 return -3; 111 if(intr_flag) 112 return -2; 113 if(of) 114 return -1; 115 return 0; 116} 117 118 119#if 0 120int main() 121{ 122 char s[128]; 123 int ret; 124 ret = read_string("foo: ", s, sizeof(s), 0); 125 printf("%d ->%s<-\n", ret, s); 126} 127#endif 128