101 lines
2.1 KiB
C
101 lines
2.1 KiB
C
#include <assert.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
#include <limits.h>
|
|
#include "myc_str.h"
|
|
#include "sys_util.h"
|
|
|
|
void F_FUN(sys_realpath)(F_CHAR(rpath), int *reslen, F_CHAR(path) F_CLEN(rpath) F_CLEN(path)) {
|
|
char p[PATH_MAX], rp[PATH_MAX], *pt;
|
|
|
|
STR_TO_C(p, path);
|
|
pt=realpath(p, rp);
|
|
if (pt==NULL) str_copy(rp, p);
|
|
*reslen=strlen(rp);
|
|
STR_TO_F(rpath, rp);
|
|
}
|
|
|
|
static char *last_line = NULL;
|
|
|
|
char *readline (char *prompt);
|
|
void add_history(const char *line);
|
|
|
|
void F_FUN(sys_rd_line)(F_CHAR(cmd), int *retlen, F_CHAR(prompt) F_CLEN(cmd) F_CLEN(prompt))
|
|
{
|
|
char *line_read;
|
|
char p0[64], p[64];
|
|
|
|
STR_TO_C(p0, prompt);
|
|
str_copy(p, "\n");
|
|
str_append(p, p0);
|
|
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);
|
|
STR_TO_F(cmd, line_read);
|
|
*retlen=strlen(line_read);
|
|
last_line = line_read;
|
|
if (*retlen>F_LEN(cmd)) *retlen=F_LEN(cmd);
|
|
} 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)=intcatch;
|
|
void (*errhdl)(void);
|
|
|
|
void sighdl(int sig)
|
|
{ if (called) longjmp(env,sig);
|
|
}
|
|
|
|
void F_FUN(sys_err_hdl)(void errhdl0(void))
|
|
{ errhdl=errhdl0; }
|
|
|
|
void F_FUN(sys_int_hdl)(void inthdl0(int sig))
|
|
{ inthdl=inthdl0; }
|
|
|
|
void F_FUN(sys_try)(void proc(void))
|
|
{ int 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 F_FUN(sys_abort)(void)
|
|
{ if (called) longjmp(env,-2);
|
|
}
|
|
|
|
|
|
void F_FUN(sys_exit_hdl)(void hdl(void))
|
|
{ int res;
|
|
res=atexit(hdl);
|
|
}
|