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

Re: [PATCH] 'svnlook diff' uses item name as temp file name (second patch version)

From: Peter Lundblad <peter_at_famlundblad.se>
Date: 2006-02-28 21:06:06 CET

Edmund Horner writes:
> Ok, here's a new patch...

Committed in r18650.

Thanks for the patch,
//Peter

> I have removed create_unique_tmpdir but kept
> the tmpdir argument to print_diff_tree; it seems more efficient to call
> svn_io_temp_dir just once. The difference is that tmpdir is now simply
> the official temp dir instead of a special unique svnlook temp dir.
>
> The comments in print_diff_tree have been trimmed down a bit more. The
> code continues to create the "second" temp file first (which it did in
> case of name conflicts), which isn't necessary now.
>
> I've tested it on the first 10000 svn revisions (yeah, my machine is
> slow) and it produces identical diffs in all cases that the original can
> handle and diffs for those cases the original can't (1398, 1399, 1795,
> 1805). It also passes svnlook-tests.
>
> Edmund.
>
>
>
> [[[
> Use simple and safe temporary file names for svnlook diff, rather than
> building out the tree as it exists in the repository -- this avoids
> problems with paths that can't be used in the temporary directory.
>
> Patch by: Edmund Horner <ejrh00@gmail.com>
> Suggested by: Max Bowsher <maxb@ukf.net>
> Review by: Peter N. Lundblad <peter@famlundblad.se>
>
> * subversion/svnlook/main.c
> (prepare_tmpfiles): Create a normal unique file in the temporary
> directory.
> (print_diff_tree): Update comments to omit mention of the built-out
> temporary directories, which don't get created any more.
> (create_unique_tmpdir): Remove function.
> (do_diff): Use the system temporary directory instead of creating
> a special svnlook one; unlike the old one, this temporary directory
> doesn't need to be removed after use, so don't try to delete it.
> ]]]
> Index: main.c
> ===================================================================
> --- main.c (revision 18619)
> +++ main.c (working copy)
> @@ -692,10 +692,9 @@
> }
>
> /* Now, prepare the two temporary files, each of which will either
> - be empty, or will have real contents. The first file we will
> - make in our temporary directory. */
> - *tmpfile2 = svn_path_join(tmpdir, path2, pool);
> - SVN_ERR(open_writable_binary_file(&fh, *tmpfile2, pool));
> + be empty, or will have real contents. */
> + SVN_ERR(svn_io_open_unique_file2(&fh, tmpfile2, apr_psprintf(pool, "%s/diff", tmpdir),
> + ".tmp", svn_io_file_del_none, pool));
> if (root2)
> SVN_ERR(dump_contents(fh, root2, path2, pool));
> apr_file_close(fh);
> @@ -897,24 +896,15 @@
> diff.
>
> - Second, dump the contents of the new version of the file
> - into the svnlook temporary directory, building out the
> - actual directories that need to be created in order to
> - fully represent the filesystem path inside the tmp
> - directory.
> + into the temporary directory.
>
> - Then, dump the contents of the old version of the file into
> - the svnlook temporary directory, also building out intermediate
> - directories as needed, using a unique temporary file name (we
> - do this *after* putting the new version of the file
> - there in case something actually versioned has a name
> - that looks like one of our unique identifiers).
> + the temporary directory.
>
> - Next, we run 'diff', passing the repository paths as the
> labels.
>
> - - Finally, we delete the temporary files (but leave the
> - built-out directories in place until after all diff
> - handling has been finished). */
> + - Finally, we delete the temporary files. */
> if (node->action == 'R' && node->text_mod)
> {
> do_diff = TRUE;
> @@ -1347,48 +1337,7 @@
> return SVN_NO_ERROR;
> }
>
> -/* Create a new temporary directory with an 'svnlook' prefix. */
> -static svn_error_t *
> -create_unique_tmpdir(const char **name, apr_pool_t *pool)
> -{
> - const char *unique_name;
> - const char *sys_tmp_dir;
> - const char *base;
> - unsigned int i;
>
> - SVN_ERR(svn_io_temp_dir(&sys_tmp_dir, pool));
> - base = svn_path_join(sys_tmp_dir, "svnlook", pool);
> -
> - for (i = 1; i <= 99999; i++)
> - {
> - svn_error_t *err;
> -
> - unique_name = apr_psprintf(pool, "%s.%u", base, i);
> - /* The directory has a predictable name so it is made writeable for
> - the owner only (without relying on the umask) to inhibit symlink
> - attacks on the filenames; the filenames are also, to a certain
> - extent, predictable. */
> - err = svn_io_dir_make(unique_name,
> - APR_UREAD | APR_UWRITE | APR_UEXECUTE,
> - pool);
> -
> - if (!err)
> - {
> - *name = unique_name;
> - return SVN_NO_ERROR;
> - }
> -
> - if (! APR_STATUS_IS_EEXIST(err->apr_err))
> - return err;
> -
> - svn_error_clear(err);
> - }
> -
> - *name = NULL;
> - return svn_error_createf(SVN_ERR_IO_UNIQUE_NAMES_EXHAUSTED,
> - NULL, _("Can't create temporary directory"));
> -}
> -
> /* Print some diff-y stuff in a TBD way. :-) */
> static svn_error_t *
> do_diff(svnlook_ctxt_t *c, apr_pool_t *pool)
> @@ -1414,18 +1363,12 @@
> if (tree)
> {
> const char *tmpdir;
> - svn_error_t *err;
>
> SVN_ERR(svn_fs_revision_root(&base_root, c->fs, base_rev_id, pool));
> - SVN_ERR(create_unique_tmpdir(&tmpdir, pool));
> - err = print_diff_tree(root, base_root, tree, "", "",
> - c, tmpdir, pool);
> - if (err)
> - {
> - svn_error_clear(svn_io_remove_dir(tmpdir, pool));
> - return err;
> - }
> - SVN_ERR(svn_io_remove_dir(tmpdir, pool));
> + SVN_ERR(svn_io_temp_dir(&tmpdir, pool));
> +
> + SVN_ERR(print_diff_tree(root, base_root, tree, "", "",
> + c, tmpdir, 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 Tue Feb 28 21:06:49 2006

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.