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 2013/11/21 15:30:05 UTC

svn commit: r1544194 - in /subversion/trunk/tools: client-side/svn-bench/svn-bench.c dev/svnraisetreeconflict/svnraisetreeconflict.c server-side/svn-rep-sharing-stats.c server-side/svnauthz.c

Author: julianfoad
Date: Thu Nov 21 14:30:05 2013
New Revision: 1544194

URL: http://svn.apache.org/r1544194
Log:
Adjust four of our command-line tools for more consistent error reporting,
following the pattern of the core command-line programs.

The visible effects are: error messages will now always have the correct
prefix, and an error will always be reported on failure to flush stdout.

* tools/client-side/svn-bench/svn-bench.c,
  (EXIT_ERROR, SVN_INT_ERR): Delete.
  (sub_main): Return a standard Subversion error object and use standard
    Subversion error handling for the most part. Add an exit_code output
    parameter and use this to yield a non-zero code when not returning an
    error. Don't flush stdout here on success.
  (main): Always use the correct program name in the error message prefix,
    always flush stdout here, and always display any errors here.

* tools/dev/svnraisetreeconflict/svnraisetreeconflict.c
  (SVNRAISETC_INT_ERR): Delete.
  (usage, help): Don't exit.
  (sub_main): New, extracted from main(). Don't do tear-down actions --
    destroying the pool, flushing stdout -- before returning. Simplify error
    handling by using the standard ways such as SVN_ERR().
  (main): Just do initilization and tear-down around a call to sub_main().

* tools/server-side/svnauthz.c
  (handle_exit_error, EXIT_ERROR, SVN_INT_ERR): Delete.
  (sub_main, main): Same as for svn-bench.

* tools/server-side/svn-rep-sharing-stats.c
  (help): Don't exit.
  (sub_main, main): Same as for svnraisetreeconflict.

Modified:
    subversion/trunk/tools/client-side/svn-bench/svn-bench.c
    subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c
    subversion/trunk/tools/server-side/svn-rep-sharing-stats.c
    subversion/trunk/tools/server-side/svnauthz.c

Modified: subversion/trunk/tools/client-side/svn-bench/svn-bench.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/client-side/svn-bench/svn-bench.c?rev=1544194&r1=1544193&r2=1544194&view=diff
==============================================================================
--- subversion/trunk/tools/client-side/svn-bench/svn-bench.c (original)
+++ subversion/trunk/tools/client-side/svn-bench/svn-bench.c Thu Nov 21 14:30:05 2013
@@ -322,22 +322,13 @@ svn_cl__check_cancel(void *baton)
 
 /*** Main. ***/
 
-/* 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)
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
   int opt_id;
@@ -356,18 +347,18 @@ sub_main(int argc, const char *argv[], a
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
   /* Check library versions */
-  SVN_INT_ERR(check_lib_versions());
+  SVN_ERR(check_lib_versions());
 
 #if defined(WIN32) || defined(__CYGWIN__)
   /* Set the working copy administrative directory name. */
   if (getenv("SVN_ASP_DOT_NET_HACK"))
     {
-      SVN_INT_ERR(svn_wc_set_adm_dir("_svn", pool));
+      SVN_ERR(svn_wc_set_adm_dir("_svn", pool));
     }
 #endif
 
   /* Initialize the RA library. */
-  SVN_INT_ERR(svn_ra_initialize(pool));
+  SVN_ERR(svn_ra_initialize(pool));
 
   /* Begin processing arguments. */
   opt_state.start_revision.kind = svn_opt_revision_unspecified;
@@ -379,12 +370,13 @@ sub_main(int argc, const char *argv[], a
   /* No args?  Show usage. */
   if (argc <= 1)
     {
-      SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-      return EXIT_FAILURE;
+      SVN_ERR(svn_cl__help(NULL, NULL, pool));
+      *exit_code = EXIT_FAILURE;
+      return SVN_NO_ERROR;
     }
 
   /* Else, parse options. */
-  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
   while (1)
@@ -399,8 +391,9 @@ sub_main(int argc, const char *argv[], a
         break;
       else if (apr_err)
         {
-          SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-          return EXIT_FAILURE;
+          SVN_ERR(svn_cl__help(NULL, NULL, pool));
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
 
       /* Stash the option code in an array before parsing it. */
@@ -412,15 +405,13 @@ sub_main(int argc, const char *argv[], a
           err = svn_cstring_atoi(&opt_state.limit, opt_arg);
           if (err)
             {
-              err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                                     _("Non-numeric limit argument given"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                      _("Non-numeric limit argument given"));
             }
           if (opt_state.limit <= 0)
             {
-              err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
-                                    _("Argument to --limit must be positive"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                                      _("Argument to --limit must be positive"));
             }
         }
         break;
@@ -454,12 +445,11 @@ sub_main(int argc, const char *argv[], a
                 {
                   if (changeno < 0 || is_negative)
                     {
-                      err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
-                                              NULL,
-                                              _("Negative number in range (%s)"
-                                                " not supported with -c"),
-                                              change_str);
-                      return EXIT_ERROR(err);
+                      return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+                                               NULL,
+                                               _("Negative number in range (%s)"
+                                                 " not supported with -c"),
+                                               change_str);
                     }
                   s = end + 1;
                   while (*s == 'r')
@@ -468,17 +458,15 @@ sub_main(int argc, const char *argv[], a
                 }
               if (end == change_str || *end != '\0')
                 {
-                  err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                          _("Non-numeric change argument (%s) "
-                                            "given to -c"), change_str);
-                  return EXIT_ERROR(err);
+                  return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                           _("Non-numeric change argument (%s) "
+                                             "given to -c"), change_str);
                 }
 
               if (changeno == 0)
                 {
-                  err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                         _("There is no change 0"));
-                  return EXIT_ERROR(err);
+                  return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                          _("There is no change 0"));
                 }
 
               if (is_negative)
@@ -517,12 +505,11 @@ sub_main(int argc, const char *argv[], a
         if (svn_opt_parse_revision_to_range(opt_state.revision_ranges,
                                             opt_arg, pool) != 0)
           {
-            SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-            err = svn_error_createf
+            SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+            return svn_error_createf
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in revision argument '%s'"),
                  utf8_opt_arg);
-            return EXIT_ERROR(err);
           }
         break;
       case 'v':
@@ -543,9 +530,9 @@ sub_main(int argc, const char *argv[], a
              the targets into an array, because otherwise we wouldn't
              know what delimiter to use for svn_cstring_split().  */
 
-          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));
+          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
+          SVN_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
           opt_state.targets = svn_cstring_split(buffer_utf8->data, "\n\r",
                                                 TRUE, pool);
         }
@@ -559,31 +546,29 @@ sub_main(int argc, const char *argv[], a
       case opt_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
         if (err)
-          return EXIT_ERROR
-            (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                               _("Error converting depth "
-                                 "from locale to UTF-8")));
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                   _("Error converting depth "
+                                     "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 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));
+            return 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);
           }
         break;
       case opt_version:
         opt_state.version = TRUE;
         break;
       case opt_auth_username:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
                                             opt_arg, pool));
         break;
       case opt_auth_password:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
                                             opt_arg, pool));
         break;
       case opt_stop_on_copy:
@@ -602,13 +587,13 @@ sub_main(int argc, const char *argv[], a
         opt_state.trust_server_cert = TRUE;
         break;
       case 'x':
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions,
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions,
                                             opt_arg, pool));
         break;
       case opt_config_dir:
         {
           const char *path_utf8;
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool));
+          SVN_ERR(svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool));
           opt_state.config_dir = svn_dirent_internal_style(path_utf8, pool);
         }
         break;
@@ -618,8 +603,8 @@ sub_main(int argc, const char *argv[], a
                    apr_array_make(pool, 1,
                                   sizeof(svn_cmdline__config_argument_t*));
 
-        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,
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
+        SVN_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
                                                      opt_arg, pool));
         break;
       case opt_with_all_revprops:
@@ -631,7 +616,7 @@ sub_main(int argc, const char *argv[], a
         opt_state.no_revprops = TRUE;
         break;
       case opt_with_revprop:
-        SVN_INT_ERR(svn_opt_parse_revprop(&opt_state.revprop_table,
+        SVN_ERR(svn_opt_parse_revprop(&opt_state.revprop_table,
                                           opt_arg, pool));
         break;
       case 'g':
@@ -657,7 +642,7 @@ sub_main(int argc, const char *argv[], a
      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?  */
-  SVN_INT_ERR(svn_config_ensure(opt_state.config_dir, pool));
+  SVN_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
@@ -690,8 +675,9 @@ sub_main(int argc, const char *argv[], a
               svn_error_clear
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Subcommand argument required\n")));
-              SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(svn_cl__help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
       else
@@ -702,14 +688,15 @@ sub_main(int argc, const char *argv[], a
           if (subcommand == NULL)
             {
               const char *first_arg_utf8;
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
                                                   first_arg, pool));
               svn_error_clear
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Unknown subcommand: '%s'\n"),
                                      first_arg_utf8));
-              SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(svn_cl__help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
     }
@@ -735,14 +722,15 @@ sub_main(int argc, const char *argv[], a
                                           subcommand, pool);
           svn_opt_format_option(&optstr, badopt, FALSE, pool);
           if (subcommand->name[0] == '-')
-            SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
+            SVN_ERR(svn_cl__help(NULL, NULL, pool));
           else
             svn_error_clear
               (svn_cmdline_fprintf
                (stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svn-bench help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -751,11 +739,10 @@ sub_main(int argc, const char *argv[], a
     {
       if (opt_state.revision_ranges->nelts > 1)
         {
-          err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("Multiple revision arguments "
-                                   "encountered; can't specify -c twice, "
-                                   "or both -c and -r"));
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  _("Multiple revision arguments "
+                                    "encountered; can't specify -c twice, "
+                                    "or both -c and -r"));
         }
     }
 
@@ -763,29 +750,26 @@ sub_main(int argc, const char *argv[], a
      --with-no-revprops.  */
   if (opt_state.all_revprops && opt_state.no_revprops)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--with-all-revprops and --with-no-revprops "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--with-all-revprops and --with-no-revprops "
+                                "are mutually exclusive"));
     }
 
   /* Disallow simultaneous use of both --with-revprop and
      --with-no-revprops.  */
   if (opt_state.revprop_table && opt_state.no_revprops)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--with-revprop and --with-no-revprops "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--with-revprop and --with-no-revprops "
+                                "are mutually exclusive"));
     }
 
   /* --trust-server-cert can only be used with --non-interactive */
   if (opt_state.trust_server_cert && !opt_state.non_interactive)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--trust-server-cert requires "
-                               "--non-interactive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--trust-server-cert requires "
+                                "--non-interactive"));
     }
 
   /* Ensure that 'revision_ranges' has at least one item, and make
@@ -805,7 +789,7 @@ sub_main(int argc, const char *argv[], a
 
   /* Create a client context object. */
   command_baton.opt_state = &opt_state;
-  SVN_INT_ERR(svn_client_create_context2(&ctx, NULL, pool));
+  SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
   command_baton.ctx = ctx;
 
   /* Only a few commands can accept a revision range; the rest can take at
@@ -814,8 +798,7 @@ sub_main(int argc, const char *argv[], a
     {
       if (opt_state.end_revision.kind != svn_opt_revision_unspecified)
         {
-          err = svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
         }
     }
 
@@ -836,7 +819,7 @@ sub_main(int argc, const char *argv[], a
           svn_error_clear(err);
         }
       else
-        return EXIT_ERROR(err);
+        return err;
     }
 
   cfg_config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
@@ -861,7 +844,7 @@ sub_main(int argc, const char *argv[], a
     use_notifier = FALSE;
   if (use_notifier)
     {
-      SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
+      SVN_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
                                        pool));
     }
 
@@ -892,7 +875,7 @@ sub_main(int argc, const char *argv[], a
 #endif
 
   /* Set up Authentication stuff. */
-  SVN_INT_ERR(svn_cmdline_create_auth_baton(&ab,
+  SVN_ERR(svn_cmdline_create_auth_baton(&ab,
                                             opt_state.non_interactive,
                                             opt_state.auth_username,
                                             opt_state.auth_password,
@@ -942,26 +925,21 @@ sub_main(int argc, const char *argv[], a
                          "(type 'svn help cleanup' for details)"));
         }
 
-      return EXIT_ERROR(err);
+      return err;
     }
-  else
-    {
-      /* Ensure that stdout is flushed, so the user will see any write errors.
-         This makes sure that output is not silently lost. */
-      SVN_INT_ERR(svn_cmdline_fflush(stdout));
 
-      return EXIT_SUCCESS;
-    }
+  return SVN_NO_ERROR;
 }
 
 int
 main(int argc, const char *argv[])
 {
   apr_pool_t *pool;
-  int exit_code;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
 
   /* Initialize the app. */
-  if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
+  if (svn_cmdline_init("svn-bench", stderr) != EXIT_SUCCESS)
     return EXIT_FAILURE;
 
   /* Create our top-level pool.  Use a separate mutexless allocator,
@@ -969,7 +947,17 @@ main(int argc, const char *argv[])
    */
   pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
-  exit_code = sub_main(argc, argv, pool);
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
+
+  if (err)
+    {
+      exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svn-bench: ");
+    }
 
   svn_pool_destroy(pool);
   return exit_code;

Modified: subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c?rev=1544194&r1=1544193&r2=1544194&view=diff
==============================================================================
--- subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c (original)
+++ subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c Thu Nov 21 14:30:05 2013
@@ -49,22 +49,6 @@
 
 #define OPT_VERSION SVN_OPT_FIRST_LONGOPT_ID
 
-/** A statement macro, similar to @c SVN_INT_ERR, but issues a
- * message saying "svnraisetreeconflict:" instead of "svn:".
- *
- * Evaluate @a expr. If it yields an error, handle that error and
- * return @c EXIT_FAILURE.
- */
-#define SVNRAISETC_INT_ERR(expr)                                 \
-  do {                                                           \
-    svn_error_t *svn_err__temp = (expr);                         \
-    if (svn_err__temp) {                                         \
-      svn_handle_error2(svn_err__temp, stderr, FALSE,            \
-                        "svnraisetreeconflict: ");               \
-      svn_error_clear(svn_err__temp);                            \
-      return EXIT_FAILURE; }                                     \
-  } while (0)
-
 static svn_error_t *
 version(apr_pool_t *pool)
 {
@@ -78,7 +62,6 @@ usage(apr_pool_t *pool)
   svn_error_clear(svn_cmdline_fprintf
                   (stderr, pool,
                    _("Type 'svnraisetreeconflict --help' for usage.\n")));
-  exit(1);
 }
 
 /***************************************************************************
@@ -295,7 +278,6 @@ help(const apr_getopt_option_t *options,
       get_enum_str(node_kind_map, svn_node_file),
       get_enum_str(node_kind_map, svn_node_none)
       ));
-  exit(0);
 }
 
 
@@ -314,11 +296,14 @@ check_lib_versions(void)
   return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
 }
 
-int
-main(int argc, const char *argv[])
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
-  apr_pool_t *pool;
-  svn_error_t *err;
   apr_getopt_t *os;
   const apr_getopt_option_t options[] =
     {
@@ -329,33 +314,18 @@ main(int argc, const char *argv[])
     };
   apr_array_header_t *remaining_argv;
 
-  /* Initialize the app. */
-  if (svn_cmdline_init("svnraisetreeconflict", 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));
-
   /* Check library versions */
-  err = check_lib_versions();
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svnraisetreeconflict: ");
+  SVN_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, "svnraisetreeconflict: ");
+      SVN_ERR(svn_wc_set_adm_dir("_svn", pool));
     }
 #endif
 
-  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svnraisetreeconflict: ");
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
   while (1)
@@ -366,19 +336,24 @@ main(int argc, const char *argv[])
       if (APR_STATUS_IS_EOF(status))
         break;
       if (status != APR_SUCCESS)
-        usage(pool);  /* this will exit() */
+        {
+          usage(pool);
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
+        }
 
       switch (opt)
         {
         case 'h':
           help(options, pool);
-          break;
+          return SVN_NO_ERROR;
         case OPT_VERSION:
-          SVNRAISETC_INT_ERR(version(pool));
-          exit(0);
-          break;
+          SVN_ERR(version(pool));
+          return SVN_NO_ERROR;
         default:
-          usage(pool);  /* this will exit() */
+          usage(pool);
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -388,23 +363,53 @@ main(int argc, const char *argv[])
     {
       const char *s;
 
-      SVNRAISETC_INT_ERR(svn_utf_cstring_to_utf8(&s, os->argv[os->ind++],
-                                                 pool));
+      SVN_ERR(svn_utf_cstring_to_utf8(&s, os->argv[os->ind++], pool));
       APR_ARRAY_PUSH(remaining_argv, const char *) = s;
     }
 
   if (remaining_argv->nelts < 1)
-    usage(pool);  /* this will exit() */
+    {
+      usage(pool);
+      *exit_code = EXIT_FAILURE;
+      return SVN_NO_ERROR;
+    }
 
   /* Do the main task */
-  SVNRAISETC_INT_ERR(raise_tree_conflict(remaining_argv->nelts,
-                                         (const char **)remaining_argv->elts,
-                                         pool));
+  SVN_ERR(raise_tree_conflict(remaining_argv->nelts,
+                              (const char **)remaining_argv->elts,
+                              pool));
 
-  svn_pool_destroy(pool);
+  return SVN_NO_ERROR;
+}
+
+int
+main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
 
-  /* Flush stdout to make sure that the user will see any printing errors. */
-  SVNRAISETC_INT_ERR(svn_cmdline_fflush(stdout));
+  /* Initialize the app. */
+  if (svn_cmdline_init("svnraisetreeconflict", stderr) != EXIT_SUCCESS)
+    return EXIT_FAILURE;
 
-  return EXIT_SUCCESS;
+  /* 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));
+
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
+
+  if (err)
+    {
+      exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svnraisetreeconflict: ");
+    }
+
+  svn_pool_destroy(pool);
+  return exit_code;
 }

Modified: subversion/trunk/tools/server-side/svn-rep-sharing-stats.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/server-side/svn-rep-sharing-stats.c?rev=1544194&r1=1544193&r2=1544194&view=diff
==============================================================================
--- subversion/trunk/tools/server-side/svn-rep-sharing-stats.c (original)
+++ subversion/trunk/tools/server-side/svn-rep-sharing-stats.c Thu Nov 21 14:30:05 2013
@@ -79,7 +79,6 @@ help(const apr_getopt_option_t *options,
       ++options;
     }
   svn_error_clear(svn_cmdline_fprintf(stdout, pool, "\n"));
-  exit(0);
 }
 
 
@@ -424,14 +423,17 @@ static svn_error_t *process(const char *
   return SVN_NO_ERROR;
 }
 
-int
-main(int argc, const char *argv[])
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
   const char *repos_path;
-  apr_pool_t *pool;
   svn_boolean_t prop = FALSE, data = FALSE;
   svn_boolean_t quiet = FALSE;
-  svn_error_t *err;
   apr_getopt_t *os;
   const apr_getopt_option_t options[] =
     {
@@ -445,25 +447,12 @@ main(int argc, const char *argv[])
       {0,             0,  0,  0}
     };
 
-  /* Initialize the app. */
-  if (svn_cmdline_init("svn-rep-sharing-stats", 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));
-
   /* Check library versions */
-  err = check_lib_versions();
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn-rep-sharing-stats: ");
+  SVN_ERR(check_lib_versions());
 
-  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
-  if (err)
-    return svn_cmdline_handle_exit_error(err, pool, "svn-rep-sharing-stats: ");
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
-  SVN_INT_ERR(check_experimental());
+  SVN_ERR(check_experimental());
 
   os->interleave = 1;
   while (1)
@@ -476,7 +465,8 @@ main(int argc, const char *argv[])
       if (status != APR_SUCCESS)
         {
           usage(pool);
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
       switch (opt)
         {
@@ -496,14 +486,14 @@ main(int argc, const char *argv[])
           break;
         case 'h':
           help(options, pool);
-          break;
+          return SVN_NO_ERROR;
         case OPT_VERSION:
-          SVN_INT_ERR(version(pool));
-          exit(0);
-          break;
+          SVN_ERR(version(pool));
+          return SVN_NO_ERROR;
         default:
           usage(pool);
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -513,23 +503,51 @@ main(int argc, const char *argv[])
   if (os->ind + 1 != argc || (!data && !prop))
     {
       usage(pool);
-      return EXIT_FAILURE;
+      *exit_code = EXIT_FAILURE;
+      return SVN_NO_ERROR;
     }
 
   /* Grab REPOS_PATH from argv. */
-  SVN_INT_ERR(svn_utf_cstring_to_utf8(&repos_path, os->argv[os->ind], pool));
+  SVN_ERR(svn_utf_cstring_to_utf8(&repos_path, os->argv[os->ind], pool));
   repos_path = svn_dirent_internal_style(repos_path, pool);
 
   set_up_cancellation();
 
   /* Do something. */
-  SVN_INT_ERR(process(repos_path, prop, data, quiet, pool));
+  SVN_ERR(process(repos_path, prop, data, quiet, pool));
 
   /* We're done. */
+  return SVN_NO_ERROR;
+}
 
-  svn_pool_destroy(pool);
-  /* Flush stdout to make sure that the user will see any printing errors. */
-  SVN_INT_ERR(svn_cmdline_fflush(stdout));
+int
+main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
+
+  /* Initialize the app. */
+  if (svn_cmdline_init("svn-rep-sharing-stats", 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));
+
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
 
-  return EXIT_SUCCESS;
+  if (err)
+    {
+      exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svn-rep-sharing-stats: ");
+    }
+
+  svn_pool_destroy(pool);
+  return exit_code;
 }

Modified: subversion/trunk/tools/server-side/svnauthz.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/server-side/svnauthz.c?rev=1544194&r1=1544193&r2=1544194&view=diff
==============================================================================
--- subversion/trunk/tools/server-side/svnauthz.c (original)
+++ subversion/trunk/tools/server-side/svnauthz.c Thu Nov 21 14:30:05 2013
@@ -382,42 +382,6 @@ subcommand_accessof(apr_getopt_t *os, vo
 #undef EXIT_FAILURE
 #define EXIT_FAILURE 2
 
-/* Similar to svn_cmdline_handle_exit_error but with an exit_code argument
-   so we can comply with our contract and exit with 2 for internal failures.
-   Also is missing the pool argument since we don't need it given
-   main/sub_main. */
-static int
-handle_exit_error(svn_error_t *err, const char *prefix, int exit_code)
-{
-  /* Issue #3014:
-   * Don't print anything on broken pipes. The pipe was likely
-   * closed by the process at the other end. We expect that
-   * process to perform error reporting as necessary.
-   *
-   * ### This assumes that there is only one error in a chain for
-   * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */
-  if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
-    svn_handle_error2(err, stderr, FALSE, prefix);
-  svn_error_clear(err);
-  return exit_code;
-}
-
-/* Report and clear the error ERR, and return EXIT_FAILURE. */
-#define EXIT_ERROR(err, exit_code)                               \
-  handle_exit_error(err, "svnauthz: ", exit_code)
-
-/* 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 'svnauthz' 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, EXIT_FAILURE);            \
-  } while (0)
-
-
 /* Return TRUE if the UI of 'svnauthz-validate' (svn 1.7 and earlier)
    should be emulated, given argv[0]. */
 static svn_boolean_t
@@ -485,8 +449,13 @@ canonicalize_access_file(const char **ca
   return SVN_NO_ERROR;
 }
 
-static int
-sub_main(int argc, const char *argv[], apr_pool_t *pool)
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
 
@@ -497,7 +466,7 @@ sub_main(int argc, const char *argv[], a
   int i;
 
   /* Initialize the FS library. */
-  SVN_INT_ERR(svn_fs_initialize(pool));
+  SVN_ERR(svn_fs_initialize(pool));
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
@@ -506,7 +475,7 @@ sub_main(int argc, const char *argv[], a
   opt_state.txn = opt_state.repos_path = opt_state.groups_file = NULL;
 
   /* Parse options. */
-  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
   os->interleave = 1;
 
   if (!use_compat_mode(argv[0], pool))
@@ -521,8 +490,9 @@ sub_main(int argc, const char *argv[], a
             break;
           if (status != APR_SUCCESS)
             {
-              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(subcommand_help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
 
           /* Stash the option code in an array before parsing it. */
@@ -535,7 +505,7 @@ sub_main(int argc, const char *argv[], a
               opt_state.help = TRUE;
               break;
             case 't':
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.txn, arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.txn, arg, pool));
               break;
             case 'R':
               opt_state.recursive = TRUE;
@@ -544,28 +514,29 @@ sub_main(int argc, const char *argv[], a
               opt_state.version = TRUE;
               break;
             case svnauthz__username:
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.username, arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.username, arg, pool));
               break;
             case svnauthz__path:
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.fspath, arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.fspath, arg, pool));
               opt_state.fspath = svn_fspath__canonicalize(opt_state.fspath,
                                                           pool);
               break;
             case svnauthz__repos:
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_name, arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_name, arg, pool));
               break;
             case svnauthz__is:
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.is, arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.is, arg, pool));
               break;
             case svnauthz__groups_file:
-              SVN_INT_ERR(
+              SVN_ERR(
                   svn_utf_cstring_to_utf8(&opt_state.groups_file,
                                           arg, pool));
               break;
             default:
                 {
-                  SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-                  return EXIT_FAILURE;
+                  SVN_ERR(subcommand_help(NULL, NULL, pool));
+                  *exit_code = EXIT_FAILURE;
+                  return SVN_NO_ERROR;
                 }
             }
         }
@@ -603,8 +574,9 @@ sub_main(int argc, const char *argv[], a
             {
               svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                         ("subcommand argument required\n")));
-              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(subcommand_help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
       else
@@ -616,14 +588,15 @@ sub_main(int argc, const char *argv[], a
               const char *first_arg_utf8;
 
               os->ind++;
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
                                                   first_arg, pool));
               svn_error_clear(
                 svn_cmdline_fprintf(stderr, pool,
                                     ("Unknown subcommand: '%s'\n"),
                                     first_arg_utf8));
-              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(subcommand_help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
     }
@@ -637,13 +610,12 @@ sub_main(int argc, const char *argv[], a
         {
           if (os->ind +2 != argc)
             {
-              err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                     ("Repository and authz file arguments "
-                                      "required"));
-              return EXIT_ERROR(err, EXIT_FAILURE);
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                      ("Repository and authz file arguments "
+                                       "required"));
             }
 
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_path, os->argv[os->ind],
+          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_path, os->argv[os->ind],
                                               pool));
           os->ind++;
 
@@ -653,24 +625,23 @@ sub_main(int argc, const char *argv[], a
       /* Exactly 1 non-option argument */
       if (os->ind + 1 != argc)
         {
-          err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 ("Authz file argument required"));
-          return EXIT_ERROR(err, EXIT_FAILURE);
+          return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  ("Authz file argument required"));
         }
 
       /* Grab AUTHZ_FILE from argv. */
-      SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.authz_file, os->argv[os->ind],
+      SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.authz_file, os->argv[os->ind],
                                           pool));
 
       /* Canonicalize opt_state.authz_file appropriately. */
-      SVN_INT_ERR(canonicalize_access_file(&opt_state.authz_file,
+      SVN_ERR(canonicalize_access_file(&opt_state.authz_file,
                                            opt_state.authz_file,
                                            opt_state.txn != NULL, pool));
 
       /* Same for opt_state.groups_file if it is present. */
       if (opt_state.groups_file)
         {
-          SVN_INT_ERR(canonicalize_access_file(&opt_state.groups_file,
+          SVN_ERR(canonicalize_access_file(&opt_state.groups_file,
                                                opt_state.groups_file,
                                                opt_state.txn != NULL, pool));
         }
@@ -696,13 +667,14 @@ sub_main(int argc, const char *argv[], a
                                           pool);
           svn_opt_format_option(&optstr, badopt, FALSE, pool);
           if (subcommand->name[0] == '-')
-            SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
+            SVN_ERR(subcommand_help(NULL, NULL, pool));
           else
             svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                             ("Subcommand '%s' doesn't accept option '%s'\n"
                              "Type 'svnauthz help %s' for usage.\n"),
                             subcommand->name, optstr, subcommand->name));
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -724,7 +696,8 @@ sub_main(int argc, const char *argv[], a
         {
           /* Follow our contract that says we exit with 1 if the file does not
              validate. */
-          return EXIT_ERROR(err, 1);
+          *exit_code = 1;
+          return err;
         }
       else if (err->apr_err == SVN_ERR_AUTHZ_UNREADABLE
                || err->apr_err == SVN_ERR_AUTHZ_UNWRITABLE
@@ -732,31 +705,22 @@ sub_main(int argc, const char *argv[], a
         {
           /* Follow our contract that says we exit with 3 if --is does not
            * match. */
-          return EXIT_ERROR(err, 3);
+          *exit_code = 3;
+          return err;
         }
 
-
-      return EXIT_ERROR(err, EXIT_FAILURE);
-    }
-  else
-    {
-      /* Ensure that everything is written to stdout, so the user will
-         see any print errors. */
-      err = svn_cmdline_fflush(stdout);
-      if (err)
-        {
-          return EXIT_ERROR(err, EXIT_FAILURE);
-        }
-      return EXIT_SUCCESS;
+      return err;
     }
 
+  return SVN_NO_ERROR;
 }
 
 int
 main(int argc, const char *argv[])
 {
   apr_pool_t *pool;
-  int exit_code;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
 
   /* Initialize the app.  Send all error messages to 'stderr'.  */
   if (svn_cmdline_init(argv[0], stderr) != EXIT_SUCCESS)
@@ -764,7 +728,18 @@ main(int argc, const char *argv[])
 
   pool = svn_pool_create(NULL);
 
-  exit_code = sub_main(argc, argv, pool);
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
+
+  if (err)
+    {
+      if (exit_code == 0)
+        exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svnauthz: ");
+    }
 
   svn_pool_destroy(pool);
   return exit_code;