Jerry, just for the record:
The subject line should say:
Re: [AC21.5R21.4] Email truncation bug begone!
instead of
Re: [AC21.4R21.5] Email truncation bug begone!
This is what you actually did, right?
Best regards,
Adrian
David,
I took much too long to process this. I can only claim extreme busyness
with some Real Life stuff over the last several weeks. Thank you so
much for analyzing the problem and coming up with a fix. I'm going to
give credit where credit is due (although I did tweak your patch very
slightly in a couple of ways). The 21.5 patch, which I am committing,
is first, followed by the 21.4 version of the patch. Both have the same
ChangeLog entry.
See the discussion rooted here for more information:
http://list-archive.xemacs.org/xemacs-beta/200412/msg00128.html
src/ChangeLog addition:
2005-02-03 David Evers <extsw(a)appliedgenerics.com>
* process-unix.c (unix_send_process): Flush the last chunk, even
when the pipe is blocked.
xemacs-21.5 source patch:
Diff command: cvs -q diff -uN
Files affected: src/process-unix.c
Index: src/process-unix.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/process-unix.c,v
retrieving revision 1.56
diff -d -u -r1.56 process-unix.c
--- src/process-unix.c 2005/01/24 23:34:05 1.56
+++ src/process-unix.c 2005/02/04 03:53:40
@@ -1511,30 +1511,38 @@
Ibyte chunkbuf[512];
Bytecount chunklen;
- while (1)
+ do
{
int writeret;
chunklen = Lstream_read (lstream, chunkbuf, 512);
- if (chunklen <= 0)
- break; /* perhaps should ABORT() if < 0?
- This should never happen. */
old_sigpipe =
(SIGTYPE (*) (int)) EMACS_SIGNAL (SIGPIPE, send_process_trap);
- /* Lstream_write() will never successfully write less than
- the amount sent in. In the worst case, it just buffers
- the unwritten data. */
- writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM (p)), chunkbuf,
- chunklen);
- {
- int save_errno = errno;
- EMACS_SIGNAL (SIGPIPE, old_sigpipe);
- errno = save_errno;
- if (writeret < 0)
- /* This is a real error. Blocking errors are handled
- specially inside of the filedesc stream. */
- report_process_error ("writing to process", proc);
- }
+ if (chunklen > 0)
+ {
+ int save_errno;
+
+ /* Lstream_write() will never successfully write less than
+ the amount sent in. In the worst case, it just buffers
+ the unwritten data. */
+ writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
+ chunklen);
+ save_errno = errno;
+ EMACS_SIGNAL (SIGPIPE, old_sigpipe);
+ errno = save_errno;
+ if (writeret < 0)
+ /* This is a real error. Blocking errors are handled
+ specially inside of the filedesc stream. */
+ report_file_error ("writing to process", list1 (proc));
+ }
+ else
+ {
+ /* Need to make sure that everything up to and including the
+ last chunk is flushed, even when the pipe is currently
+ blocked. */
+ Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
+ EMACS_SIGNAL (SIGPIPE, old_sigpipe);
+ }
while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
{
/* Buffer is full. Wait, accepting input;
@@ -1549,7 +1557,9 @@
Lstream_flush (XLSTREAM (p->pipe_outstream));
EMACS_SIGNAL (SIGPIPE, old_sigpipe);
}
+ /* Perhaps should ABORT() if < 0? This should never happen. */
}
+ while (chunklen > 0);
}
else
{ /* We got here from a longjmp() from the SIGPIPE handler */
Index: src/process-unix.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/process-unix.c,v
retrieving revision 1.20.2.8
diff -d -u -r1.20.2.8 process-unix.c
--- src/process-unix.c 2005/01/31 02:55:26 1.20.2.8
+++ src/process-unix.c 2005/02/04 03:31:08
@@ -1293,26 +1293,38 @@
Bufbyte chunkbuf[512];
Bytecount chunklen;
- while (1)
+ do
{
Lstream_data_count writeret;
chunklen = Lstream_read (lstream, chunkbuf, 512);
- if (chunklen <= 0)
- break; /* perhaps should ABORT() if < 0?
- This should never happen. */
old_sigpipe =
(SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap);
- /* Lstream_write() will never successfully write less than
- the amount sent in. In the worst case, it just buffers
- the unwritten data. */
- writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
- chunklen);
- signal (SIGPIPE, old_sigpipe);
- if (writeret < 0)
- /* This is a real error. Blocking errors are handled
- specially inside of the filedesc stream. */
- report_file_error ("writing to process", list1 (proc));
+ if (chunklen > 0)
+ {
+ int save_errno;
+
+ /* Lstream_write() will never successfully write less than
+ the amount sent in. In the worst case, it just buffers
+ the unwritten data. */
+ writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
+ chunklen);
+ save_errno = errno;
+ signal (SIGPIPE, old_sigpipe);
+ errno = save_errno;
+ if (writeret < 0)
+ /* This is a real error. Blocking errors are handled
+ specially inside of the filedesc stream. */
+ report_file_error ("writing to process", list1 (proc));
+ }
+ else
+ {
+ /* Need to make sure that everything up to and including the
+ last chunk is flushed, even when the pipe is currently
+ blocked. */
+ Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
+ signal (SIGPIPE, old_sigpipe);
+ }
while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
{
/* Buffer is full. Wait, accepting input;
@@ -1327,7 +1339,9 @@
Lstream_flush (XLSTREAM (p->pipe_outstream));
signal (SIGPIPE, old_sigpipe);
}
+ /* Perhaps should abort() if < 0? This should never happen. */
}
+ while (chunklen > 0);
}
else
{ /* We got here from a longjmp() from the SIGPIPE handler */