Bug 169092

Summary: text entered in external editor not passed to composer window
Product: [Applications] kmail Reporter: Vincent DiCarlo <vdicarlo>
Component: composerAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: brian.foster, brian.overstreet, gtwilliams, ruchir.brahmbhatt
Priority: NOR Keywords: triaged
Version: 1.11.2   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: Work-around so Konsole is synchronous in KDE 4 for when --nofork doesn't work
Patch that opens the temporary file after the external editor is finished.

Description Vincent DiCarlo 2008-08-14 07:20:46 UTC
Version:           1.10.0 Release 26.5 (using KDE 4.1.0)
Installed from:    SuSE RPMs
Compiler:          NA. Installed from Opensuse online repositories 
OS:                Linux

To duplicate bug:

-Go to Settings>Configure Kmail>Composer
-select Use External Editor; Specify External Editor text box enter "gvim -f %f"
-select compose new email
-type a character in the message area; gvim opens
-type something in gvim, save and exit
-focus returns to kmail composer, but none of the text saved in the external editor is present
Comment 1 Thomas McGuire 2008-08-20 17:45:17 UTC
I can not reproduce, this works fine for me after hitting :w and :q.
Comment 2 Garry Williams 2008-12-24 22:31:46 UTC
I can confirm this exact behavior since installing Fedora 10.  The bug continues with KDE 4.2 beta kmail, too.
Comment 3 Brian Foster 2009-01-09 12:15:15 UTC
I can also confirm this happens with Kmail 1.10.3 (Kubuntu 8.10).
In addition, there is a significant clew as to what is happening.

First, instead of CREATING a new e-mail, REPLYING to an existing
e-mail helps to show the problem.  The thing to notice when the
vim(1) starts up is  (i) The file is empty (it doesn't contain
the text of the message being replied to or your signature);
and  (ii) `vim' reports the file is "[New]".

Playing with strace(1) seems to confirm Kmail is creating the file
with what looks like plausible contents.  It then launches the editor,
and then seems to immediately *DELETE* the file (unlink(2)), whilst
the editor is still starting up.  That is, this mysterious unlink
is racing the editor, and usually wining; i.e., the file is unlinked
before the editor opens it.

By using a very simple bash(1) shell script similar to:

   #!/bin/bash
   date >>$1

 as my "external editor" I have *sometimes* been able to win the
race; that is, the date appears in the composer window.  But not
always, sometimes Kmail wins, and the date doesn't appear.
Comment 4 Brian Foster 2009-01-09 17:46:08 UTC
PARTIAL SOLUTION.

To use gvim(1), specify ‘--nofork’:

	gvim --nofork %f

 but please see the POSSIBLE CAVEAT below.

In theory, the same will work for vim(1) when run by Konsole:

	konsole --nofork -e vim %f

However, this results in the opaque complaint:

	<unknown program name>(4763)/: KUniqueApplication: Can't setup D-Bus service. Probably already running.

where the ‘4763’ is clearly the PID of some process (presumably
Konsole).  To work-around this unclear problem, use xterm(1) or,
I presume, another non-KDE terminak.

The CAVEAT:  I don't if the ‘gvim’ work-around works if there is
an already-running ‘gvim’ (I don't normally use ‘gvim’ myself);
and for that matter, I don't know if the Konsole should-work
actually does work if there is_not_ an already-running Konsole.
Comment 5 Brian Foster 2009-01-12 11:00:20 UTC
Created attachment 30175 [details]
Work-around so Konsole is synchronous in KDE 4 for when --nofork doesn't work

Has been successfully used to launch vim(1) as the Kmail external editor:

   /bin/bash /path/to/the/script -e vim %f

Has also been successfully used (similar command line) to launch the external
editor (also `vim') for both claws-mail(1) and Thunderbird, all on Kubuntu 8.10
(currently using KDE 4.1).
Comment 6 Brian Foster 2009-01-12 11:04:49 UTC
1st, KDevelop seems to have a similar problem, see
  “Can't use --nofork for KUniqueApplications from another kde process”,
  http://www.nabble.com/Can't-use---nofork-for-KUniqueApplications-from-another-kde-process-td21047022.html#a21047022

2nd, Attached is a bash(1) script which attempts to work-around the
    problem.  Use at own risk; Your mileage may vary; Etc, etc ... .

 [ Apologies if this comment is duplicted.  I'd intended it to be
  committed along with the above script/attachment, but it doesn't
  look like it was?  Apologies for any confusion!   -blf ]
Comment 7 Brian Overstreet 2009-03-10 01:54:43 UTC
The other solutions did not work for me.  
When the external editor is first opened:

$ lsof -p `pgrep kmail` | grep s18228.tmp
kmail   18228 overstre   35u   REG              253,0        0  1056790 /home/overstre/.kde/tmp-panic/kmails18228.tmp

Now after saving text in the external editor:

$ lsof -p `pgrep kmail` | grep s18228.tmp
kmail   18228 overstre   35u   REG              253,0        0  1056790 /home/overstre/.kde/tmp-panic/kmails18228.tmp~

Kmail no longer has the original file open, but instead the backup file.  Now when the editor is closed the backup file which is empty gets passed to kmail. The workaround is to save the original file to backup file before closing the external editor.
Comment 8 Garry Williams 2009-03-22 14:42:30 UTC
(In reply to comment #7)
> Kmail no longer has the original file open, but instead the backup file.

It's even worse than that.

For many years, I have configured vim to not create backup files.  The (g)vim program creates a new file and renames it to the original as soon as I tell it to write my changes.

Since kmail now opens the original (and unlinks it), and waits for the external process to exit, it ends up reading the original file without my saved changes.

This behaviour is new since KDE 4.something.

I have an older system I use at work:

    $ rpm -q kdepim
    kdepim-3.5.9-6.fc7

This version does not have the bug.  Apparently, the older version uses the name (not the inode) to obtain the updated buffer after the external program exits.

There is no work-around that seems possible here.

The bug exists in:

    $ rpm -q kdepim
    kdepim-4.2.1-3.fc10.i386
Comment 9 Ruchir Brahmbhatt 2009-04-10 12:08:47 UTC
I can't reproduce on 1.11.2 in both cases i.e. new mail and reply.
Comment 10 Garry Williams 2009-04-11 17:04:01 UTC
This bug is not fixed for me.  Perhaps I have a version different from the version you tested against.

I strace-d my kontact process and I can confirm that the E-mail program opens the editor file before fork()ing the editor and then reads the contents of that file to place in the composer screen.  Since the editor renames the file it was passed and then creates a new file with the original name in which to write its changes, the E-mail program simply reads the original contents without the changes that the editor made.

I am using gvim as my external editor (and calling it with the -f option to force it to run in the foreground without fork()ing).  I don't think this is new behaviour for gvim -- it has always rename()ed the original file then open()ed the original file name, creating a new file, to write its changes.

The fix is to assume that an external editor will create a new version of the file and open it *after* the child process exits.  Kmail in KDE 3.5 did not have this bug.

Here's my version information:

    $ kmail --version
    Qt: 4.5.0
    KDE: 4.2.2 (KDE 4.2.2)
    KMail: 1.11.2
    $ kontact --version
    Qt: 4.5.0
    KDE: 4.2.2 (KDE 4.2.2)
    Kontact: 1.4.2
    $ rpm -q kdepim
    kdepim-4.2.2-3.fc10.i386
    $

Please let me know what other information you require.
Comment 11 Ruchir Brahmbhatt 2009-04-11 20:04:55 UTC
@Garry: Below are my package versions. I tried again but still can't reproduce. In case of new mail and reply modified text is passed to composer. Can you try upgrading your packages? I have packages from opensuse factory which is more up to date.

linux-u64f:~ # kmail --version
Qt: 4.5.0
KDE: 4.2.2 (KDE 4.2.2) "release 112"
KMail: 1.11.2
linux-u64f:~ # kontact --version
Qt: 4.5.0
KDE: 4.2.2 (KDE 4.2.2) "release 112"
Kontact: 1.4.2
linux-u64f:~ # rpm -q kdepim4
kdepim4-4.2.2-107.5
Comment 12 Ruchir Brahmbhatt 2009-04-14 11:28:34 UTC
Finally reproduced on 1.11.2 using following information provide from Garry.

If it matters, here's a script that produces the bug:

    #!/bin/sh
    mv $1 $1.sav
    echo test message >$1

I saved this as ~/test-editor.sh, made it executable and then 
configured Kmail to use this program as the composer editor.  This 
script clearly creates a file with desired content, but since my 
version of Kmail opens that file name before calling this "editor", 
Kmail never "sees" the editor's results.  If you remove line two of 
this script (the mv command), the Kmail composer receives the "editor" 
text as you would expect.
Comment 13 Brian Overstreet 2009-06-28 03:20:52 UTC
Created attachment 34877 [details]
Patch that opens the temporary file after the external editor is finished.

This is a possible fix for this issue.
Comment 14 Martin Koller 2009-08-03 21:06:12 UTC
SVN commit 1006443 by mkoller:

BUG: 169092

After the external editor closed, reopen the temporary file to ensure
that a possible new file the editor recreated will be read.
Based on a patch by  Brian Overstreet


 M  +9 -5      kmeditor.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1006443