From owner-svn-src-all@freebsd.org Fri Feb 9 19:46:52 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9B106F1EC71; Fri, 9 Feb 2018 19:46:52 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48B69754A3; Fri, 9 Feb 2018 19:46:52 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3F9A71416; Fri, 9 Feb 2018 19:46:52 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w19JkqSC038865; Fri, 9 Feb 2018 19:46:52 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w19Jkqb3038864; Fri, 9 Feb 2018 19:46:52 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201802091946.w19Jkqb3038864@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Fri, 9 Feb 2018 19:46:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329077 - head/usr.bin/tftp X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: head/usr.bin/tftp X-SVN-Commit-Revision: 329077 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Feb 2018 19:46:53 -0000 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 #include #include +#include #include #include #include @@ -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) {