I reported this problem a few days ago: http://www.egroups.com/group/info-cvs/20160.html? Here's a better fix. Comments welcome. Index: lib/ChangeLog =================================================================== RCS file: /home2/cvsroot/ccvs/lib/ChangeLog,v retrieving revision 1.126 diff -u -p -r1.126 ChangeLog --- ChangeLog 2000/01/03 22:22:59 1.126 +++ ChangeLog 2000/02/16 16:51:01 @@ -1,3 +1,7 @@ +2000-02-16 Jim Meyering <[EMAIL PROTECTED]> + + * sighandle.c (SIG_inCrSect): New function. + 2000-01-03 Larry Jones <[EMAIL PROTECTED]> * getdate.y (Convert): Add window to determine whether 2-digit dates Index: lib/sighandle.c =================================================================== RCS file: /home2/cvsroot/ccvs/lib/sighandle.c,v retrieving revision 1.6 diff -u -p -r1.6 sighandle.c --- sighandle.c 1997/01/08 20:05:51 1.6 +++ sighandle.c 2000/02/16 16:51:01 @@ -384,6 +384,16 @@ void SIG_beginCrSect() } /* + * Return nonzero if currently in a critical section. + * Otherwise return zero. + */ + +int SIG_inCrSect() +{ + return SIG_crSectNest > 0; +} + +/* * The following ends a critical section. */ Index: src/ChangeLog =================================================================== RCS file: /home2/cvsroot/ccvs/src/ChangeLog,v retrieving revision 1.1857 diff -u -p -r1.1857 ChangeLog --- ChangeLog 2000/02/16 16:21:55 1.1857 +++ ChangeLog 2000/02/16 16:51:06 @@ -1,5 +1,12 @@ 2000-02-16 Jim Meyering <[EMAIL PROTECTED]> + Fix to avoid race condition whereby a catchable signal could + end up corrupting the repository. + * commit.c (checkaddfile): Put a critical section around the code + that handles the first commit on the trunk of a file that's already + been committed on a branch. + * cvs.h (Sig_inCrSect): Declare new function. + * update.c (join_file): Correct typo in diagnostic: change `file %s is present...' to `file %s is not present...'. Index: src/cvs.h =================================================================== RCS file: /home2/cvsroot/ccvs/src/cvs.h,v retrieving revision 1.199 diff -u -p -r1.199 cvs.h --- cvs.h 2000/02/10 21:32:23 1.199 +++ cvs.h 2000/02/16 16:51:11 @@ -637,6 +637,7 @@ int start_recursion PROTO((FILEPROC file int dosrcs)); void SIG_beginCrSect PROTO((void)); void SIG_endCrSect PROTO((void)); +int SIG_inCrSect PROTO((void)); void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname)); char *make_message_rcslegal PROTO((char *message)); Index: src/commit.c =================================================================== RCS file: /home2/cvsroot/ccvs/src/commit.c,v retrieving revision 1.157 diff -u -p -r1.157 commit.c --- commit.c 2000/01/05 16:35:46 1.157 +++ commit.c 2000/02/16 16:51:11 @@ -1401,6 +1401,8 @@ out: } } } + if (SIG_inCrSect ()) + SIG_endCrSect (); return (err); } @@ -1752,8 +1754,8 @@ remove_file (finfo, tag, message) "failed to commit dead revision for `%s'", finfo->fullname); return (1); } -/* At this point, the file has been committed as removed. We should - probably tell the history file about it */ + /* At this point, the file has been committed as removed. We should + probably tell the history file about it */ history_write ('R', NULL, finfo->rcs->head, finfo->file, finfo->repository); if (rev != NULL) @@ -1966,6 +1968,11 @@ checkaddfile (file, repository, tag, opt sprintf (rcs, "%s/%s%s", repository, file, RCSEXT); + /* Begin a critical section around the code that spans the + first commit on the trunk of a file that's already been + committed on a branch. */ + SIG_beginCrSect (); + if (RCS_setattic (rcsfile, 0)) { retval = 1; @@ -2198,6 +2205,8 @@ checkaddfile (file, repository, tag, opt retval = 0; out: + if (retval != 0 && SIG_inCrSect ()) + SIG_endCrSect (); free (rcs); return retval; }
