⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getkey.c

📁 des算法实现源码
💻 C
字号:
/* * Getkey: * * A machine dependent function to prompt for and read a keystring from stdin * * Input: *   prompt - A string output to display prior to requesting input *   str    - where to put the characters *   size   - the number of storage locations reserved for the key - 1 *     * Returns:  *    The number of characters read (not counting terminating '\n') * * Display a prompt on the screen (not stdout!) before entry.  * Reads in upto <size> characters from the terminal (not stdin!).   * Terminated by EOF or '\n'.  * The trailing terminator is removed if present.   * String will be '\0' terminated if its less than size bytes.    * The characters are not echoed as they are typed. */#if !defined(__msdos) && !defined(__MSDOS__) && !defined(__BSD) /* { */#define _POSIX_SOURCE#include <unistd.h>	/* read write getpid */#include <termios.h>	/* termio stuff */#include <signal.h>	/* signal stuff */#include <string.h>	/* strlen */#include <fcntl.h>	/* O_RDWR */#include <stdio.h>	/* ctermid on dec alpha *//* * The type of a signal handler is declared inconsistantly in the header files. * Extremely picky compilers may require adjustment here; most don't complain. * The problem is what the type of signal's argument really is.  POSIX doesn't * state this precisely; what is the prototype of the signal handler's * declaration supposed to look like exactly?  Like Sun, I would guess  *     void handler(int,...)  * but most vendors use void handler(). Sigh. */#if defined(_HPUX_SOURCE) && defined(__cplusplus)typedef void (*pfv)(int);			/* HPUX 9.0 C++ */#elsetypedef void (*pfv)();				/* POSIX (normal case) *//* typedef void (*pfv)(int, ...);		/* sunOS 4.1.2 C++ */#endif/* * Signal with posix signal semantics */static pfv psignal(sig, handler)   int sig;   pfv handler;{   struct sigaction sact, oact;   int res;   sact.sa_handler = handler; /* some compilers break here; see typedef pfv */   sact.sa_flags   = 0;   sigemptyset(&sact.sa_mask);   res = sigaction(sig, &sact, &oact);   if (res < 0) {      return (pfv) -1;   }   return (pfv) oact.sa_handler;}/* * Set tty echo on(1) or off(0); returns previous setting or -1 */static int setTtyEcho(fd, echo)   int fd;   int echo;{   register int res, oldecho;   struct termios modes;   res = tcgetattr(fd, &modes);   if (res < 0) return -1;       oldecho = ((modes.c_lflag & ECHO) != 0);   if (echo) {      modes.c_lflag |= ECHO;   } else {      modes.c_lflag &= ~ECHO;   }   res = tcsetattr(fd, TCSANOW, &modes);   if (res < 0) return -2;   return oldecho;}static int oldEcho = 1;		/* previous tty echo state */static int ttyfd   = -1;	/* controlling terminal */pfv    	   oldsigint;		/* previous handler */static void restoreEcho(sig)    int sig;{   if (ttyfd >= 0) {      setTtyEcho(ttyfd, oldEcho);      close(ttyfd);   }   (void) psignal(SIGINT, oldsigint);	/* restore old handler */   kill(getpid(), SIGINT);		/* invoke old handler on return */}/* * Display prompt to the screen, read from the keyboard without echo until CR. */int getkey(prompt, str, size)   char *prompt;   char *str;   register unsigned size;{   unsigned len = strlen(prompt);   register int count;   register char *chp = str;   register int res = -1;   char ch;    ttyfd = open(ctermid((char *) 0), O_RDWR);   if (ttyfd < 0) return -1;   oldsigint = psignal(SIGINT, restoreEcho);   oldEcho   = setTtyEcho(ttyfd, 0);   count = write(ttyfd, prompt, len);   if (count != len) return -1;   if (size != 0) do {      count = read(ttyfd, &ch, 1);      if (count == 0) break;      if (count != 1) break;      if (ch == '\n') break;      *chp++ = ch;   } while (--size != 0);   if (count >= 0) {      res =  chp - str;   }   *chp = '\0';   count = write(ttyfd, "\n", 1);			/* goto next line */   oldEcho = setTtyEcho(ttyfd, oldEcho);   psignal(SIGINT, oldsigint);   close(ttyfd);   ttyfd = -1;   return res;}#endif		/* } POSIX */#if defined(__msdos) || defined(__MSDOS__)	/* { */#include <dos.h>/* * Output a character to the console independent of I/O redirection */void conOut(ch)   int ch;{   union REGS regs;   regs.h.ah = 14 ;     /* INT 10h, function 0EH, for video driver */   regs.h.al = (unsigned char) ch;   int86(16, &regs, &regs) ;}/* * Input a character from the console independent of I/O redirection (no echo) */char conIn(){   union REGS regs;   regs.h.ah = 0 ; /* INT 16h, function 00H, get char from keyboard */   int86(22, &regs, &regs) ;   return (char) regs.h.al;}int getkey(prompt, str, size)   register char *prompt;   char *str;   register unsigned size;{   register int ch;   register char *chp = str;;   while (*prompt != '\0') {      conOut(*prompt++);                /* write char to console */   }   if (size != 0) do {      ch = conIn();             /* read char from console without echo */      if (ch == '\r') break;    /* carriage return */      *chp++ = ch;   } while (--size != 0);   if (size != 0) {      *chp = '\0';   }   conOut('\r');   conOut('\n');   return chp - str;}#endif 	/* } MSDOS */#if defined(__BSD)		/* Are you *sure* you don't have Posix? { *//* * This code taken from ciper's original release.  I don't mess with  * BSD-specific stuff anymore since POSIX now works almost everywhere * (including every BSD machine I can find these days). * * Tested on SunOS 4.1 on SPARC IPC (sun4c/40) 28-Mar-94 by Dave Barrett * (That OS *does* have POSIX; I just wanted to make *sure* BSD worked) */#include <string.h>#include <fcntl.h>#if defined(_LINUX_SOURCE)	/* or whatever linux cpp sets automagically */#include <bsd/sgtty.h>#else#include <sgtty.h>		/* *my* BSD manual says; works on Sun SPARC  */#endif#include <signal.h>int setEcho(fd, echo)   int fd;   int echo;{     struct sgttyb modes;   int res, oldecho;   res = ioctl(fd, TIOCGETP, &modes);   oldecho = modes.sg_flags & ECHO;   if (echo >= 0) {      if (echo) {	 modes.sg_flags |= ECHO;      } else {	 modes.sg_flags &= ~ECHO;      }      res = ioctl(fd, TIOCSETN, &modes);   }   return oldecho;}static void (*oldSigInt)();static int  oldEcho = 1;			/* assume echo was on */static int  fd = -1;void intHandler(){   setEcho(fd, oldEcho);			/* restore echoing */   close(fd);					/* close /dev/tty */   (void) signal(SIGINT, oldSigInt);		/* restore old handler */   kill(getpid(), SIGINT);			/* invoke old handler */}/* * A machine dependent function to prompt for and read a keystring from stdin * * Input: *   prompt - A string output to display prior to requesting input *   str    - where to put the characters *   size   - the number of storage locations reserved for the key *     * Returns:  *    The number of characters read (not counting terminating '\n') * * Reads in upto <size> characters from the terminal.  Terminated by EOF * or '\n'.  String will be '\0' terminated if its less than size bytes. */int getkey(prompt, str, size)   char *prompt;   char *str;   register unsigned size;{   int count, len;   char buf[1], *chp = str;;   fd = open("/dev/tty", O_RDWR);   if (fd < 0) return fd;   oldSigInt = signal(SIGINT, intHandler);   oldEcho = setEcho(fd, 0);		/* disable printing of input */   len   = strlen(prompt);   count = write(fd, prompt, len);   if (size != 0) do {      count = read(fd, buf, 1);      if (count != 1) break;      if (buf[0] == '\n') break;      *chp++ = buf[0];   } while (--size != 0);    if (size != 0) {      *chp = '\0';   }#if !defined(_LINUX_SOURCE)   /*    * This code is definitely correct on Sun BSD machines.  I'd like to    * know why it's wrong on some others.  Please send me mail if you disagree.    * Dave Barrett <barrett@asgard.cs.Colorado.EDU>    */   write(fd, "\n", 1);			/* goto next line */#endif   setEcho(fd, oldEcho);		/* restore echo to previous state */   (void) signal(SIGINT, oldSigInt);   close(fd);   return chp - str;}#endif /* } __BSD but not POSIX (must be an OLD machine) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -