svn commit: r329077 - head/usr.bin/tftp
Conrad Meyer
cem at FreeBSD.org
Fri Feb 9 19:46:53 UTC 2018
Author: cem
Date: Fri Feb 9 19:46:51 2018
New Revision: 329077
URL: https://svnweb.freebsd.org/changeset/base/329077
Log:
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
Modified:
head/usr.bin/tftp/main.c
Modified: head/usr.bin/tftp/main.c
==============================================================================
--- head/usr.bin/tftp/main.c Fri Feb 9 19:10:46 2018 (r329076)
+++ head/usr.bin/tftp/main.c Fri Feb 9 19:46:51 2018 (r329077)
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <netdb.h>
#include <setjmp.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -114,7 +115,7 @@ static void setoptions(int, char **);
static void setrollover(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 void urihandling(char *URI);
@@ -176,11 +177,28 @@ static struct modes {
int
main(int argc, char *argv[])
{
+ HistEvent he;
+ EditLine *el;
+ History *hist;
+ bool interactive;
acting_as_client = 1;
peer = -1;
strcpy(mode, "netascii");
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 (setjmp(toplevel) != 0)
exit(txrx_error);
@@ -192,11 +210,15 @@ main(int argc, char *argv[])
setpeer(argc, argv);
}
- if (setjmp(toplevel) != 0)
+
+ if (setjmp(toplevel) != 0) {
+ if (interactive)
+ el_reset(el);
(void)putchar('\n');
+ }
init_options();
- command();
+ command(interactive, el, hist, &he);
}
/*
@@ -703,36 +725,22 @@ command_prompt(void)
* Command parser.
*/
static void
-command(void)
+command(bool interactive, EditLine *el, History *hist, HistEvent *hep)
{
- HistEvent he;
struct cmd *c;
- static EditLine *el;
- static History *hist;
const char *bp;
char *cp;
- int len, num, vrbose;
+ int len, num;
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 (;;) {
- if (vrbose) {
+ if (interactive) {
if ((bp = el_gets(el, &num)) == NULL || num == 0)
exit(0);
len = MIN(MAXLINE, num);
memcpy(line, bp, len);
line[len] = '\0';
- history(hist, &he, H_ENTER, bp);
+ history(hist, hep, H_ENTER, bp);
} else {
line[0] = 0;
if (fgets(line, sizeof line , stdin) == NULL) {
More information about the svn-src-head
mailing list