131 lines
2.6 KiB
C
131 lines
2.6 KiB
C
#include <termios.h>
|
|
#include <time.h>
|
|
#include <assert.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
#include <limits.h>
|
|
|
|
static char *last_line = NULL;
|
|
|
|
int lnblnk_(char *c, int c_len);
|
|
char *readline(char *prompt);
|
|
void add_history(char *line_read);
|
|
int usleep(time_t delay);
|
|
|
|
void sys_rd_line_(char *cmd, int *retlen, char *prompt, int clen, int plen)
|
|
{
|
|
char *line_read, *p;
|
|
int l;
|
|
|
|
l = lnblnk_(prompt, clen);
|
|
p = malloc((unsigned) l+2); if( p == NULL ) return;
|
|
strncpy(p+1,prompt,l); p[0]='\n'; p[l] = '\0';
|
|
if (last_line == NULL) { last_line =malloc(1); last_line[0] = '\0';};
|
|
|
|
line_read = readline(p);
|
|
free(p);
|
|
|
|
if (line_read)
|
|
{
|
|
if (*line_read && strcmp(last_line, line_read)!=0)
|
|
add_history (line_read);
|
|
free (last_line);
|
|
strncpy(cmd, line_read, clen);
|
|
*retlen=strlen(line_read);
|
|
last_line = line_read;
|
|
if (*retlen>clen) *retlen=clen;
|
|
} else {
|
|
*retlen=-1;
|
|
}
|
|
}
|
|
|
|
|
|
void intcatch(int sig)
|
|
{ printf("\nuse quit (normally ctrl-\\) to interrupt\n");
|
|
}
|
|
|
|
int called=0; /* env is valid only if called==1 */
|
|
jmp_buf env;
|
|
|
|
void (*inthdl)(int sig);
|
|
void (*errhdl)();
|
|
|
|
void sighdl(int sig)
|
|
{ if (called) longjmp(env,sig);
|
|
}
|
|
|
|
void sys_err_hdl_(void errhdl0())
|
|
{ errhdl=errhdl0; }
|
|
|
|
void sys_int_hdl_(void inthdl0(int sig))
|
|
{ inthdl=inthdl0; }
|
|
|
|
void sys_try_(void proc())
|
|
{ int sig, status;
|
|
void (*sgh[32]) (int);
|
|
|
|
assert(!called); /* nested calls not allowed */
|
|
called=1;
|
|
sgh[SIGFPE] =signal(SIGFPE, sighdl);
|
|
sgh[SIGINT] =signal(SIGINT, *inthdl);
|
|
status=setjmp(env);
|
|
if (status==0) /* first return of setjmp */
|
|
{ proc(); }
|
|
else
|
|
{ (*errhdl)(); };
|
|
signal(SIGFPE, sgh[SIGFPE]);
|
|
signal(SIGINT, intcatch);
|
|
called=0;
|
|
}
|
|
|
|
void sys_abort_()
|
|
{ if (called) longjmp(env,-2);
|
|
}
|
|
|
|
|
|
void sys_exit_hdl_(void hdl())
|
|
{ int res;
|
|
res=atexit(hdl);
|
|
}
|
|
|
|
struct termios atts;
|
|
|
|
void sys_get_raw_key_(char *key, int *tmo, int k_len)
|
|
{
|
|
struct termios attr;
|
|
int ires, ntmo, chr;
|
|
|
|
ires=tcgetattr(STDIN_FILENO,&attr);
|
|
atts=attr; /* save term. attr. */
|
|
if (ires!=0) {perror("***\n");}
|
|
attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */
|
|
attr.c_cc[VMIN]=0;
|
|
ires= tcsetattr(STDIN_FILENO,TCSANOW,&attr);
|
|
if (ires!=0) {perror("***\n");}
|
|
|
|
/*
|
|
ires=fflush(stdin);
|
|
ires=fflush(stderr);
|
|
*/
|
|
|
|
ntmo=*tmo*100;
|
|
chr=fgetc(stdin);
|
|
if (chr==EOF) {
|
|
while ((chr==EOF) & (ntmo>0)) {
|
|
usleep(10000); /* wait 10 ms */
|
|
chr=fgetc(stdin);
|
|
ntmo--;
|
|
}
|
|
}
|
|
if (chr==EOF) chr=0;
|
|
|
|
*key=chr;
|
|
|
|
ires=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */
|
|
if (ires!=0) {perror("***\n");};
|
|
}
|