Works now under OSF1 and Linux
This commit is contained in:
200
tecs/sys_linux_c.c
Normal file
200
tecs/sys_linux_c.c
Normal file
@@ -0,0 +1,200 @@
|
||||
#include <termios.h>
|
||||
#include <sys/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);
|
||||
|
||||
void sys_rd_line__(char *cmd, int *retlen, char *prompt, int clen, int plen)
|
||||
{
|
||||
char *line_read, p[64];
|
||||
|
||||
assert(plen < sizeof(p));
|
||||
strncpy(p,prompt,plen); p[plen] = '\0';
|
||||
if (last_line == NULL) { last_line =malloc(1); last_line[0] = '\0';};
|
||||
|
||||
line_read = readline(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);
|
||||
|
||||
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");};
|
||||
}
|
||||
|
||||
|
||||
void usleep_(int *usec) { usleep(*usec); }
|
||||
int getppid_(void) { return getppid(); }
|
||||
|
||||
int sys_setenv__(ename,evalue,ilen1,ilen2)
|
||||
char *ename, *evalue;
|
||||
int ilen1, ilen2;
|
||||
{
|
||||
int i1, i2, ow, rc;
|
||||
char *p1, *p2;
|
||||
|
||||
i1 = lnblnk_(ename,ilen1);
|
||||
i2 = lnblnk_(evalue,ilen2);
|
||||
|
||||
p1 = malloc((unsigned) i1+1); if( p1 == NULL ) return (-1);
|
||||
p2 = malloc((unsigned) i2+1); if( p2 == NULL ) { free(p1); return (-1); }
|
||||
|
||||
strncpy(p1,ename,i1); p1[i1] = '\0';
|
||||
strncpy(p2,evalue,i2); p2[i2] = '\0';
|
||||
|
||||
ow = 1;
|
||||
|
||||
rc = setenv(p1, p2, ow);
|
||||
free(p1); free(p2);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
|
||||
void sys_rd_tmo__(char *prompt, char *result, int *reslen, int p_len, int r_len)
|
||||
{
|
||||
struct termios atts;
|
||||
struct termios attr;
|
||||
int ires, i, 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");}
|
||||
|
||||
do { chr=fgetc(stdin); } while (chr!=EOF);
|
||||
|
||||
for (i=0; i<p_len; i++)
|
||||
{ fputc(prompt[i], stderr);
|
||||
};
|
||||
|
||||
ires=fflush(stdin);
|
||||
ires=fflush(stderr);
|
||||
|
||||
*reslen=0;
|
||||
if (prompt[0]=='\0') { ntmo=10; }
|
||||
else { ntmo=200; }; /* wait 2 sec. for the first char */
|
||||
while (*reslen<r_len)
|
||||
{ chr=fgetc(stdin);
|
||||
if (chr==EOF)
|
||||
{ while ((chr==EOF) & (ntmo>0))
|
||||
{ usleep(10000); /* wait 10 ms */
|
||||
chr=fgetc(stdin);
|
||||
ntmo--;
|
||||
};
|
||||
if (chr==EOF) break;
|
||||
if (chr==10) {ntmo=10;} else {ntmo=100;}; /* wait 0.1 sec after LF, 1 sec else */
|
||||
};
|
||||
result[(*reslen)++]=(char)chr;
|
||||
if (chr==24) {(*reslen)=0;}; /* ctrl-X purges buffer */
|
||||
};
|
||||
if (result[(*reslen)-1]=10) {(*reslen)--;}; /* strip trailing LF */
|
||||
|
||||
ires=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */
|
||||
if (ires!=0) {perror("***\n");};
|
||||
}
|
||||
Reference in New Issue
Block a user