You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2016/02/09 18:36:50 UTC

svn commit: r1729422 - in /subversion/trunk/subversion: svn/svn.c svnadmin/svnadmin.c svnbench/svnbench.c svnfsfs/svnfsfs.c svnlook/svnlook.c svnrdump/svnrdump.c svnsync/svnsync.c

Author: philip
Date: Tue Feb  9 17:36:49 2016
New Revision: 1729422

URL: http://svn.apache.org/viewvc?rev=1729422&view=rev
Log:
* subversion/svn/svn.c
* subversion/svnbench/svnbench.c
* subversion/svnfsfs/svnfsfs.c
* subversion/svnlook/svnlook.c
* subversion/svnrdump/svnrdump.c
* subversion/svnsync/svnsync.c
  (signal_handler, setup_cancellation,
   sub_main, main): Followup to r1727916, handle race if second signal
   arrives, don't assume int fits in sig_atomic_t.

Found by: danielsh

Modified:
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/svnadmin/svnadmin.c
    subversion/trunk/subversion/svnbench/svnbench.c
    subversion/trunk/subversion/svnfsfs/svnfsfs.c
    subversion/trunk/subversion/svnlook/svnlook.c
    subversion/trunk/subversion/svnrdump/svnrdump.c
    subversion/trunk/subversion/svnsync/svnsync.c

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Tue Feb  9 17:36:49 2016
@@ -1803,15 +1803,35 @@ check_lib_versions(void)
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* A signal handler to support cancellation. */
 static void
 signal_handler(int signum)
 {
+  int i;
+
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 /* Our cancellation callback. */
@@ -2956,17 +2976,8 @@ sub_main(int *exit_code, int argc, const
 
   /* Set up our cancellation support. */
   ctx->cancel_func = svn_cl__check_cancel;
-  apr_signal(SIGINT, signal_handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, signal_handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, signal_handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, signal_handler);
-#endif
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 
 #ifdef SIGPIPE
   /* Disable SIGPIPE generation for the platforms that have it. */
@@ -3154,11 +3165,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
+++ subversion/trunk/subversion/svnadmin/svnadmin.c Tue Feb  9 17:36:49 2016
@@ -66,15 +66,35 @@
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* A signal handler to support cancellation. */
 static void
 signal_handler(int signum)
 {
+  int i;
+  
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 
@@ -82,17 +102,10 @@ signal_handler(int signum)
 static void
 setup_cancellation_signals(void (*handler)(int signum))
 {
-  apr_signal(SIGINT, handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, handler);
-#endif
+  int i;
+  
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 }
 
 
@@ -3042,11 +3055,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnbench/svnbench.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnbench/svnbench.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnbench/svnbench.c (original)
+++ subversion/trunk/subversion/svnbench/svnbench.c Tue Feb  9 17:36:49 2016
@@ -334,15 +334,35 @@ check_lib_versions(void)
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* A signal handler to support cancellation. */
 static void
 signal_handler(int signum)
 {
+  int i;
+  
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 /* Baton for ra_progress_func() callback. */
@@ -914,17 +934,8 @@ sub_main(int *exit_code, int argc, const
 
   /* Set up our cancellation support. */
   ctx->cancel_func = svn_cl__check_cancel;
-  apr_signal(SIGINT, signal_handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, signal_handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, signal_handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, signal_handler);
-#endif
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 
 #ifdef SIGPIPE
   /* Disable SIGPIPE generation for the platforms that have it. */
@@ -1059,11 +1070,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnfsfs/svnfsfs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnfsfs/svnfsfs.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnfsfs/svnfsfs.c (original)
+++ subversion/trunk/subversion/svnfsfs/svnfsfs.c Tue Feb  9 17:36:49 2016
@@ -49,15 +49,35 @@
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* A signal handler to support cancellation. */
 static void
 signal_handler(int signum)
 {
+  int i;
+  
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 
@@ -65,17 +85,10 @@ signal_handler(int signum)
 static void
 setup_cancellation_signals(void (*handler)(int signum))
 {
-  apr_signal(SIGINT, handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, handler);
-#endif
+  int i;
+  
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 }
 
 
@@ -549,11 +562,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnlook/svnlook.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnlook/svnlook.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnlook/svnlook.c (original)
+++ subversion/trunk/subversion/svnlook/svnlook.c Tue Feb  9 17:36:49 2016
@@ -381,7 +381,20 @@ typedef struct svnlook_ctxt_t
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 
 /*** Helper functions. ***/
@@ -390,9 +403,16 @@ static int signum_cancelled;
 static void
 signal_handler(int signum)
 {
+  int i;
+
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 /* Our cancellation callback. */
@@ -2808,17 +2828,8 @@ sub_main(int *exit_code, int argc, const
     }
 
   /* Set up our cancellation support. */
-  apr_signal(SIGINT, signal_handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, signal_handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, signal_handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, signal_handler);
-#endif
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 
 #ifdef SIGPIPE
   /* Disable SIGPIPE generation for the platforms that have it. */
@@ -2895,11 +2906,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/svnrdump.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/svnrdump.c (original)
+++ subversion/trunk/subversion/svnrdump/svnrdump.c Tue Feb  9 17:36:49 2016
@@ -54,15 +54,35 @@
 
 /* A flag to see if we've been cancelled by the client or not. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* A signal handler to support cancellation. */
 static void
 signal_handler(int signum)
 {
+  int i;
+  
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 /* Our cancellation callback. */
@@ -812,17 +832,9 @@ sub_main(int *exit_code, int argc, const
   os->interleave = TRUE; /* Options and arguments can be interleaved */
 
   /* Set up our cancellation support. */
-  apr_signal(SIGINT, signal_handler);
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, signal_handler);
-#endif
-#ifdef SIGHUP
-  apr_signal(SIGHUP, signal_handler);
-#endif
-#ifdef SIGTERM
-  apr_signal(SIGTERM, signal_handler);
-#endif
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
+
 #ifdef SIGPIPE
   /* Disable SIGPIPE generation for the platforms that have it. */
   apr_signal(SIGPIPE, SIG_IGN);
@@ -1169,11 +1181,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif
 

Modified: subversion/trunk/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnsync/svnsync.c?rev=1729422&r1=1729421&r2=1729422&view=diff
==============================================================================
--- subversion/trunk/subversion/svnsync/svnsync.c (original)
+++ subversion/trunk/subversion/svnsync/svnsync.c Tue Feb  9 17:36:49 2016
@@ -331,16 +331,35 @@ typedef struct opt_baton_t {
 
 /* Global record of whether the user has requested cancellation. */
 static volatile sig_atomic_t cancelled = FALSE;
-static int signum_cancelled;
-
+static volatile sig_atomic_t signum_cancelled = 0;
+static int signal_map [] = {
+  SIGINT
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  , SIGBREAK,
+#endif
+#ifdef SIGHUP
+  , SIGHUP
+#endif
+#ifdef SIGTERM
+  , SIGTERM
+#endif
+};
 
 /* Callback function for apr_signal(). */
 static void
 signal_handler(int signum)
 {
+  int i;
+
   apr_signal(signum, SIG_IGN);
   cancelled = TRUE;
-  signum_cancelled = signum;
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    if (signal_map[i] == signum)
+      {
+        signum_cancelled = i + 1;
+        break;
+      }
 }
 
 
@@ -2370,20 +2389,8 @@ sub_main(int *exit_code, int argc, const
 
   opt_baton.source_prop_encoding = source_prop_encoding;
 
-  apr_signal(SIGINT, signal_handler);
-
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  apr_signal(SIGBREAK, signal_handler);
-#endif
-
-#ifdef SIGHUP
-  apr_signal(SIGHUP, signal_handler);
-#endif
-
-#ifdef SIGTERM
-  apr_signal(SIGTERM, signal_handler);
-#endif
+  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
+    apr_signal(signal_map[i], signal_handler);
 
 #ifdef SIGPIPE
   /* Disable SIGPIPE generation for the platforms that have it. */
@@ -2482,11 +2489,16 @@ main(int argc, const char *argv[])
   /* Resend any signal as this may cause the program to exit and
      allows the shell to use WIFSIGNALED and WTERMSIG to detect the
      signal.  See http://www.cons.org/cracauer/sigint.html */
-  if (cancelled)
+  if (cancelled && signum_cancelled)
     {
-      apr_signal(signum_cancelled, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum_cancelled);
+      int saved_signum = signal_map[signum_cancelled - 1];
+
+      if (saved_signum)
+        {
+          apr_signal(saved_signum, SIG_DFL);
+          /* No APR support for getpid() so cannot use apr_proc_kill(). */
+          kill(getpid(), saved_signum);
+        }
     }
 #endif