Re: bug #41707: RCS 5.8 file corruption when using file descriptor IO for large files
Thien-Thi Nguyen <[email protected]> Wed, 27 Aug 2014 08:36:56 +0200
| Newsgroups | gmane.comp.version-control.rcs.bugs |
|---|---|
| Message-ID | <[email protected]> |
() Achim Gratz <[email protected]> () Sun, 10 Aug 2014 20:00:54 +0200 [changes to src/z.c] I've made the data file some odd number of kiB so the various buffer sizes aren't obscured. Just curious: What is its precise size now (per ‘ls -l’)? In doing these experiments I had an idea for a far less intrusive patch. The code that rewinds the file before diff actually doesn't need to keep the stream and fd position the same before the runv call since runv only inherits the fd. Calling fro_bob _only after_ the runv call actually gets the stream into a useable state, while calling it before and after does apparently nothing (presumably because it already is at the same position). Thanks for mentioning this. It tickled my memory and i was able to search src/ChangeLog for "sync" to ultimately trace the change in behavior to: http://git.savannah.gnu.org/cgit/rcs.git/commit?id=cf7bab62a85 which went into RCS 5.7.94 (released 2010-11-08). I think our experiments w/ src/z.c yield a more conclusive test than the configure-time test deleted in that change, so a simple revert is not indicated. That is, the simplification is partially correct. What i ignorantly missed (originally, in 2010) was: - De-sync is natural and expected (info "(libc) Stream/Descriptor Precautions") so removing all re-sync code represents a regression. - The configure-time test for ‘CAN_FFLUSH_IN’ performs not only ‘fflush’ but also ‘lseek’ afterwards. Anyway, does this patch (against branch ‘p’) work for you? This keeps the pre-diff(1) stream rewind and fixes up the file descriptor post-diff(1) only. It does not use ‘fflush’ as that is presumably part of the stream rewind. (Am i missing something?) -- Thien-Thi Nguyen GPG key: 4C807502 (if you're human and you know it) read my lisp: (responsep (questions 'technical) (not (via 'mailing-list))) => nil
ci.c.diff
(text/x-diff, 585 B)
src/ci.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/ci.c b/src/ci.c
index 97f949d..6f7e291 100644
--- a/src/ci.c
+++ b/src/ci.c
@@ -1092,6 +1092,11 @@ ci_main (const char *cmd, int argc, char **argv)
*++diffp = NULL;
if (DIFF_TROUBLE == runv (wfd, diffname, diffv))
RFATAL ("diff failed");
+
+ if (STDIO_P (work.fro)
+ && PROB (lseek (wfd, 0, SEEK_SET)))
+ Ierror ();
+
if (newhead)
{
fro_bob (work.fro);
signature.asc
(application/pgp-signature, 197 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlP9fI4ACgkQZwMiJEyAdQIbbQCg4lsofb79dGIFRS9HIrdyGjXA jGIAn0XUCgzXxspHlTDHPXNYGI4JlNbT =csZV -----END PGP SIGNATURE-----