Philip Martin <philip.mar...@wandisco.com> writes: > Ben Reser <b...@reser.org> writes: > >> I don't imagine it'd take very long at all to implement but the >> problem of course is that we really should think carefully how we go >> about doing this. If we can detect this at runtime we probably >> should. > > I don't see how Subversion can determine that one script needs a > terminal while another can use a file, only the user knows that. > > It's also hard to fix 1.8, how do we pass the information into the > client library without changing the API? Perhaps we could recognise a > special part of the command name or a special external parameter, so > > --diff-cmd svn:interactive:myscript > > or > > --diff-cmd myscript -x svn:interactive > > gets a terminal while > > --diff-cmd myscript > > gets a file.
Or we could extend the opaque svn_stream_t to make the underlying apr_file_t available. Is mixing output to the file and output to the stream acceptable or does it introduce output order problems? Index: subversion/include/private/svn_io_private.h =================================================================== --- subversion/include/private/svn_io_private.h (revision 1494268) +++ subversion/include/private/svn_io_private.h (working copy) @@ -90,7 +90,10 @@ svn_stream__set_is_buffered(svn_stream_t *stream, svn_boolean_t svn_stream__is_buffered(svn_stream_t *stream); +apr_file_t * +svn_stream__aprfile(svn_stream_t *stream); + #ifdef __cplusplus } #endif /* __cplusplus */ Index: subversion/libsvn_client/diff.c =================================================================== --- subversion/libsvn_client/diff.c (revision 1494268) +++ subversion/libsvn_client/diff.c (working copy) @@ -51,6 +51,7 @@ #include "private/svn_wc_private.h" #include "private/svn_diff_private.h" #include "private/svn_subr_private.h" +#include "private/svn_io_private.h" #include "svn_private_config.h" @@ -809,13 +810,22 @@ diff_content_changed(svn_boolean_t *wrote_header, /* We deal in streams, but svn_io_run_diff2() deals in file handles, unfortunately, so we need to make these temporary files, and then copy the contents to our stream. */ - SVN_ERR(svn_io_open_unique_file3(&outfile, &outfilename, NULL, - svn_io_file_del_on_pool_cleanup, - scratch_pool, scratch_pool)); - SVN_ERR(svn_io_open_unique_file3(&errfile, &errfilename, NULL, - svn_io_file_del_on_pool_cleanup, - scratch_pool, scratch_pool)); + outfile = svn_stream__aprfile(outstream); + if (!outfile) + SVN_ERR(svn_io_open_unique_file3(&outfile, &outfilename, NULL, + svn_io_file_del_on_pool_cleanup, + scratch_pool, scratch_pool)); + else + outfilename = NULL; + errfile = svn_stream__aprfile(errstream); + if (!errfile) + SVN_ERR(svn_io_open_unique_file3(&errfile, &errfilename, NULL, + svn_io_file_del_on_pool_cleanup, + scratch_pool, scratch_pool)); + else + errfilename = NULL; + SVN_ERR(svn_io_run_diff2(".", diff_cmd_baton->options.for_external.argv, diff_cmd_baton->options.for_external.argc, @@ -824,20 +834,28 @@ diff_content_changed(svn_boolean_t *wrote_header, &exitcode, outfile, errfile, diff_cmd_baton->diff_cmd, scratch_pool)); - SVN_ERR(svn_io_file_close(outfile, scratch_pool)); - SVN_ERR(svn_io_file_close(errfile, scratch_pool)); + if (outfilename) + SVN_ERR(svn_io_file_close(outfile, scratch_pool)); + if (errfilename) + SVN_ERR(svn_io_file_close(errfile, scratch_pool)); /* Now, open and copy our files to our output streams. */ - SVN_ERR(svn_stream_open_readonly(&stream, outfilename, - scratch_pool, scratch_pool)); - SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(outstream, - scratch_pool), + if (outfilename) + { + SVN_ERR(svn_stream_open_readonly(&stream, outfilename, + scratch_pool, scratch_pool)); + SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(outstream, + scratch_pool), + NULL, NULL, scratch_pool)); + } + if (errfilename) + { + SVN_ERR(svn_stream_open_readonly(&stream, errfilename, + scratch_pool, scratch_pool)); + SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(errstream, + scratch_pool), NULL, NULL, scratch_pool)); - SVN_ERR(svn_stream_open_readonly(&stream, errfilename, - scratch_pool, scratch_pool)); - SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(errstream, - scratch_pool), - NULL, NULL, scratch_pool)); + } /* We have a printed a diff for this path, mark it as visited. */ *wrote_header = TRUE; Index: subversion/libsvn_subr/stream.c =================================================================== --- subversion/libsvn_subr/stream.c (revision 1494268) +++ subversion/libsvn_subr/stream.c (working copy) @@ -56,6 +56,7 @@ struct svn_stream_t { svn_stream_mark_fn_t mark_fn; svn_stream_seek_fn_t seek_fn; svn_stream__is_buffered_fn_t is_buffered_fn; + apr_file_t *file; /* Maybe NULL */ }; @@ -81,6 +82,7 @@ svn_stream_create(void *baton, apr_pool_t *pool) stream->mark_fn = NULL; stream->seek_fn = NULL; stream->is_buffered_fn = NULL; + stream->file = NULL; return stream; } @@ -913,6 +915,7 @@ svn_stream_from_aprfile2(apr_file_t *file, svn_stream_set_mark(stream, mark_handler_apr); svn_stream_set_seek(stream, seek_handler_apr); svn_stream__set_is_buffered(stream, is_buffered_handler_apr); + stream->file = file; if (! disown) svn_stream_set_close(stream, close_handler_apr); @@ -920,6 +923,12 @@ svn_stream_from_aprfile2(apr_file_t *file, return stream; } +apr_file_t * +svn_stream__aprfile(svn_stream_t *stream) +{ + return stream->file; +} + /* Compressed stream support */ -- Philip Martin | Subversion Committer WANdisco | Non-Stop Data www.wandisco.com