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>