NetBSD Problem Report #33625
From www@NetBSD.org Thu Jun 1 16:34:50 2006
Return-Path: <www@NetBSD.org>
Received: by narn.NetBSD.org (Postfix, from userid 31301)
id 9E84B63BA5F; Thu, 1 Jun 2006 16:34:50 +0000 (UTC)
Message-Id: <20060601163450.9E84B63BA5F@narn.NetBSD.org>
Date: Thu, 1 Jun 2006 16:34:50 +0000 (UTC)
From: chardin@2wire.com
Reply-To: chardin@2wire.com
To: gnats-bugs@NetBSD.org
Subject: [PATCH] allow using t_puts inside of libedit
X-Send-Pr-Version: www-1.0
>Number: 33625
>Category: lib
>Synopsis: [PATCH] allow using t_puts inside of libedit
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Jun 01 16:35:00 +0000 2006
>Originator: Charles Hardin
>Release: CVS HEAD libedit on a FreeBSD box (sorry)
>Organization:
2Wire
>Environment:
FreeBSD reddevil.2wire.com 4.7-RELEASE FreeBSD 4.7-RELEASE #0: Mon Mar 20 14:47:22 PST 2006 root@reddevil.2wire.com:/usr/obj/usr/src/sys/REDDEVILIPSEC i386
>Description:
Was writing a threaded application that was monitoring multiple consoles using libedit and ran across a problem with output appearing on the other tty... Tracked it back to a comment in libedit and made a patch that fixed our problem by allowing the use of t_puts instead of tputs...
>How-To-Repeat:
Should probably right a test application - but, a little too lazy for that... The application just started n threads and did an el_init for each thread to a different tty[0-9]...
Then when going thru the history it would get flushed to the wrong terminal in some cases... it's just a race condition...
So, did the patch below to allow the use of t_puts so I can pass the EditLine pointer all the way to the output routines...
>Fix:
Index: common.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/common.c,v
retrieving revision 1.19
diff -u -r1.19 common.c
--- common.c 6 Mar 2006 21:11:56 -0000 1.19
+++ common.c 1 Jun 2006 16:31:57 -0000
@@ -910,7 +910,7 @@
int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: ");
- term__putc('\n');
+ term__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el);
Index: read.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/read.c,v
retrieving revision 1.39
diff -u -r1.39 read.c
--- read.c 2 Aug 2005 12:11:14 -0000 1.39
+++ read.c 1 Jun 2006 16:31:57 -0000
@@ -223,7 +223,7 @@
ma->level--;
}
term_beep(el);
- term__flush();
+ term__flush(el);
}
@@ -311,7 +311,7 @@
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
- term__flush();
+ term__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
@@ -368,7 +368,7 @@
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
- term__flush();
+ term__flush(el);
}
protected void
@@ -445,7 +445,7 @@
else
cp = el->el_line.lastchar;
- term__flush();
+ term__flush(el);
while ((*el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space next character */
@@ -588,7 +588,7 @@
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
- term__flush();
+ term__flush(el);
break;
}
el->el_state.argument = 1;
@@ -598,7 +598,7 @@
break;
}
- term__flush(); /* flush any buffered output */
+ term__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
Index: refresh.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/refresh.c,v
retrieving revision 1.27
diff -u -r1.27 refresh.c
--- refresh.c 9 Nov 2005 22:11:10 -0000 1.27
+++ refresh.c 1 Jun 2006 16:31:57 -0000
@@ -323,9 +323,9 @@
{
term_move_to_line(el, el->el_refresh.r_oldcv);
- term__putc('\n');
+ term__putc(el, '\n');
re_clear_display(el);
- term__flush();
+ term__flush(el);
}
@@ -1011,7 +1011,7 @@
/* now go there */
term_move_to_line(el, v);
term_move_to_char(el, h);
- term__flush();
+ term__flush(el);
}
@@ -1022,7 +1022,7 @@
re_fastputc(EditLine *el, int c)
{
- term__putc(c);
+ term__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
if (el->el_cursor.h >= el->el_term.t_size.h) {
/* if we must overflow */
@@ -1049,12 +1049,12 @@
}
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {
- term__putc(' ');
- term__putc('\b');
+ term__putc(el, ' ');
+ term__putc(el, '\b');
}
} else {
- term__putc('\r');
- term__putc('\n');
+ term__putc(el, '\r');
+ term__putc(el, '\n');
}
}
}
@@ -1094,7 +1094,7 @@
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0');
}
- term__flush();
+ term__flush(el);
}
@@ -1133,7 +1133,7 @@
} else {
term_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */
- term__putc('\r'); /* go to BOL */
- term__putc('\n'); /* go to new line */
+ term__putc(el, '\r'); /* go to BOL */
+ term__putc(el, '\n'); /* go to new line */
}
}
Index: sig.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/sig.c,v
retrieving revision 1.11
diff -u -r1.11 sig.c
--- sig.c 7 Aug 2003 16:44:33 -0000 1.11
+++ sig.c 1 Jun 2006 16:31:57 -0000
@@ -80,7 +80,7 @@
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
- term__flush();
+ term__flush(sel);
break;
case SIGWINCH:
Index: term.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/term.c,v
retrieving revision 1.45
diff -u -r1.45 term.c
--- term.c 18 Mar 2006 19:23:14 -0000 1.45
+++ term.c 1 Jun 2006 16:31:57 -0000
@@ -273,9 +273,6 @@
private void term_reset_arrow(EditLine *);
-private FILE *term_outfile = NULL; /* XXX: How do we fix that? */
-
-
/* term_setflags():
* Set the terminal capability flags
*/
@@ -347,7 +344,6 @@
if (el->el_term.t_val == NULL)
return (-1);
(void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
- term_outfile = el->el_outfile;
(void) term_set(el, NULL);
term_init_arrow(el);
return (0);
@@ -418,7 +414,7 @@
*/
tlen = 0;
for (tmp = tlist; tmp < &tlist[T_str]; tmp++)
- if (*tmp != NULL && *tmp != '\0' && *tmp != *str) {
+ if (*tmp != NULL && *tmp[0] != '\0' && *tmp != *str) {
char *ptr;
for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++)
@@ -559,12 +555,12 @@
del--;
} else {
if ((del > 1) && GoodStr(T_DO)) {
- (void) tputs(tgoto(Str(T_DO), del, del),
- del, term__putc);
+ term__puts(el,
+ tgoto(Str(T_DO), del, del), del);
del = 0;
} else {
for (; del > 0; del--)
- term__putc('\n');
+ term__putc(el, '\n');
/* because the \n will become \r\n */
el->el_cursor.h = 0;
}
@@ -572,12 +568,11 @@
}
} else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
- (void) tputs(tgoto(Str(T_UP), -del, -del), -del,
- term__putc);
+ term__puts(el, tgoto(Str(T_UP), -del, -del), -del);
else {
if (GoodStr(T_up))
for (; del < 0; del++)
- (void) tputs(Str(T_up), 1, term__putc);
+ term__puts(el, Str(T_up), 1);
}
}
el->el_cursor.v = where;/* now where is here */
@@ -604,7 +599,7 @@
return;
}
if (!where) { /* if where is first column */
- term__putc('\r'); /* do a CR */
+ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0;
return;
}
@@ -612,12 +607,12 @@
if ((del < -4 || del > 4) && GoodStr(T_ch))
/* go there directly */
- (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc);
+ term__puts(el, tgoto(Str(T_ch), where, where), where);
else {
if (del > 0) { /* moving forward */
if ((del > 4) && GoodStr(T_RI))
- (void) tputs(tgoto(Str(T_RI), del, del),
- del, term__putc);
+ term__puts(el, tgoto(Str(T_RI), del, del),
+ del);
else {
/* if I can do tabs, use them */
if (EL_CAN_TAB) {
@@ -628,7 +623,7 @@
(el->el_cursor.h & 0370);
i < (where & 0370);
i += 8)
- term__putc('\t');
+ term__putc(el, '\t');
/* then tab over */
el->el_cursor.h = where & 0370;
}
@@ -648,8 +643,8 @@
}
} else { /* del < 0 := moving backward */
if ((-del > 4) && GoodStr(T_LE))
- (void) tputs(tgoto(Str(T_LE), -del, -del),
- -del, term__putc);
+ term__puts(el, tgoto(Str(T_LE), -del, -del),
+ -del);
else { /* can't go directly there */
/*
* if the "cost" is greater than the "cost"
@@ -660,12 +655,12 @@
(((unsigned int) where >> 3) +
(where & 07)))
: (-del > where)) {
- term__putc('\r'); /* do a CR */
+ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0;
goto mc_again; /* and try again */
}
for (i = 0; i < -del; i++)
- term__putc('\b');
+ term__putc(el, '\b');
}
}
}
@@ -690,7 +685,7 @@
return;
}
do {
- term__putc(*cp++);
+ term__putc(el, *cp++);
el->el_cursor.h++;
} while (--n);
@@ -706,7 +701,7 @@
!= '\0')
term_overwrite(el, &c, 1);
else
- term__putc(' ');
+ term__putc(el, ' ');
el->el_cursor.h = 1;
}
} else /* no wrap, but cursor stays on screen */
@@ -740,19 +735,18 @@
if (GoodStr(T_DC)) /* if I have multiple delete */
if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more
* expen. */
- (void) tputs(tgoto(Str(T_DC), num, num),
- num, term__putc);
+ term__puts(el, tgoto(Str(T_DC), num, num), num);
return;
}
if (GoodStr(T_dm)) /* if I have delete mode */
- (void) tputs(Str(T_dm), 1, term__putc);
+ term__puts(el, Str(T_dm), 1);
if (GoodStr(T_dc)) /* else do one at a time */
while (num--)
- (void) tputs(Str(T_dc), 1, term__putc);
+ term__puts(el, Str(T_dc), 1);
if (GoodStr(T_ed)) /* if I have delete mode */
- (void) tputs(Str(T_ed), 1, term__putc);
+ term__puts(el, Str(T_ed), 1);
}
@@ -781,37 +775,36 @@
if (GoodStr(T_IC)) /* if I have multiple insert */
if ((num > 1) || !GoodStr(T_ic)) {
/* if ic would be more expensive */
- (void) tputs(tgoto(Str(T_IC), num, num),
- num, term__putc);
+ term__puts(el, tgoto(Str(T_IC), num, num), num);
term_overwrite(el, cp, num);
/* this updates el_cursor.h */
return;
}
if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
- (void) tputs(Str(T_im), 1, term__putc);
+ term__puts(el, Str(T_im), 1);
el->el_cursor.h += num;
do
- term__putc(*cp++);
+ term__putc(el, *cp++);
while (--num);
if (GoodStr(T_ip)) /* have to make num chars insert */
- (void) tputs(Str(T_ip), 1, term__putc);
+ term__puts(el, Str(T_ip), 1);
- (void) tputs(Str(T_ei), 1, term__putc);
+ term__puts(el, Str(T_ei), 1);
return;
}
do {
if (GoodStr(T_ic)) /* have to make num chars insert */
- (void) tputs(Str(T_ic), 1, term__putc);
+ term__puts(el, Str(T_ic), 1);
/* insert a char */
- term__putc(*cp++);
+ term__putc(el, *cp++);
el->el_cursor.h++;
if (GoodStr(T_ip)) /* have to make num chars insert */
- (void) tputs(Str(T_ip), 1, term__putc);
+ term__puts(el, Str(T_ip), 1);
/* pad the inserted char */
} while (--num);
@@ -827,10 +820,10 @@
int i;
if (EL_CAN_CEOL && GoodStr(T_ce))
- (void) tputs(Str(T_ce), 1, term__putc);
+ term__puts(el, Str(T_ce), 1);
else {
for (i = 0; i < num; i++)
- term__putc(' ');
+ term__putc(el, ' ');
el->el_cursor.h += num; /* have written num spaces */
}
}
@@ -845,14 +838,14 @@
if (GoodStr(T_cl))
/* send the clear screen code */
- (void) tputs(Str(T_cl), Val(T_li), term__putc);
+ term__puts(el, Str(T_cl), Val(T_li));
else if (GoodStr(T_ho) && GoodStr(T_cd)) {
- (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */
+ term__puts(el, Str(T_ho), Val(T_li)); /* home */
/* clear to bottom of screen */
- (void) tputs(Str(T_cd), Val(T_li), term__putc);
+ term__puts(el, Str(T_cd), Val(T_li));
} else {
- term__putc('\r');
- term__putc('\n');
+ term__putc(el, '\r');
+ term__putc(el, '\n');
}
}
@@ -865,9 +858,9 @@
{
if (GoodStr(T_bl))
/* what termcap says we should use */
- (void) tputs(Str(T_bl), 1, term__putc);
+ term__puts(el, Str(T_bl), 1);
else
- term__putc('\007'); /* an ASCII bell; ^G */
+ term__putc(el, '\007'); /* an ASCII bell; ^G */
}
@@ -879,9 +872,9 @@
term_clear_to_bottom(EditLine *el)
{
if (GoodStr(T_cd))
- (void) tputs(Str(T_cd), Val(T_li), term__putc);
+ term__puts(el, Str(T_cd), Val(T_li));
else if (GoodStr(T_ce))
- (void) tputs(Str(T_ce), Val(T_li), term__putc);
+ term__puts(el, Str(T_ce), Val(T_li));
}
#endif
@@ -1238,14 +1231,47 @@
}
+#ifdef _HAVE_T_PUTS_
+private void
+term__outc(char c, void *arg)
+{
+ EditLine *el;
+ el = (EditLine *)arg;
+ return (fputc(c, el->el_outfile));
+}
+
+protected void
+term__puts(EditLine *el, const char *str, int cnt)
+{
+ (void) t_puts(NULL, str, cnt, term__outc, el);
+}
+#else
+private FILE *term_outfile = NULL; /* XXX: How do we fix that? */
+
+private int
+term__outc(int c)
+{
+
+ return (fputc(c, term_outfile));
+}
+
+protected void
+term__puts(EditLine *el, const char *str, int cnt)
+{
+ term_outfile = el->el_outfile;
+ (void) tputs(str, cnt, term__outc);
+}
+#endif
+
+
/* term__putc():
* Add a character
*/
protected int
-term__putc(int c)
+term__putc(EditLine *el, int c)
{
- return (fputc(c, term_outfile));
+ return (fputc(c, el->el_outfile));
}
@@ -1253,10 +1279,10 @@
* Flush output
*/
protected void
-term__flush(void)
+term__flush(EditLine *el)
{
- (void) fflush(term_outfile);
+ (void) fflush(el->el_outfile);
}
/* term_writec():
@@ -1269,7 +1295,7 @@
int cnt = key__decode_char(buf, sizeof(buf), 0, c);
buf[cnt] = '\0';
term_overwrite(el, buf, cnt);
- term__flush();
+ term__flush(el);
}
@@ -1530,7 +1556,7 @@
*argv);
return (-1);
}
- (void) tputs(scap, 1, term__putc);
+ term__puts(el, scap, 1);
break;
case 1:
argv++;
@@ -1558,7 +1584,7 @@
*argv);
return (-1);
}
- (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc);
+ term__puts(el, tgoto(scap, arg_cols, arg_rows), 1);
break;
default:
/* This is wrong, but I will ignore it... */
@@ -1614,8 +1640,7 @@
*argv);
return (-1);
}
- (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows,
- term__putc);
+ term__puts(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
break;
}
return (0);
Index: term.h
===================================================================
RCS file: /cvsroot/src/lib/libedit/term.h,v
retrieving revision 1.17
diff -u -r1.17 term.h
--- term.h 6 Mar 2006 21:11:56 -0000 1.17
+++ term.h 1 Jun 2006 16:31:57 -0000
@@ -103,8 +103,9 @@
protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **);
protected void term_writec(EditLine *, int);
-protected int term__putc(int);
-protected void term__flush(void);
+protected void term__puts(EditLine *, const char *, int);
+protected int term__putc(EditLine *, int);
+protected void term__flush(EditLine *);
/*
* Easy access macros
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.