Bug 583075 - Running tcsh with '-v' option dumps contents of ~/.history
Summary: Running tcsh with '-v' option dumps contents of ~/.history
Status: CLOSED DUPLICATE of bug 688173
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: tcsh617
Version: 5.4
Hardware: All
OS: Linux
low
medium
Target Milestone: rc
: ---
Assignee: Vojtech Vitek
QA Contact: BaseOS QE - Apps
URL:
Whiteboard:
Keywords:
Depends On:
Blocks: 658171 688173
TreeView+ depends on / blocked
 
Reported: 2010-04-16 15:33 UTC by Mike Spencer
Modified: 2018-11-14 19:40 UTC (History)
5 users (show)

(edit)
Clone Of:
: 658171 (view as bug list)
(edit)
Last Closed: 2011-04-14 15:20:57 UTC


Attachments (Terms of Use)
patch to not print history (463 bytes, patch)
2010-05-05 23:32 UTC, Jeff Bastian
no flags Details | Diff
Do not print history on verbose (patch v2) (683 bytes, patch)
2011-01-26 14:43 UTC, Vojtech Vitek
no flags Details | Diff
Do not print history on verbose (upstream patch) (807 bytes, patch)
2011-01-28 12:20 UTC, Vojtech Vitek
no flags Details | Diff

Description Mike Spencer 2010-04-16 15:33:36 UTC
Description of problem: On newer version of tcsh, when running a script with the '-v' option the contents of the ~/.history file are appended to the output.


Version-Release number of selected component (if applicable): Problem appeared in tcsh-6.14


How reproducible: Every time


Steps to Reproduce:
1. Confirm you have data in the ~/.history file
2. Run a script with the '-v' option;  $ tcsh -v /etc/csh.cshrc
3. (NOTE: running the script again creates a similar output (~/.history data still appended, but reordered). Running it a 3rd time reverts back to the same output as run #1)
  
Actual results:  ~/.history data appended to script output


Expected results:  ~/.history data not appended


Additional info:
  - I am seeing the same behavior with tcsh-6.14(EL5) and tcsh-6.17(F12)
but not with tcsh-6.12 (EL-3) or tcsh-6.13(EL-4)
  - After rebuilding the tcsh-6.13.00 code on F12, you get the same behavior as 6.14.00 when doing a -v.
  - Looking through the code and doing a lot of recompiles on RHEL-4 and 5
it looks like the code branches differently here in sh.c

2529                rechist(NULL, adrof(STRsavehist) != NULL);

ON el_4 (adrof(STRsavehist) != NULL) evaluates to 0
ON el_5 (adrof(STRsavehist) != NULL) evaluates to 1

Comment 1 Jeff Bastian 2010-04-16 18:31:02 UTC
This sounds similar to bug 531353 which appended command output to `backtick` command output.

Comment 2 Jeff Bastian 2010-04-16 18:52:23 UTC
Another reproducer method:

1. echo "echo running test script" >/tmp/test.csh
2. mv ~/.history ~/.history.ORIG
3. echo "This is the history file" > ~/.history
4. tcsh -v /tmp/test.csh
5. mv ~/.history.ORIG ~/.history

Actual results:
$ tcsh -v /tmp/test.csh
echo running test script
running test script
This is the history file                   <--- this shouldn't be here!

Expected results:
$ tcsh -v /tmp/test.csh
echo running test script
running test script

Comment 3 Jeff Bastian 2010-04-16 20:24:39 UTC
The reason this appears to be a new bug in RHEL 5 and newer is because this line was added to /etc/csh.cshrc:
   set savehist = (1024 merge)

If you add that line to /etc/csh.cshrc on RHEL 4, the bug can be reproduced there as well.

Comment 4 Jeff Bastian 2010-04-16 20:53:10 UTC
I wonder if tcsh is trying to do history expansion when it ends the end-of-file character.  You can reproduce the bug with a 0 byte file:

$ cat /dev/null > /tmp/eof.csh
$ ls -l /tmp/eof.csh
-rw-rw-r--  1 user group 0 Apr 16 15:51 /tmp/eof.csh
$ tcsh -v /tmp/eof.csh

This is the history file

Comment 5 Vitezslav Crhonek 2010-04-28 13:21:31 UTC
The first problem I see is that 1024 should be less or equal to the value of history variable (which is by default 100), but fixing that doesn't help.

Quick workaround of the problem is changing
set savehist = (1024 merge)
to
set savehist
in /etc/csh.cshrc.

Comment 6 Jeff Bastian 2010-05-05 22:06:02 UTC
With a bit of experimentation, I was able to get a backtrace using gdb just before it writes a line of history out to the terminal.

First I created this set of batch commands for gdb (this was the experimentation part) and saved them in gdb.cmds
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
b xprintf
run -v /tmp/eof.csh
c 3
b doprnt
c
b flush
c
n 8
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Next, run tcsh through gdb:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ cat /dev/null >/tmp/eof.csh
$ echo "my tcsh history" >~/.history
$ gdb -x gdb.cmds /bin/tcsh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

gdb breaks just before the write() syscall:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259         if (write(unit, linbuf, sz) == -1)
(gdb) p unit
$1 = 18
(gdb) n
my tcsh history
301         linp = linbuf;
(gdb) bt
#0  flush () at sh.print.c:301
#1  0x000000000043d3b3 in doprnt (addchar=0x41c5b0 <xputchar>, 
    sfmt=<value optimized out>, ap=0x7fffffff4ed0) at tc.printf.c:264
#2  0x000000000043db43 in xprintf (fmt=0x6b15e0 "my tcsh history\n")
    at tc.printf.c:377
#3  0x0000000000418d4f in prlex (sp0=0x673b80) at sh.lex.c:245
#4  0x0000000000403a91 in process (catch=0) at sh.c:2102
#5  0x000000000040470c in srcunit (unit=6, onlyown=<value optimized out>, 
    hflg=2, av=0x8743d0) at sh.c:1724
#6  0x0000000000404932 in srcfile (f=<value optimized out>, onlyown=0, flag=2, 
    av=0x8743d0) at sh.c:1494
#7  0x0000000000404a43 in dosource (t=0x8743d0, c=<value optimized out>)
    at sh.c:2233
#8  0x000000000041674c in rechist (fname=0x0, ref=<value optimized out>)
    at sh.hist.c:450
#9  0x0000000000405fda in main (argc=<value optimized out>, 
    argv=0x7fffffffc778) at sh.c:1381
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Notice the 'unit', or file descriptor, is 18.  This matches an strace on tcsh:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ strace -e trace=file -e trace=desc -o /tmp/tcsh.strace tcsh -v /tmp/eof.csh
my tcsh history

$ cat /tmp/tcsh.strace
...
dup2(2, 18)                             = 18
...
write(18, "\n", 1)                      = 1
write(18, "my tcsh history\n", 16)      = 16
...
open("/home/jbastian/.history", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0600) = 0
write(0, "#+1273068294\n", 13)          = 13
write(0, "my tcsh history\n", 16)       = 16
close(0)                                = 0 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Comment 7 Jeff Bastian 2010-05-05 23:32:27 UTC
Created attachment 411763 [details]
patch to not print history

I think I see the problem.                                                      

When savehist has the 'merge' keyword in it, rechist() calls loadhist():
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL)
        if (shist->vec[1] && eq(shist->vec[1], STRmerge))
            loadhist(fname, 1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

loadhist() just calls dosource() like it was an interactive shell.

Continuing up the stack through srcfile() and srcunit() and process() we get to this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /*
     * Echo not only on VERBOSE, but also with history expansion. If there
     * is a lexical error then we forego history echo.
     */
    if ((lex(&paraml) && !seterr && intty && !tellwhat && !Expand &&
         !whyles) || adrof(STRverbose)) {
        int odidfds = didfds;
        haderr = 1;
        didfds = 0;
        prlex(&paraml);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


And prlex() goes on to print to stderr the line of the history file being processed.


My solution was to just unset STRverbose when recording the history at the end of main().  See the attached patch.  Maybe it would be better, though, to save the STRverbose state and restore it after the record() call?

Comment 9 Jeff Bastian 2010-05-05 23:45:12 UTC
This is still a problem with tcsh-6.17 so I've been discussing it upstream at
  http://mx.gw.com/pipermail/tcsh-bugs/2010-May/000667.html

Comment 11 RHEL Product and Program Management 2010-08-09 18:11:07 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.

Comment 12 RHEL Product and Program Management 2011-01-11 19:57:31 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.

Comment 13 RHEL Product and Program Management 2011-01-12 15:14:53 UTC
This request was erroneously denied for the current release of
Red Hat Enterprise Linux.  The error has been fixed and this
request has been re-proposed for the current release.

Comment 14 Vojtech Vitek 2011-01-26 14:43:20 UTC
Created attachment 475409 [details]
Do not print history on verbose (patch v2)

Added if statement to the previous version of the patch.
- Fix error message on exit "verbose: Undefined variable."

Comment 16 Vojtech Vitek 2011-01-28 12:20:05 UTC
Created attachment 475790 [details]
Do not print history on verbose (upstream patch)

Prevents printing also on `history -S`.

Comment 18 Vojtech Vitek 2011-04-14 15:20:57 UTC

*** This bug has been marked as a duplicate of bug 688173 ***


Note You need to log in before you can comment on or make changes to this bug.