tftp(1): Fix libedit state corruption involving signals
This bug was first reported 14 years ago. The problem was understood 8.5 years ago. A patch that is functionally identical to this one was proposed almost 8 years ago and languished in the PR system / Bugzilla. PR: 63197 Submitted by: lxv AT omut.org, fernando.apesteguia AT gmail.com Reported by: freebsd AT nbritton.org
This commit is contained in:
parent
16c0c8eeec
commit
49fb06154b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=329077
@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -114,7 +115,7 @@ static void setoptions(int, char **);
|
|||||||
static void setrollover(int, char **);
|
static void setrollover(int, char **);
|
||||||
static void setpacketdrop(int, char **);
|
static void setpacketdrop(int, char **);
|
||||||
|
|
||||||
static void command(void) __dead2;
|
static void command(bool, EditLine *, History *, HistEvent *) __dead2;
|
||||||
static const char *command_prompt(void);
|
static const char *command_prompt(void);
|
||||||
|
|
||||||
static void urihandling(char *URI);
|
static void urihandling(char *URI);
|
||||||
@ -176,11 +177,28 @@ static struct modes {
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
HistEvent he;
|
||||||
|
EditLine *el;
|
||||||
|
History *hist;
|
||||||
|
bool interactive;
|
||||||
|
|
||||||
acting_as_client = 1;
|
acting_as_client = 1;
|
||||||
peer = -1;
|
peer = -1;
|
||||||
strcpy(mode, "netascii");
|
strcpy(mode, "netascii");
|
||||||
signal(SIGINT, intr);
|
signal(SIGINT, intr);
|
||||||
|
|
||||||
|
interactive = isatty(STDIN_FILENO);
|
||||||
|
if (interactive) {
|
||||||
|
el = el_init("tftp", stdin, stdout, stderr);
|
||||||
|
hist = history_init();
|
||||||
|
history(hist, &he, H_SETSIZE, 100);
|
||||||
|
el_set(el, EL_HIST, history, hist);
|
||||||
|
el_set(el, EL_EDITOR, "emacs");
|
||||||
|
el_set(el, EL_PROMPT, command_prompt);
|
||||||
|
el_set(el, EL_SIGNAL, 1);
|
||||||
|
el_source(el, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if (setjmp(toplevel) != 0)
|
if (setjmp(toplevel) != 0)
|
||||||
exit(txrx_error);
|
exit(txrx_error);
|
||||||
@ -192,11 +210,15 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
setpeer(argc, argv);
|
setpeer(argc, argv);
|
||||||
}
|
}
|
||||||
if (setjmp(toplevel) != 0)
|
|
||||||
|
if (setjmp(toplevel) != 0) {
|
||||||
|
if (interactive)
|
||||||
|
el_reset(el);
|
||||||
(void)putchar('\n');
|
(void)putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
init_options();
|
init_options();
|
||||||
command();
|
command(interactive, el, hist, &he);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -703,36 +725,22 @@ command_prompt(void)
|
|||||||
* Command parser.
|
* Command parser.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
command(void)
|
command(bool interactive, EditLine *el, History *hist, HistEvent *hep)
|
||||||
{
|
{
|
||||||
HistEvent he;
|
|
||||||
struct cmd *c;
|
struct cmd *c;
|
||||||
static EditLine *el;
|
|
||||||
static History *hist;
|
|
||||||
const char *bp;
|
const char *bp;
|
||||||
char *cp;
|
char *cp;
|
||||||
int len, num, vrbose;
|
int len, num;
|
||||||
char line[MAXLINE];
|
char line[MAXLINE];
|
||||||
|
|
||||||
vrbose = isatty(0);
|
|
||||||
if (vrbose) {
|
|
||||||
el = el_init("tftp", stdin, stdout, stderr);
|
|
||||||
hist = history_init();
|
|
||||||
history(hist, &he, H_SETSIZE, 100);
|
|
||||||
el_set(el, EL_HIST, history, hist);
|
|
||||||
el_set(el, EL_EDITOR, "emacs");
|
|
||||||
el_set(el, EL_PROMPT, command_prompt);
|
|
||||||
el_set(el, EL_SIGNAL, 1);
|
|
||||||
el_source(el, NULL);
|
|
||||||
}
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (vrbose) {
|
if (interactive) {
|
||||||
if ((bp = el_gets(el, &num)) == NULL || num == 0)
|
if ((bp = el_gets(el, &num)) == NULL || num == 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
len = MIN(MAXLINE, num);
|
len = MIN(MAXLINE, num);
|
||||||
memcpy(line, bp, len);
|
memcpy(line, bp, len);
|
||||||
line[len] = '\0';
|
line[len] = '\0';
|
||||||
history(hist, &he, H_ENTER, bp);
|
history(hist, hep, H_ENTER, bp);
|
||||||
} else {
|
} else {
|
||||||
line[0] = 0;
|
line[0] = 0;
|
||||||
if (fgets(line, sizeof line , stdin) == NULL) {
|
if (fgets(line, sizeof line , stdin) == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user