You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/08/01 23:23:56 UTC

svn commit: r1368252 - in /subversion/trunk/subversion: svn/main.c svnadmin/main.c

Author: julianfoad
Date: Wed Aug  1 21:23:55 2012
New Revision: 1368252

URL: http://svn.apache.org/viewvc?rev=1368252&view=rev
Log:
Factor out some of the error and pool handling in the main() functions of
svn and svnadmin.  Create and destroy the pool exactly once, in the outer
function, instead of destroying it at every return statement -- where,
inevitably, some were missed (at the three places where we were calling
svn_handle_error2(...TRUE...), specifically).

We should probably do the same for the other svn* executables too.

* subversion/svnadmin/main.c,
  subversion/svn/main.c
  (EXIT_ERROR): New macro.
  (SVN_INT_ERR): Redefine this public macro name to suppress error messages
    about writing to a broken pipe, and (in svnadmin only) to report the
    program name as 'svnadmin' instead of 'svn'.
  (sub_main): New name for the body of main(). Use SVN_INT_ERR and SVN_ERROR
    to simplify error handling.
  (main): Extract everything except the initialization of the application
    and of the top-level pool, and the destruction of that pool, into the
    new function sub_main(), and call that.

Modified:
    subversion/trunk/subversion/svn/main.c
    subversion/trunk/subversion/svnadmin/main.c

Modified: subversion/trunk/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=1368252&r1=1368251&r2=1368252&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/main.c (original)
+++ subversion/trunk/subversion/svn/main.c Wed Aug  1 21:23:55 2012
@@ -1591,14 +1591,28 @@ svn_cl__check_cancel(void *baton)
     return SVN_NO_ERROR;
 }
 
+
 
 /*** Main. ***/
 
-int
-main(int argc, const char *argv[])
+/* Report and clear the error ERR, and return EXIT_FAILURE. */
+#define EXIT_ERROR(err)                                                 \
+  svn_cmdline_handle_exit_error(err, NULL, "svn: ")
+
+/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
+ * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR. */
+#undef SVN_INT_ERR
+#define SVN_INT_ERR(expr)                                        \
+  do {                                                           \
+    svn_error_t *svn_err__temp = (expr);                         \
+    if (svn_err__temp)                                           \
+      return EXIT_ERROR(svn_err__temp);                          \
+  } while (0)
+
+static int
+sub_main(int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
-  apr_pool_t *pool;
   int opt_id;
   apr_getopt_t *os;
   svn_cl__opt_state_t opt_state = { 0, { 0 } };
@@ -1615,35 +1629,21 @@ main(int argc, const char *argv[])
   svn_boolean_t use_notifier = TRUE;
   apr_hash_t *changelists;
 
-  /* Initialize the app. */
-  if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
-    return EXIT_FAILURE;
-
-  /* Create our top-level pool.  Use a separate mutexless allocator,
-   * given this application is single threaded.
-   */
-  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
   /* Check library versions */
-  err = check_lib_versions();
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(check_lib_versions());
 
 #if defined(WIN32) || defined(__CYGWIN__)
   /* Set the working copy administrative directory name. */
   if (getenv("SVN_ASP_DOT_NET_HACK"))
     {
-      err = svn_wc_set_adm_dir("_svn", pool);
-      if (err)
-        return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      SVN_INT_ERR(svn_wc_set_adm_dir("_svn", pool));
     }
 #endif
 
   /* Initialize the RA library. */
-  err = svn_ra_initialize(pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(svn_ra_initialize(pool));
 
   /* Init our changelists hash. */
   changelists = apr_hash_make(pool);
@@ -1662,14 +1662,11 @@ main(int argc, const char *argv[])
   if (argc <= 1)
     {
       svn_cl__help(NULL, NULL, pool);
-      svn_pool_destroy(pool);
       return EXIT_FAILURE;
     }
 
   /* Else, parse options. */
-  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
   while (1)
@@ -1685,7 +1682,6 @@ main(int argc, const char *argv[])
       else if (apr_err)
         {
           svn_cl__help(NULL, NULL, pool);
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
 
@@ -1700,13 +1696,13 @@ main(int argc, const char *argv[])
             {
               err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
                                      _("Non-numeric limit argument given"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
           if (opt_state.limit <= 0)
             {
               err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                                     _("Argument to --limit must be positive"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
         }
         break;
@@ -1727,7 +1723,7 @@ main(int argc, const char *argv[])
               err = svn_error_create
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Can't specify -c with --old"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
 
           for (i = 0; i < change_revs->nelts; i++)
@@ -1760,7 +1756,7 @@ main(int argc, const char *argv[])
                                               _("Negative number in range (%s)"
                                                 " not supported with -c"),
                                               change_str);
-                      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+                      return EXIT_ERROR(err);
                     }
                   s = end + 1;
                   while (*s == 'r')
@@ -1772,14 +1768,14 @@ main(int argc, const char *argv[])
                   err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                           _("Non-numeric change argument (%s) "
                                             "given to -c"), change_str);
-                  return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+                  return EXIT_ERROR(err);
                 }
 
               if (changeno == 0)
                 {
                   err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                          _("There is no change 0"));
-                  return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+                  return EXIT_ERROR(err);
                 }
 
               if (is_negative)
@@ -1818,13 +1814,12 @@ main(int argc, const char *argv[])
         if (svn_opt_parse_revision_to_range(opt_state.revision_ranges,
                                             opt_arg, pool) != 0)
           {
-            err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-            if (! err)
-              err = svn_error_createf
+            SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+            err = svn_error_createf
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in revision argument '%s'"),
                  utf8_opt_arg);
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+            return EXIT_ERROR(err);
           }
         break;
       case 'v':
@@ -1844,12 +1839,9 @@ main(int argc, const char *argv[])
         opt_state.incremental = TRUE;
         break;
       case 'F':
-        err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-        if (! err)
-          err = svn_stringbuf_from_file2(&(opt_state.filedata),
-                                         utf8_opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+                                         utf8_opt_arg, pool));
         dash_F_arg = opt_arg;
         break;
       case opt_targets:
@@ -1860,14 +1852,9 @@ main(int argc, const char *argv[])
              the targets into an array, because otherwise we wouldn't
              know what delimiter to use for svn_cstring_split().  */
 
-          err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-
-          if (! err)
-            err = svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool);
-          if (! err)
-            err = svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool);
-          if (err)
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_INT_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
+          SVN_INT_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
           opt_state.targets = svn_cstring_split(buffer_utf8->data, "\n\r",
                                                 TRUE, pool);
         }
@@ -1893,55 +1880,51 @@ main(int argc, const char *argv[])
       case opt_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
         if (err)
-          return svn_cmdline_handle_exit_error
+          return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
                                _("Error converting depth "
-                                 "from locale to UTF-8")), pool, "svn: ");
+                                 "from locale to UTF-8")));
         opt_state.depth = svn_depth_from_word(utf8_opt_arg);
         if (opt_state.depth == svn_depth_unknown
             || opt_state.depth == svn_depth_exclude)
           {
-            return svn_cmdline_handle_exit_error
+            return EXIT_ERROR
               (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  _("'%s' is not a valid depth; try "
                                    "'empty', 'files', 'immediates', "
                                    "or 'infinity'"),
-                                 utf8_opt_arg), pool, "svn: ");
+                                 utf8_opt_arg));
           }
         break;
       case opt_set_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
         if (err)
-          return svn_cmdline_handle_exit_error
+          return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
                                _("Error converting depth "
-                                 "from locale to UTF-8")), pool, "svn: ");
+                                 "from locale to UTF-8")));
         opt_state.set_depth = svn_depth_from_word(utf8_opt_arg);
         /* svn_depth_exclude is okay for --set-depth. */
         if (opt_state.set_depth == svn_depth_unknown)
           {
-            return svn_cmdline_handle_exit_error
+            return EXIT_ERROR
               (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  _("'%s' is not a valid depth; try "
                                    "'exclude', 'empty', 'files', "
                                    "'immediates', or 'infinity'"),
-                                 utf8_opt_arg), pool, "svn: ");
+                                 utf8_opt_arg));
           }
         break;
       case opt_version:
         opt_state.version = TRUE;
         break;
       case opt_auth_username:
-        err = svn_utf_cstring_to_utf8(&opt_state.auth_username,
-                                      opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
+                                      opt_arg, pool));
         break;
       case opt_auth_password:
-        err = svn_utf_cstring_to_utf8(&opt_state.auth_password,
-                                      opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
+                                      opt_arg, pool));
         break;
       case opt_encoding:
         opt_state.encoding = apr_pstrdup(pool, opt_arg);
@@ -1989,9 +1972,7 @@ main(int argc, const char *argv[])
         opt_state.relocate = TRUE;
         break;
       case 'x':
-        err = svn_utf_cstring_to_utf8(&opt_state.extensions, opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions, opt_arg, pool));
         break;
       case opt_diff_cmd:
         opt_state.diff.diff_cmd = apr_pstrdup(pool, opt_arg);
@@ -2014,7 +1995,7 @@ main(int argc, const char *argv[])
             err = svn_error_create
               (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                _("Can't specify -c with --old"));
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+            return EXIT_ERROR(err);
           }
         opt_state.old_target = apr_pstrdup(pool, opt_arg);
         break;
@@ -2024,9 +2005,7 @@ main(int argc, const char *argv[])
       case opt_config_dir:
         {
           const char *path_utf8;
-          err = svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool);
-          if (err)
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool));
           opt_state.config_dir = svn_dirent_internal_style(path_utf8, pool);
         }
         break;
@@ -2036,12 +2015,9 @@ main(int argc, const char *argv[])
                    apr_array_make(pool, 1,
                                   sizeof(svn_cmdline__config_argument_t*));
 
-        err = svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool);
-        if (!err)
-          err = svn_cmdline__parse_config_option(opt_state.config_options,
-                                                 opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
+        SVN_INT_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
+                                                 opt_arg, pool));
         break;
       case opt_autoprops:
         opt_state.autoprops = TRUE;
@@ -2055,13 +2031,12 @@ main(int argc, const char *argv[])
           opt_state.native_eol = apr_pstrdup(pool, opt_arg);
         else
           {
-            err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-            if (! err)
-              err = svn_error_createf
+            SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+            err = svn_error_createf
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in native-eol argument '%s'"),
                  utf8_opt_arg);
-            return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+            return EXIT_ERROR(err);
           }
         break;
       case opt_no_unlock:
@@ -2093,9 +2068,7 @@ main(int argc, const char *argv[])
         opt_state.no_revprops = TRUE;
         break;
       case opt_with_revprop:
-        err = svn_opt_parse_revprop(&opt_state.revprop_table, opt_arg, pool);
-        if (err != SVN_NO_ERROR)
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        SVN_INT_ERR(svn_opt_parse_revprop(&opt_state.revprop_table, opt_arg, pool));
         break;
       case opt_parents:
         opt_state.parents = TRUE;
@@ -2106,20 +2079,18 @@ main(int argc, const char *argv[])
       case opt_accept:
         opt_state.accept_which = svn_cl__accept_from_word(opt_arg);
         if (opt_state.accept_which == svn_cl__accept_invalid)
-          return svn_cmdline_handle_exit_error
+          return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'%s' is not a valid --accept value"),
-                               opt_arg),
-             pool, "svn: ");
+                               opt_arg));
         break;
       case opt_show_revs:
         opt_state.show_revs = svn_cl__show_revs_from_word(opt_arg);
         if (opt_state.show_revs == svn_cl__show_revs_invalid)
-          return svn_cmdline_handle_exit_error
+          return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'%s' is not a valid --show-revs value"),
-                               opt_arg),
-             pool, "svn: ");
+                               opt_arg));
         break;
       case opt_reintegrate:
         opt_state.reintegrate = TRUE;
@@ -2131,13 +2102,13 @@ main(int argc, const char *argv[])
             {
               err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
                                       _("Invalid strip count '%s'"), opt_arg);
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
           if (opt_state.strip < 0)
             {
               err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                                      _("Argument to --strip must be positive"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
         }
         break;
@@ -2186,9 +2157,7 @@ main(int argc, const char *argv[])
     }
 
   /* Turn our hash of changelists into an array of unique ones. */
-  err = svn_hash_keys(&(opt_state.changelists), changelists, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(svn_hash_keys(&(opt_state.changelists), changelists, pool));
 
   /* ### This really belongs in libsvn_client.  The trouble is,
      there's no one place there to run it from, no
@@ -2200,9 +2169,7 @@ main(int argc, const char *argv[])
      hand, the alternative is effectively to demand that they call
      svn_config_ensure() instead, so maybe we should have a generic
      init function anyway.  Thoughts?  */
-  err = svn_config_ensure(opt_state.config_dir, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(svn_config_ensure(opt_state.config_dir, pool));
 
   /* If the user asked for help, then the rest of the arguments are
      the names of subcommands to get help on (if any), or else they're
@@ -2235,7 +2202,6 @@ main(int argc, const char *argv[])
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Subcommand argument required\n")));
               svn_cl__help(NULL, NULL, pool);
-              svn_pool_destroy(pool);
               return EXIT_FAILURE;
             }
         }
@@ -2247,15 +2213,12 @@ main(int argc, const char *argv[])
           if (subcommand == NULL)
             {
               const char *first_arg_utf8;
-              err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
-              if (err)
-                return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool));
               svn_error_clear
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Unknown command: '%s'\n"),
                                      first_arg_utf8));
               svn_cl__help(NULL, NULL, pool);
-              svn_pool_destroy(pool);
               return EXIT_FAILURE;
             }
         }
@@ -2289,7 +2252,6 @@ main(int argc, const char *argv[])
                (stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svn help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
     }
@@ -2304,7 +2266,7 @@ main(int argc, const char *argv[])
                                  _("Multiple revision arguments "
                                    "encountered; can't specify -c twice, "
                                    "or both -c and -r"));
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          return EXIT_ERROR(err);
         }
     }
 
@@ -2315,7 +2277,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--depth and --set-depth are mutually "
                                "exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* Disallow simultaneous use of both --with-all-revprops and
@@ -2325,7 +2287,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--with-all-revprops and --with-no-revprops "
                                "are mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* Disallow simultaneous use of both --with-revprop and
@@ -2335,7 +2297,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--with-revprop and --with-no-revprops "
                                "are mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* Disallow simultaneous use of both -m and -F, when they are
@@ -2348,7 +2310,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--message (-m) and --file (-F) "
                                "are mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* --trust-server-cert can only be used with --non-interactive */
@@ -2357,7 +2319,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--trust-server-cert requires "
                                "--non-interactive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* Disallow simultaneous use of both --diff-cmd and
@@ -2367,7 +2329,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("--diff-cmd and --internal-diff "
                                "are mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* Ensure that 'revision_ranges' has at least one item, and make
@@ -2387,8 +2349,7 @@ main(int argc, const char *argv[])
 
   /* Create a client context object. */
   command_baton.opt_state = &opt_state;
-  if ((err = svn_client_create_context(&ctx, pool)))
-    return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+  SVN_INT_ERR(svn_client_create_context(&ctx, pool));
   command_baton.ctx = ctx;
 
   /* If we're running a command that could result in a commit, verify
@@ -2435,7 +2396,7 @@ main(int argc, const char *argv[])
                          _("Lock comment file is a versioned file; "
                            "use '--force-log' to override"));
                     }
-                  return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+                  return EXIT_ERROR(err);
                 }
             }
           svn_error_clear(err);
@@ -2463,7 +2424,7 @@ main(int argc, const char *argv[])
                      _("The lock comment is a pathname "
                        "(was -F intended?); use '--force-log' to override"));
                 }
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
         }
     }
@@ -2476,7 +2437,7 @@ main(int argc, const char *argv[])
           err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                  _("--relocate and --depth are mutually "
                                    "exclusive"));
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          return EXIT_ERROR(err);
         }
       if (! descend)
         {
@@ -2484,7 +2445,7 @@ main(int argc, const char *argv[])
                     SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                     _("--relocate and --non-recursive (-N) are mutually "
                       "exclusive"));
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          return EXIT_ERROR(err);
         }
     }
 
@@ -2499,7 +2460,7 @@ main(int argc, const char *argv[])
       if (opt_state.end_revision.kind != svn_opt_revision_unspecified)
         {
           err = svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          return EXIT_ERROR(err);
         }
     }
 
@@ -2539,7 +2500,7 @@ main(int argc, const char *argv[])
           svn_error_clear(err);
         }
       else
-        return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+        return EXIT_ERROR(err);
     }
 
   cfg_config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
@@ -2572,7 +2533,7 @@ main(int argc, const char *argv[])
       err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                              _("--auto-props and --no-auto-props are "
                                "mutually exclusive"));
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
 
   /* The --reintegrate option is mutually exclusive with both
@@ -2587,14 +2548,14 @@ main(int argc, const char *argv[])
                                      _("--reintegrate cannot be used with "
                                        "--ignore-ancestry or "
                                        "--record-only"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
           else
             {
               err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                      _("--reintegrate cannot be used with "
                                        "--ignore-ancestry"));
-              return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+              return EXIT_ERROR(err);
             }
           }
       else if (opt_state.record_only)
@@ -2602,7 +2563,7 @@ main(int argc, const char *argv[])
           err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                  _("--reintegrate cannot be used with "
                                    "--record-only"));
-          return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+          return EXIT_ERROR(err);
         }
     }
 
@@ -2617,9 +2578,8 @@ main(int argc, const char *argv[])
                      SVN_CONFIG_OPTION_MIMETYPES_FILE, FALSE);
       if (mimetypes_file && *mimetypes_file)
         {
-          if ((err = svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
-                                                 mimetypes_file, pool)))
-            svn_handle_error2(err, stderr, TRUE, "svn: ");
+          SVN_INT_ERR(svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
+                                                 mimetypes_file, pool));
         }
 
       if (opt_state.autoprops)
@@ -2657,9 +2617,7 @@ main(int argc, const char *argv[])
     use_notifier = FALSE;
   if (use_notifier)
     {
-      err = svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, pool);
-      if (err)
-        return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, pool));
     }
 
   /* Set up our cancellation support. */
@@ -2689,7 +2647,7 @@ main(int argc, const char *argv[])
 #endif
 
   /* Set up Authentication stuff. */
-  if ((err = svn_cmdline_create_auth_baton(&ab,
+  SVN_INT_ERR(svn_cmdline_create_auth_baton(&ab,
                                            opt_state.non_interactive,
                                            opt_state.auth_username,
                                            opt_state.auth_password,
@@ -2699,18 +2657,16 @@ main(int argc, const char *argv[])
                                            cfg_config,
                                            ctx->cancel_func,
                                            ctx->cancel_baton,
-                                           pool)))
-    svn_handle_error2(err, stderr, TRUE, "svn: ");
+                                           pool));
 
   ctx->auth_baton = ab;
 
   /* Set up conflict resolution callback. */
-  if ((err = svn_config_get_bool(cfg_config, &interactive_conflicts,
+  SVN_INT_ERR(svn_config_get_bool(cfg_config, &interactive_conflicts,
                                  SVN_CONFIG_SECTION_MISCELLANY,
                                  SVN_CONFIG_OPTION_INTERACTIVE_CONFLICTS,
-                                 TRUE)))  /* ### interactivity on by default.
+                                 TRUE));  /* ### interactivity on by default.
                                                  we can change this. */
-    svn_handle_error2(err, stderr, TRUE, "svn: ");
 
   /* The new svn behavior is to postpone everything until after the operation
      completed */
@@ -2739,18 +2695,16 @@ main(int argc, const char *argv[])
       if (opt_state.non_interactive)
         {
           if (opt_state.accept_which == svn_cl__accept_edit)
-            return svn_cmdline_handle_exit_error
+            return EXIT_ERROR
               (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  _("--accept=%s incompatible with"
-                                   " --non-interactive"), SVN_CL__ACCEPT_EDIT),
-               pool, "svn: ");
+                                   " --non-interactive"), SVN_CL__ACCEPT_EDIT));
           if (opt_state.accept_which == svn_cl__accept_launch)
-            return svn_cmdline_handle_exit_error
+            return EXIT_ERROR
               (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  _("--accept=%s incompatible with"
                                    " --non-interactive"),
-                                 SVN_CL__ACCEPT_LAUNCH),
-               pool, "svn: ");
+                                 SVN_CL__ACCEPT_LAUNCH));
         }
 
       opt_state.conflict_func = svn_cl__conflict_handler;
@@ -2792,17 +2746,35 @@ main(int argc, const char *argv[])
                          "(type 'svn help cleanup' for details)"));
         }
 
-      return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      return EXIT_ERROR(err);
     }
   else
     {
       /* Ensure that stdout is flushed, so the user will see any write errors.
          This makes sure that output is not silently lost. */
-      err = svn_cmdline_fflush(stdout);
-      if (err)
-        return svn_cmdline_handle_exit_error(err, pool, "svn: ");
+      SVN_INT_ERR(svn_cmdline_fflush(stdout));
 
-      svn_pool_destroy(pool);
       return EXIT_SUCCESS;
     }
 }
+
+int
+main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  int exit_code;
+
+  /* Initialize the app. */
+  if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
+    return EXIT_FAILURE;
+
+  /* Create our top-level pool.  Use a separate mutexless allocator,
+   * given this application is single threaded.
+   */
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+
+  exit_code = sub_main(argc, argv, pool);
+
+  svn_pool_destroy(pool);
+  return exit_code;
+}

Modified: subversion/trunk/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/main.c?rev=1368252&r1=1368251&r2=1368252&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/main.c (original)
+++ subversion/trunk/subversion/svnadmin/main.c Wed Aug  1 21:23:55 2012
@@ -1790,12 +1790,26 @@ subcommand_upgrade(apr_getopt_t *os, voi
 
 /** Main. **/
 
-int
-main(int argc, const char *argv[])
+/* Report and clear the error ERR, and return EXIT_FAILURE. */
+#define EXIT_ERROR(err)                                                 \
+  svn_cmdline_handle_exit_error(err, NULL, "svnadmin: ")
+
+/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
+ * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR, amd with the
+ * program name 'svnadmin' instead of 'svn'. */
+#undef SVN_INT_ERR
+#define SVN_INT_ERR(expr)                                        \
+  do {                                                           \
+    svn_error_t *svn_err__temp = (expr);                         \
+    if (svn_err__temp)                                           \
+      return EXIT_ERROR(svn_err__temp);                          \
+  } while (0)
+
+static int
+sub_main(int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
   apr_status_t apr_err;
-  apr_pool_t *pool;
 
   const svn_opt_subcommand_desc2_t *subcommand = NULL;
   struct svnadmin_opt_state opt_state = { 0 };
@@ -1804,31 +1818,17 @@ main(int argc, const char *argv[])
   apr_array_header_t *received_opts;
   int i;
 
-  /* Initialize the app. */
-  if (svn_cmdline_init("svnadmin", stderr) != EXIT_SUCCESS)
-    return EXIT_FAILURE;
-
-  /* Create our top-level pool.  Use a separate mutexless allocator,
-   * given this application is single threaded.
-   */
-  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
-
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
   /* Check library versions */
-  err = check_lib_versions();
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+  SVN_INT_ERR(check_lib_versions());
 
   /* Initialize the FS library. */
-  err = svn_fs_initialize(pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+  SVN_INT_ERR(svn_fs_initialize(pool));
 
   if (argc <= 1)
     {
       SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-      svn_pool_destroy(pool);
       return EXIT_FAILURE;
     }
 
@@ -1838,9 +1838,7 @@ main(int argc, const char *argv[])
   opt_state.memory_cache_size = svn_cache_config_get()->cache_size;
 
   /* Parse options. */
-  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
 
@@ -1856,7 +1854,6 @@ main(int argc, const char *argv[])
       else if (apr_err)
         {
           SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
 
@@ -1871,7 +1868,7 @@ main(int argc, const char *argv[])
               err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Multiple revision arguments encountered; "
                    "try '-r N:M' instead of '-r N -r M'"));
-              return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+              return EXIT_ERROR(err);
             }
           if (svn_opt_parse_revision(&(opt_state.start_revision),
                                      &(opt_state.end_revision),
@@ -1884,7 +1881,7 @@ main(int argc, const char *argv[])
                 err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                         _("Syntax error in revision argument '%s'"),
                         utf8_opt_arg);
-              return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+              return EXIT_ERROR(err);
             }
         }
         break;
@@ -1927,15 +1924,11 @@ main(int argc, const char *argv[])
         opt_state.pre_1_8_compatible = TRUE;
         break;
       case svnadmin__fs_type:
-        err = svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, pool));
         break;
       case svnadmin__parent_dir:
-        err = svn_utf_cstring_to_utf8(&opt_state.parent_dir, opt_arg,
-                                      pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.parent_dir, opt_arg,
+                                      pool));
         opt_state.parent_dir
           = svn_dirent_internal_style(opt_state.parent_dir, pool);
         break;
@@ -1967,9 +1960,7 @@ main(int argc, const char *argv[])
         opt_state.clean_logs = TRUE;
         break;
       case svnadmin__config_dir:
-        err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
-        if (err)
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.config_dir =
             apr_pstrdup(pool, svn_dirent_canonicalize(utf8_opt_arg, pool));
         break;
@@ -1979,7 +1970,6 @@ main(int argc, const char *argv[])
       default:
         {
           SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
       }  /* close `switch' */
@@ -2014,7 +2004,6 @@ main(int argc, const char *argv[])
               svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                         _("subcommand argument required\n")));
               SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              svn_pool_destroy(pool);
               return EXIT_FAILURE;
             }
         }
@@ -2025,14 +2014,11 @@ main(int argc, const char *argv[])
           if (subcommand == NULL)
             {
               const char *first_arg_utf8;
-              err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
-              if (err)
-                return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool));
               svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                                   _("Unknown command: '%s'\n"),
                                                   first_arg_utf8));
               SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              svn_pool_destroy(pool);
               return EXIT_FAILURE;
             }
         }
@@ -2048,13 +2034,13 @@ main(int argc, const char *argv[])
         {
           err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  _("Repository argument required"));
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+          return EXIT_ERROR(err);
         }
 
       if ((err = svn_utf_cstring_to_utf8(&repos_path,
                                          os->argv[os->ind++], pool)))
         {
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+          return EXIT_ERROR(err);
         }
 
       if (svn_path_is_url(repos_path))
@@ -2062,7 +2048,7 @@ main(int argc, const char *argv[])
           err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                   _("'%s' is a URL when it should be a "
                                     "local path"), repos_path);
-          return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+          return EXIT_ERROR(err);
         }
 
       opt_state.repository_path = svn_dirent_internal_style(repos_path, pool);
@@ -2094,7 +2080,6 @@ main(int argc, const char *argv[])
                             , _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svnadmin help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
-          svn_pool_destroy(pool);
           return EXIT_FAILURE;
         }
     }
@@ -2137,18 +2122,38 @@ main(int argc, const char *argv[])
           err = svn_error_quick_wrap(err,
                                      _("Try 'svnadmin help' for more info"));
         }
-      return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
+      return EXIT_ERROR(err);
     }
   else
     {
-      svn_pool_destroy(pool);
       /* Ensure that everything is written to stdout, so the user will
          see any print errors. */
       err = svn_cmdline_fflush(stdout);
       if (err)
         {
-          return svn_cmdline_handle_exit_error(err, NULL, "svnadmin: ");
+          return EXIT_ERROR(err);
         }
       return EXIT_SUCCESS;
     }
 }
+
+int
+main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  int exit_code;
+
+  /* Initialize the app. */
+  if (svn_cmdline_init("svnadmin", stderr) != EXIT_SUCCESS)
+    return EXIT_FAILURE;
+
+  /* Create our top-level pool.  Use a separate mutexless allocator,
+   * given this application is single threaded.
+   */
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+
+  exit_code = sub_main(argc, argv, pool);
+
+  svn_pool_destroy(pool);
+  return exit_code;
+}