<commit_before>/* hooks.c : running repository hooks and sentinels
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <apr_pools.h>
#include <apr_file_io.h>

#include "svn_error.h"
#include "svn_path.h"
#include "svn_repos.h"
#include "repos.h"
#include "svn_private_config.h"

/* In the code below, "hook" is sometimes used indiscriminately to
   mean either hook or sentinel.  */




/*** Hook drivers. ***/

/* NAME, CMD and ARGS are the name, path to and arguments for the hook
   program that is to be run.  If READ_ERRSTREAM is TRUE then the hook's
   exit status will be checked, and if an error occurred the hook's stderr
   output will be added to the returned error.

   If READ_ERRSTREAM is FALSE the hook's stderr output will be discarded.

   If STDIN_HANDLE is non-null, pass it as the hook's stdin, else pass
   no stdin to the hook. */
static svn_error_t *
run_hook_cmd (const char *name,
              const char *cmd,
              const char **args,
              svn_boolean_t read_errstream,
              apr_file_t *stdin_handle,
              apr_pool_t *pool)
{
  apr_file_t *read_errhandle, *write_errhandle, *null_handle;
  apr_status_t apr_err;
  svn_error_t *err;
  int exitcode;
  apr_exit_why_e exitwhy;
  apr_proc_t cmd_proc;

  /* Create a pipe to access stderr of the child. */
  apr_err = apr_file_pipe_create(&read_errhandle, &write_errhandle, pool);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Can't create pipe for hook '%s'"), cmd);

  /* Redirect stdout to the null device */
  apr_err = apr_file_open (&null_handle, SVN_NULL_DEVICE_NAME, APR_WRITE,
                           APR_OS_DEFAULT, pool);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Can't create null stdout for hook '%s'"), cmd);

  err = svn_io_start_cmd (&cmd_proc, ".", cmd, args, FALSE,
                          stdin_handle, null_handle, write_errhandle, pool);

  /* This seems to be done automatically if we pass the third parameter of
     apr_procattr_child_in/out_set(), but svn_io_run_cmd()'s interface does
     not support those parameters. We need to close the write end of the
     pipe so we don't hang on the read end later, if we need to read it. */
  apr_err = apr_file_close (write_errhandle);
  if (!err && apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Error closing write end of stderr pipe"));

  if (err)
    {
      err = svn_error_createf
        (SVN_ERR_REPOS_HOOK_FAILURE, err, _("Failed to start '%s' hook"), cmd);
    }
  else
    {
      svn_stringbuf_t *error;
      svn_error_t *err2;

      err2 = svn_stringbuf_from_aprfile (&error, read_errhandle, pool);

      err = svn_io_wait_for_cmd(&cmd_proc, cmd, &exitcode, &exitwhy, pool);
      if (! err)
        {
          if (! APR_PROC_CHECK_EXIT (exitwhy) || exitcode != 0)
            {
              if (read_errstream && ! err2)
                {
                  err = svn_error_createf
                    (SVN_ERR_REPOS_HOOK_FAILURE, err,
                     _("'%s' hook failed with error output:\n%s"),
                     name, error->data);
                }
              else
                {
                  err = svn_error_createf
                    (SVN_ERR_REPOS_HOOK_FAILURE, err,
                     _("'%s' hook failed; no error output available"), name);
                }
            }
        }
      if (err2)
        {
          if (err)
            svn_error_clear (err2);
          else
            err = err2;
        }
    }

  /* Hooks are fallible, and so hook failure is "expected" to occur at
     times.  When such a failure happens we still want to close the pipe
     and null file */
  apr_err = apr_file_close (read_errhandle);
  if (!err && apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Error closing read end of stderr pipe"));

  apr_err = apr_file_close (null_handle);<commit_msg>Translate error output from hook scripts from the native encoding to UTF8.<commit_after>/* hooks.c : running repository hooks and sentinels
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <apr_pools.h>
#include <apr_file_io.h>

#include "svn_error.h"
#include "svn_path.h"
#include "svn_repos.h"
#include "svn_utf.h"
#include "repos.h"
#include "svn_private_config.h"

/* In the code below, "hook" is sometimes used indiscriminately to
   mean either hook or sentinel.  */




/*** Hook drivers. ***/

/* NAME, CMD and ARGS are the name, path to and arguments for the hook
   program that is to be run.  If READ_ERRSTREAM is TRUE then the hook's
   exit status will be checked, and if an error occurred the hook's stderr
   output will be added to the returned error.

   If READ_ERRSTREAM is FALSE the hook's stderr output will be discarded.

   If STDIN_HANDLE is non-null, pass it as the hook's stdin, else pass
   no stdin to the hook. */
static svn_error_t *
run_hook_cmd (const char *name,
              const char *cmd,
              const char **args,
              svn_boolean_t read_errstream,
              apr_file_t *stdin_handle,
              apr_pool_t *pool)
{
  apr_file_t *read_errhandle, *write_errhandle, *null_handle;
  apr_status_t apr_err;
  svn_error_t *err;
  int exitcode;
  apr_exit_why_e exitwhy;
  apr_proc_t cmd_proc;

  /* Create a pipe to access stderr of the child. */
  apr_err = apr_file_pipe_create(&read_errhandle, &write_errhandle, pool);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Can't create pipe for hook '%s'"), cmd);

  /* Redirect stdout to the null device */
  apr_err = apr_file_open (&null_handle, SVN_NULL_DEVICE_NAME, APR_WRITE,
                           APR_OS_DEFAULT, pool);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Can't create null stdout for hook '%s'"), cmd);

  err = svn_io_start_cmd (&cmd_proc, ".", cmd, args, FALSE,
                          stdin_handle, null_handle, write_errhandle, pool);

  /* This seems to be done automatically if we pass the third parameter of
     apr_procattr_child_in/out_set(), but svn_io_run_cmd()'s interface does
     not support those parameters. We need to close the write end of the
     pipe so we don't hang on the read end later, if we need to read it. */
  apr_err = apr_file_close (write_errhandle);
  if (!err && apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Error closing write end of stderr pipe"));

  if (err)
    {
      err = svn_error_createf
        (SVN_ERR_REPOS_HOOK_FAILURE, err, _("Failed to start '%s' hook"), cmd);
    }
  else
    {
      svn_stringbuf_t *native_error;
      const char *error;
      svn_error_t *err2;

      err2 = svn_stringbuf_from_aprfile (&native_error, read_errhandle, pool);

      err = svn_io_wait_for_cmd(&cmd_proc, cmd, &exitcode, &exitwhy, pool);
      if (! err)
        {
          if (! APR_PROC_CHECK_EXIT (exitwhy) || exitcode != 0)
            {
              if (read_errstream && ! err2)
                {
                  err2 = svn_utf_cstring_to_utf8 (&error, native_error->data,
                                                  pool);
                  if (! err2)
                    err = svn_error_createf
                      (SVN_ERR_REPOS_HOOK_FAILURE, err,
                       _("'%s' hook failed with error output:\n%s"),
                       name, error);
                }
              else
                {
                  err = svn_error_createf
                    (SVN_ERR_REPOS_HOOK_FAILURE, err,
                     _("'%s' hook failed; no error output available"), name);
                }
            }
        }
      if (err2)
        {
          if (err)
            svn_error_clear (err2);
          else
            err = err2;
        }
    }

  /* Hooks are fallible, and so hook failure is "expected" to occur at
     times.  When such a failure happens we still want to close the pipe
     and null file */
  apr_err = apr_file_close (read_errhandle);
  if (!err && apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Error closing read end of stderr pipe"));

  apr_err = apr_file_close (null_handle);
{'fraction_non_alphanumeric': 0.11398367176051916, 'fraction_numerical': 0.0037680552648105504, 'mean_word_length': 2.4974377745241583, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1056230', 'n_tokens_mistral': 3053, 'n_tokens_neox': 2975, 'n_words': 964}