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;
 }

Reply via email to