Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Feb 2018 19:46:52 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r329077 - head/usr.bin/tftp
Message-ID:  <201802091946.w19Jkqb3038864@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802091946.w19Jkqb3038864>