[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Issue 952: Pass the new value as stdin to the pre-revprop-change hook script.

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2004-03-19 04:49:36 CET

We have been creating hook script templates that say the new revprop value is available on standard input, but this has never been true as far as I can tell. It was not just broken, but completely unimplemented.

In issue 952, kfogel says:

"svn_io_run_cmd() currently takes 'apr_file_t *infile'. We need it to
take an svn_stream_t instead for the input, and be able to send that
data to the child process asynchronously" ...

But wouldn't be easier to spool the property value into a temporary file and pass that temporary file to the existing svn_io_run_cmd()?

The attached patch does that. It works and passes the regression tests. Does it look OK?

- Julian

Issue 952: Pass the new value as stdin to the pre-revprop-change hook script.

* subversion/libsvn_repos/hooks.c
  (run_hook_cmd): Accept a file handle to be used for stdin.
  (create_temp_file): New function.
  (svn_repos__hooks_pre_revprop_change): Write the new value to a temporary
    file and pass that as stdin for the hook.
  (svn_repos__hooks_start_commit, svn_repos__hooks_pre_commit,
   svn_repos__hooks_post_commit, svn_repos__hooks_post_revprop_change): Pass
    NULL as a stdin file for the hook.

Index: subversion/libsvn_repos/hooks.c
===================================================================
--- subversion/libsvn_repos/hooks.c (revision 9122)
+++ subversion/libsvn_repos/hooks.c (working copy)
@@ -48,6 +48,7 @@ run_hook_cmd (const char *name,
               const char *cmd,
               const char **args,
               svn_boolean_t check_exitcode,
+ apr_file_t *stdin_handle,
               apr_pool_t *pool)
 {
   apr_file_t *read_errhandle, *write_errhandle, *null_handle;
@@ -70,7 +71,7 @@ run_hook_cmd (const char *name,
       (apr_err, "Can't create null stdout for hook '%s'", cmd);
 
   err = svn_io_run_cmd (".", cmd, args, &exitcode, &exitwhy, FALSE,
- NULL, null_handle, write_errhandle, pool);
+ 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
@@ -120,6 +121,26 @@ run_hook_cmd (const char *name,
   return err;
 }
 
+
+/* Create a temporary file F that will automatically be deleted when it is
+ closed. Fill it with VALUE, and leave it open and rewound, ready to be
+ read from. */
+static svn_error_t *
+create_temp_file (apr_file_t **f, const svn_string_t *value, apr_pool_t *pool)
+{
+ const char *dir, *fname;
+ apr_off_t offset = 0;
+
+ SVN_ERR (svn_io_temp_dir (&dir, pool));
+ SVN_ERR (svn_io_open_unique_file (f, &fname,
+ svn_path_join (dir, "hook-input", pool),
+ "", TRUE /* delete on close */, pool));
+ SVN_ERR (svn_io_file_write_full (*f, value->data, value->len, NULL, pool));
+ SVN_ERR (svn_io_file_seek (*f, APR_SET, &offset, pool));
+ return SVN_NO_ERROR;
+}
+
+
 /* Check if the HOOK program exists and is a file, using POOL for
    temporary allocations. Returns the hook program if found,
    otherwise NULL. */
@@ -154,6 +175,7 @@ check_hook_cmd (const char *hook, apr_po
   return NULL;
 }
 
+
 svn_error_t *
 svn_repos__hooks_start_commit (svn_repos_t *repos,
                                const char *user,
@@ -170,7 +192,7 @@ svn_repos__hooks_start_commit (svn_repos
       args[2] = user ? user : "";
       args[3] = NULL;
 
- SVN_ERR (run_hook_cmd ("start-commit", hook, args, TRUE, pool));
+ SVN_ERR (run_hook_cmd ("start-commit", hook, args, TRUE, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -193,7 +215,7 @@ svn_repos__hooks_pre_commit (svn_repos_t
       args[2] = txn_name;
       args[3] = NULL;
 
- SVN_ERR (run_hook_cmd ("pre-commit", hook, args, TRUE, pool));
+ SVN_ERR (run_hook_cmd ("pre-commit", hook, args, TRUE, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -216,7 +238,7 @@ svn_repos__hooks_post_commit (svn_repos_
       args[2] = apr_psprintf (pool, "%" SVN_REVNUM_T_FMT, rev);
       args[3] = NULL;
 
- SVN_ERR (run_hook_cmd ("post-commit", hook, args, FALSE, pool));
+ SVN_ERR (run_hook_cmd ("post-commit", hook, args, FALSE, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -236,8 +258,10 @@ svn_repos__hooks_pre_revprop_change (svn
   if ((hook = check_hook_cmd (hook, pool)))
     {
       const char *args[6];
+ apr_file_t *stdin_handle;
 
- /* ### somehow pass the new value as stdin to hook? */
+ /* Pass the new value as stdin to hook */
+ SVN_ERR (create_temp_file (&stdin_handle, value, pool));
 
       args[0] = hook;
       args[1] = svn_repos_path (repos, pool);
@@ -246,7 +270,10 @@ svn_repos__hooks_pre_revprop_change (svn
       args[4] = name;
       args[5] = NULL;
 
- SVN_ERR (run_hook_cmd ("pre-revprop-change", hook, args, TRUE, pool));
+ SVN_ERR (run_hook_cmd ("pre-revprop-change", hook, args, TRUE,
+ stdin_handle, pool));
+
+ SVN_ERR (svn_io_file_close (stdin_handle, pool));
     }
   else
     {
@@ -288,7 +315,8 @@ svn_repos__hooks_post_revprop_change (sv
       args[4] = name;
       args[5] = NULL;
 
- SVN_ERR (run_hook_cmd ("post-revprop-change", hook, args, FALSE, pool));
+ SVN_ERR (run_hook_cmd ("post-revprop-change", hook, args, FALSE,
+ NULL, pool));
     }
 
   return SVN_NO_ERROR;

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Mar 19 04:47:38 2004

This is an archived mail posted to the Subversion Dev mailing list.