On Thu, Nov 29, 2001 at 05:10:06PM -0600, Karl Fogel wrote:
> Kevin, thanks for taking this on! A couple of nits/questions:
>
> - No OS-specific code in Subversion itself -- use APR for that. So
> your new svn_io_set_permissions() needs to be changed. Note that
> it's okay for a patch to include changes to APR; we have a fair
> number of APR committers here, no worries.
>
> Now, you probably saw the `WIN32' stuff in config.c and io.c in
> the same directory and said to yourself "Hey, if it was okay
> there, it'll be okay in my new function.", which is
> understandable. :-) However, that old stuff is equally
> blasphemous, and will be removed ASAP (Greg Stein just noticed the
> io.c stuff, and plans to deal with it by not using file
> descriptors with Neon at all, which may require some tweaks to
> Neon, but that's fine).
>
> So it's still: no OS-sensitive code in Subversion. APR is our
> portability layer.
>
No problem. I did see the stuff there, and I thought it might be possible to
put it there while waiting for it to go into APR. I'll re-work the patch to
include a patch to APR as well.
>
> - I don't understand why we suddenly need to pay attention to umask
> for this change. The idea is to make the .svn area read-only,
> except for the tmp area, which doesn't need umask afaik. So if we
> weren't using umasks before now, why does this change require
> paying attention to them?
>
> This isn't actually a nit, it's a real question -- probably
> there's a good reason for the umask stuff, and I'm just not
> thinking of it...
Consider the way an update works if there are no local mods. It copies the
text-base file to the tmp area, applies the txdelta, and then moves it back to
text-base and copies it out to the working copy. Note that this means it
starts with the supposedly read-only text-base file. If we don't change the
permissions, then we run into problems moving stuff around. Also even if we
didn't we wind up with a read-only file in the working copy. However, if we
just set the permissions, without worrying about the umask, then what do we
set them to? We could set them -rw-------, but then people have to re-set
the permissions to allow group reading every time the do an update. We can't
set them -rw-r--r--, because they might contain information that a user doesn't
want to be shared. So overall our best strategy is to move or copy the file,
then set the permissions to look like we just created the file, which means
obeying the umask.
There are however, two things I don't like about this patch.
1) It resets a file to non-executable after an update, even if the user had
made it executable (e.g. autogen.sh). Not a big deal in the long run, since
sometime (hopefully soon), we will know that a file should have the execute
bit set, and set it.
2) There is a race condition in svn_io_set_permissions for multithreaded
apps, with regard to the umask. Just wondering if anyone had any ideas of
how to fix that for apr. I was thinking of making:
apr_status_t apr_umask_get(apr_fileperms_t *mask);
and
apr_status_t apr_umask_set(apr_fileperms_t *mask);
Then it would be possible to perform a umask(mask=umask(0777)) in
apr_initialize (before any threads are created) and store the umask somewhere.
Then apr_umask_get would just return the value, and apr_umask_set could set
both apr's copy and call umask to set the new value.
Sound okay???
>
> Best,
> -Karl
>
> Kevin Pilch-Bisson <kevin@pilch-bisson.net> writes:
> > Subject and log message say it all.
> >
> > Log:
> > Make the .svn area read-only, with the exception of things in tmp, which
> > will be writable. This will have no effect on platforms other unix, since
> > apr_file_open does not obey the permission flags, and apr_file_perms_set
> > is not implemented.
> >
> > This patch is safe to apply to an already existing working copy. It will
> > gradually make file read-only as they are updated or committed.
> >
> > * subversion/include/svn_io.h:(svn_io_rename_file): New prototype for a
> > wrapper around apr_file_rename;
> > (svn_io_set_permissions): New prototype for a function which is able to
> > set the permissions in a matter that obeys a user's umask.
> >
> > * subversion/libsvn_subr/io.c:(svn_io_append_file): Format for 80 column
> > lines.
> > (svn_io_rename_file): New function, a wrapper around apr_file_rename.
> > (svn_io_set_permissions): New function, on unix this is able to retreive
> > the user's umask and set the file as if it were newly created. On other
> > platforms this does nothing since apr_file_perms_set is not implemented
> > on any other platform.
> >
> > * subversion/libsvn_wc/wc.h:Doc chanes for SVN_LOG_ATTR_MV and
> > SVN_LOG_ATTR_CP.
> > (SVN_WC__LOG_ATTR_PERM): New define, use to indicate what permissions a
> > move, copy, or append action should set the dest file to.
> > (SVN_WC__LOG_PERM_SRC): New define, don't change permissions.
> > (SVN_WC__LOG_DEFAULT): New define, use os-default permissions.
> > (SVN_WC__LOG_EXEC): New define, make file executable(not currently used,
> > but might be useful for making checkouts/updates recognize executable
> > files.
> > (SVN_WC__LOG_READONLY): New define, make file read-only.
> >
> > * subversion/libsvn_wc/props.c:(svn_wc__do_property_merge): Pass
> > permissions to log entries.
> >
> > * subversion/libsvn_wc/adm_crawler.c:(restore_file): Make files writable
> > when copying them out to the working copy.
> >
> > * subversion/libsvn_wc/log.c:(svn_wc__perm_type): New enum.
> > (file_xfer_under_path) Takes new `perm' argument, sets dest file
> > permissions according to it.
> > (log_do_file_xfer) Determine perm argument for file_xfer_under_path from
> > the xml attributes.
> >
> > * subversion/libsvn_wc/adm_files.c:(maybe_copy_file): Set permissions when
> > copying the file to the tmp area.
> > (sync_adm_file): Set permissions on the file when moving it out of the
> > tmp area.
> > (close_adm_file): Set permissions on the file when moving it
> > out of the tmp area.
> > (svn_wc__close_auth_file): Make the file readable only by the user when
> > closing it.
> > (svn_wc__remove_adm_file): Make the file writable before removing it.
> >
> > * subversion/libsvn_wc/get_editor.c:(close_file): Pass permissions to be
> > used to log entries.
> >
> > Index: ./subversion/include/svn_io.h
> > ===================================================================
> > --- ./subversion/include/.svn/text-base/svn_io.h.svn-base Wed Nov 21 12:45:58 2001
> > +++ ./subversion/include/svn_io.h Tue Nov 27 13:47:16 2001
> > @@ -129,6 +129,19 @@
> > svn_stringbuf_t *dst,
> > apr_pool_t *pool);
> >
> > +/* Rename SRC to DST. DST will be overwritten if it exists. */
> > +svn_error_t *svn_io_rename_file (svn_stringbuf_t *src,
> > + svn_stringbuf_t *dst,
> > + apr_pool_t *pool);
> > +
> > +/* Change the permissions on PATH to PERMS. If APPLY_UMASK is true then
> > + * the permissions will be combined with the umask in the same way as
> > + * open, if the platform permits. Otherwise, the permissions will be set
> > + * to exactly PERMS. */
> > +svn_error_t *svn_io_set_permissions (svn_stringbuf_t *path,
> > + apr_fileperms_t perms,
> > + svn_boolean_t apply_umask,
> > + apr_pool_t *pool);
> >
> > /* Read a line from FILE into BUF, but not exceeding *LIMIT bytes.
> > * Does not include newline, instead '\0' is put there.
> > Index: ./subversion/libsvn_wc/props.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/props.c.svn-base Wed Nov 21 11:22:30 2001
> > +++ ./subversion/libsvn_wc/props.c Wed Nov 28 12:25:44 2001
> > @@ -620,6 +620,8 @@
> > tmp_prop_base,
> > SVN_WC__LOG_ATTR_DEST,
> > real_prop_base,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create (SVN_WC__LOG_PERM_SRC, pool),
> > NULL);
> >
> > /* Write log entry to move working tmp copy to real working area. */
> > @@ -631,6 +633,8 @@
> > tmp_props,
> > SVN_WC__LOG_ATTR_DEST,
> > real_props,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create (SVN_WC__LOG_PERM_SRC, pool),
> > NULL);
> >
> > if (reject_tmp_fp)
> > Index: ./subversion/libsvn_wc/wc.h
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/wc.h.svn-base Mon Nov 26 09:35:17 2001
> > +++ ./subversion/libsvn_wc/wc.h Wed Nov 28 12:26:52 2001
> > @@ -373,10 +373,12 @@
> > */
> > #define SVN_WC__LOG_RUN_CMD "run"
> >
> > -/* Move file SVN_WC__LOG_ATTR_NAME to SVN_WC__LOG_ATTR_DEST. */
> > +/* Move file SVN_WC__LOG_ATTR_NAME to SVN_WC__LOG_ATTR_DEST, with
> > + * permissions SVN_WC__LOG_ATTR_PERM. */
> > #define SVN_WC__LOG_MV "mv"
> >
> > -/* Copy file SVN_WC__LOG_ATTR_NAME to SVN_WC__LOG_ATTR_DEST. */
> > +/* Copy file SVN_WC__LOG_ATTR_NAME to SVN_WC__LOG_ATTR_DEST, with
> > + * permissions SVN_WC__LOG_ATTR_PERM. */
> > #define SVN_WC__LOG_CP "cp"
> >
> > /* Remove file SVN_WC__LOG_ATTR_NAME. */
> > @@ -415,6 +417,7 @@
> > #define SVN_WC__LOG_ATTR_NAME "name"
> > #define SVN_WC__LOG_ATTR_DEST "dest"
> > #define SVN_WC__LOG_ATTR_REVISION "revision"
> > +#define SVN_WC__LOG_ATTR_PERM "permission"
> > #define SVN_WC__LOG_ATTR_TEXT_REJFILE "text-rejfile"
> > #define SVN_WC__LOG_ATTR_PROP_REJFILE "prop-rejfile"
> > /* The rest are for SVN_WC__LOG_RUN_CMD. Extend as necessary. */
> > @@ -430,6 +433,15 @@
> > #define SVN_WC__LOG_ATTR_ARG_7 "arg7"
> > #define SVN_WC__LOG_ATTR_ARG_8 "arg8"
> > #define SVN_WC__LOG_ATTR_ARG_9 "arg9"
> > +
> > +/* Keep permissions the same as the source file. */
> > +#define SVN_WC__LOG_PERM_SRC "src"
> > +/* Make the permissions the operating system's default. */
> > +#define SVN_WC__LOG_PERM_DEFAULT "default"
> > +/* Make the permissions os/default, but with the execute bit set. */
> > +#define SVN_WC__LOG_PERM_EXEC "executable"
> > +/* Make the permissions read-only. */
> > +#define SVN_WC__LOG_PERM_READONLY "read-only"
> >
> >
> > /* Starting at PATH, write out log entries indicating that a commit
> > Index: ./subversion/libsvn_wc/adm_crawler.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/adm_crawler.c.svn-base Mon Nov 26 09:35:17 2001
> > +++ ./subversion/libsvn_wc/adm_crawler.c Tue Nov 27 14:09:04 2001
> > @@ -1795,12 +1795,9 @@
> > tmp_text_base_path = svn_wc__text_base_path (file_path, 1, pool);
> >
> > SVN_ERR (svn_io_copy_file (text_base_path, tmp_text_base_path, pool));
> > - status = apr_file_rename (tmp_text_base_path->data, file_path->data, pool);
> > - if (status)
> > - return svn_error_createf (status, 0, NULL, pool,
> > - "error renaming `%s' to `%s'",
> > - tmp_text_base_path->data,
> > - file_path->data);
> > + SVN_ERR (svn_io_set_permissions (tmp_text_base_path, APR_OS_DEFAULT,
> > + TRUE, pool));
> > + SVN_ERR (svn_io_rename_file (tmp_text_base_path, file_path, pool));
> >
> > return SVN_NO_ERROR;
> > }
> > Index: ./subversion/libsvn_wc/log.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/log.c.svn-base Wed Nov 21 08:50:24 2001
> > +++ ./subversion/libsvn_wc/log.c Tue Nov 27 14:21:19 2001
> > @@ -51,18 +51,27 @@
> > svn_wc__xfer_mv,
> > };
> >
> > +enum svn_wc__perm_type {
> > + svn_wc__perm_src,
> > + svn_wc__perm_default,
> > + svn_wc__perm_exec,
> > + svn_wc__perm_readonly
> > +};
> >
> >
> > -/* Copy (or rename, if RENAME is non-zero) NAME to DEST, assuming that
> > - PATH is the common parent of both locations. */
> > +/* Transfer contents of NAME to DEST, assuming that PATH is the common
> > + parent of both locations, according to ACTION. If ACTION requires that
> > + DEST be created, give it permissions appropriate to PERM. */
> > static svn_error_t *
> > file_xfer_under_path (svn_stringbuf_t *path,
> > const char *name,
> > const char *dest,
> > enum svn_wc__xfer_action action,
> > + enum svn_wc__perm_type perm,
> > apr_pool_t *pool)
> > {
> > apr_status_t status;
> > + apr_fileperms_t fperms;
> > svn_stringbuf_t *full_from_path, *full_dest_path;
> >
> > full_from_path = svn_stringbuf_dup (path, pool);
> > @@ -71,22 +80,39 @@
> > svn_path_add_component_nts (full_from_path, name, svn_path_local_style);
> > svn_path_add_component_nts (full_dest_path, dest, svn_path_local_style);
> >
> > + switch (perm)
> > + {
> > + case svn_wc__perm_default:
> > + fperms = APR_OS_DEFAULT;
> > + break;
> > + case svn_wc__perm_exec:
> > + fperms = APR_UREAD | APR_GREAD | APR_WREAD | APR_UWRITE
> > + | APR_GWRITE | APR_WWRITE | APR_UEXECUTE | APR_GEXECUTE
> > + | APR_WEXECUTE;
> > + break;
> > + case svn_wc__perm_src:
> > + /* Doesn't matter, since the permissions won't be applied anyway. */
> > + break;
> > + case svn_wc__perm_readonly:
> > + fperms = APR_UREAD | APR_GREAD | APR_WREAD;
> > + }
> > +
> > switch (action)
> > {
> > case svn_wc__xfer_append:
> > - return svn_io_append_file (full_from_path, full_dest_path, pool);
> > + SVN_ERR (svn_io_append_file (full_from_path, full_dest_path, pool));
> > + break;
> > case svn_wc__xfer_cp:
> > - return svn_io_copy_file (full_from_path, full_dest_path, pool);
> > + SVN_ERR (svn_io_copy_file (full_from_path, full_dest_path, pool));
> > + break;
> > case svn_wc__xfer_mv:
> > - status = apr_file_rename (full_from_path->data,
> > - full_dest_path->data, pool);
> > - if (status)
> > - return svn_error_createf (status, 0, NULL, pool,
> > - "file_xfer_under_path: "
> > - "can't move %s to %s",
> > - name, dest);
> > + SVN_ERR (svn_io_rename_file (full_from_path, full_dest_path, pool));
> > + break;
> > }
> >
> > + if (perm != svn_wc__perm_src)
> > + SVN_ERR (svn_io_set_permissions (full_dest_path, fperms, TRUE, pool));
> > +
> > return SVN_NO_ERROR;
> > }
> >
> > @@ -238,15 +264,34 @@
> > const XML_Char **atts)
> > {
> > svn_error_t *err;
> > + enum svn_wc__perm_type perm = svn_wc__perm_src;
> > const char *dest = svn_xml_get_attr_value (SVN_WC__LOG_ATTR_DEST, atts);
> > + const char *permstr = svn_xml_get_attr_value (SVN_WC__LOG_ATTR_PERM, atts);
> >
> > if (! dest)
> > return svn_error_createf (SVN_ERR_WC_BAD_ADM_LOG, 0, NULL, loggy->pool,
> > "missing dest attr in %s", loggy->path->data);
> >
> > - /* Else. */
> > + if (permstr)
> > + {
> > + if (strcmp (permstr, SVN_WC__LOG_PERM_SRC) == 0)
> > + perm = svn_wc__perm_src;
> > + else if (strcmp (permstr, SVN_WC__LOG_PERM_DEFAULT) == 0)
> > + perm = svn_wc__perm_default;
> > + else if (strcmp (permstr, SVN_WC__LOG_PERM_EXEC) == 0)
> > + perm = svn_wc__perm_exec;
> > + else if (strcmp (permstr, SVN_WC__LOG_PERM_READONLY) == 0)
> > + perm = svn_wc__perm_readonly;
> > + else
> > + return svn_error_createf (SVN_ERR_WC_BAD_ADM_LOG, 0, NULL,
> > + loggy->pool,
> > + "unrecognized perm attr in %s",
> > + loggy->path->data);
> > + }
> >
> > - err = file_xfer_under_path (loggy->path, name, dest, action, loggy->pool);
> > + /* Else. */
> > + err = file_xfer_under_path (loggy->path, name, dest, action,
> > + perm, loggy->pool);
> > if (err)
> > signal_error (loggy, err);
> >
> > Index: ./subversion/libsvn_wc/adm_ops.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/adm_ops.c.svn-base Mon Nov 26 09:35:18 2001
> > +++ ./subversion/libsvn_wc/adm_ops.c Wed Nov 28 13:05:32 2001
> > @@ -911,6 +911,9 @@
> > (err->apr_err, 0, NULL, pool,
> > "revert_admin_things: Error restoring pristine text for '%s'",
> > full_path->data);
> > + SVN_ERR (svn_io_set_permissions (full_path,
> > + APR_OS_DEFAULT,
> > + TRUE, pool));
> > SVN_ERR (svn_io_file_affected_time (&tstamp, full_path, pool));
> >
> > /* Modify our entry structure. */
> > Index: ./subversion/libsvn_wc/adm_files.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/adm_files.c.svn-base Mon Nov 26 09:35:18 2001
> > +++ ./subversion/libsvn_wc/adm_files.c Wed Nov 28 13:10:44 2001
> > @@ -289,11 +289,10 @@
> > return SVN_NO_ERROR;
> > }
> > }
> > - else /* SRC exists, so copy it to DST. */
> > + else /* SRC exists, so copy it to DST, and make sure we can write to it. */
> > {
> > - err = svn_io_copy_file (src, dst, pool);
> > - if (err)
> > - return err;
> > + SVN_ERR (svn_io_copy_file (src, dst, pool));
> > + SVN_ERR (svn_io_set_permissions (dst, APR_OS_DEFAULT, TRUE, pool));
> > }
> >
> > return SVN_NO_ERROR;
> > @@ -313,7 +312,7 @@
> > given how C va_lists work. */
> >
> > svn_stringbuf_t *tmp_path = svn_stringbuf_dup (path, pool);
> > - apr_status_t apr_err;
> > + svn_error_t *err;
> > int components_added;
> > va_list ap;
> >
> > @@ -327,18 +326,22 @@
> > v_extend_with_adm_name (tmp_path, extension, 1, pool, ap);
> > va_end (ap);
> >
> > - /* Rename. */
> > - apr_err = apr_file_rename (tmp_path->data, path->data, pool);
> > + /* Rename. 1) Make write-able, rename, make read-only. */
> > + err = svn_io_set_permissions (path, APR_UREAD | APR_UWRITE, FALSE, pool);
> > + if (!err || APR_STATUS_IS_ENOENT (err->apr_err))
> > + {
> > + err = svn_io_rename_file (tmp_path, path, pool);
> > + if (!err)
> > + err = svn_io_set_permissions (path,
> > + APR_UREAD | APR_GREAD | APR_WREAD,
> > + TRUE, pool);
> > + }
> > +
> >
> > /* Unconditionally restore path. */
> > chop_admin_name (path, components_added);
> >
> > - if (apr_err)
> > - return svn_error_createf (apr_err, 0, NULL, pool,
> > - "error renaming %s to %s",
> > - tmp_path->data, path->data);
> > - else
> > - return SVN_NO_ERROR;
> > + return err;
> > }
> >
> >
> > @@ -635,6 +638,7 @@
> > ...)
> > {
> > apr_status_t apr_err = 0;
> > + svn_error_t *err;
> > int components_added;
> > va_list ap;
> >
> > @@ -672,17 +676,20 @@
> > va_end (ap);
> >
> > /* Rename. */
> > - apr_err = apr_file_rename (tmp_path->data, path->data, pool);
> > + err = svn_io_set_permissions (path, APR_UREAD | APR_UWRITE, FALSE, pool);
> > + if (!err || APR_STATUS_IS_ENOENT (err->apr_err))
> > + {
> > + err = svn_io_rename_file (tmp_path, path, pool);
> > + if (!err)
> > + err = svn_io_set_permissions (path,
> > + APR_UREAD | APR_GREAD | APR_WREAD,
> > + TRUE, pool);
> > + }
> >
> > /* Unconditionally restore path. */
> > chop_admin_name (path, components_added);
> >
> > - if (apr_err)
> > - return svn_error_createf (apr_err, 0, NULL, pool,
> > - "error renaming %s to %s",
> > - tmp_path->data, path->data);
> > - else
> > - return SVN_NO_ERROR;
> > + return err;
> > }
> >
> > return SVN_NO_ERROR;
> > @@ -767,8 +774,13 @@
> > int sync,
> > apr_pool_t *pool)
> > {
> > - return close_adm_file (handle, path, NULL, sync, pool,
> > - SVN_WC__ADM_AUTH_DIR, file->data, NULL);
> > + svn_stringbuf_t *full_path = svn_stringbuf_dup(path, pool);
> > + SVN_ERR (close_adm_file (handle, path, NULL, sync, pool,
> > + SVN_WC__ADM_AUTH_DIR, file->data, NULL));
> > + extend_with_adm_name (full_path, NULL, FALSE, pool, SVN_WC__ADM_AUTH_DIR,
> > + file->data, NULL);
> > + SVN_ERR (svn_io_set_permissions (full_path, APR_UREAD, FALSE, pool));
> > + return SVN_NO_ERROR;
> > }
> >
> > svn_error_t *
> > @@ -966,9 +978,18 @@
> > components_added = v_extend_with_adm_name (path, NULL, 0, pool, ap);
> > va_end (ap);
> >
> > - apr_err = apr_file_remove (path->data, pool);
> > - if (apr_err)
> > - err = svn_error_create (apr_err, 0, NULL, pool, path->data);
> > + /* Make sure we have permission to remove the file. */
> > + err = svn_io_set_permissions (path, APR_UREAD | APR_UWRITE, FALSE, pool);
> > +
> > + if (!err || APR_STATUS_IS_ENOENT (err->apr_err))
> > + {
> > + /* It's okay if we couldn't change permissions because the file
> > + * didn't exist, since all we wanted to do was remove it. */
> > + err = NULL;
> > + apr_err = apr_file_remove (path->data, pool);
> > + if (apr_err)
> > + err = svn_error_create (apr_err, 0, NULL, pool, path->data);
> > + }
> >
> > /* Restore path to its original state no matter what. */
> > chop_admin_name (path, components_added);
> > Index: ./subversion/libsvn_wc/get_editor.c
> > ===================================================================
> > --- ./subversion/libsvn_wc/.svn/text-base/get_editor.c.svn-base Mon Nov 26 09:35:19 2001
> > +++ ./subversion/libsvn_wc/get_editor.c Tue Nov 27 09:42:39 2001
> > @@ -1155,6 +1155,9 @@
> > tmp_txtb,
> > SVN_WC__LOG_ATTR_DEST,
> > txtb,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create
> > + (SVN_WC__LOG_PERM_READONLY, fb->pool),
> > NULL);
> >
> > if ( (! is_locally_modified)
> > @@ -1171,6 +1174,9 @@
> > txtb,
> > SVN_WC__LOG_ATTR_DEST,
> > fb->name,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create
> > + (SVN_WC__LOG_PERM_DEFAULT, fb->pool),
> > NULL);
> > }
> >
> > @@ -1198,6 +1204,10 @@
> > txtb,
> > SVN_WC__LOG_ATTR_DEST,
> > fb->name,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create
> > + (SVN_WC__LOG_PERM_DEFAULT,
> > + fb->pool),
> > NULL);
> > }
> > else /* working file exists */
> > @@ -1411,6 +1421,9 @@
> > fb->name,
> > SVN_WC__LOG_ATTR_DEST,
> > renamed_basename,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create
> > + (SVN_WC__LOG_PERM_SRC, fb->pool),
> > NULL);
> >
> > /* Copy the new file out into working area. */
> > @@ -1422,6 +1435,9 @@
> > txtb,
> > SVN_WC__LOG_ATTR_DEST,
> > fb->name,
> > + SVN_WC__LOG_ATTR_PERM,
> > + svn_stringbuf_create
> > + (SVN_WC__LOG_PERM_DEFAULT, fb->pool),
> > NULL);
> > }
> > }
> > Index: ./subversion/libsvn_subr/io.c
> > ===================================================================
> > --- ./subversion/libsvn_subr/.svn/text-base/io.c.svn-base Wed Nov 21 12:45:58 2001
> > +++ ./subversion/libsvn_subr/io.c Wed Nov 28 12:31:56 2001
> > @@ -342,7 +342,8 @@
> >
> >
> > svn_error_t *
> > -svn_io_append_file (svn_stringbuf_t *src, svn_stringbuf_t *dst, apr_pool_t *pool)
> > +svn_io_append_file (svn_stringbuf_t *src, svn_stringbuf_t *dst,
> > + apr_pool_t *pool)
> > {
> > apr_status_t apr_err;
> >
> > @@ -358,8 +359,45 @@
> > return SVN_NO_ERROR;
> > }
> >
> > +svn_error_t *
> > +svn_io_rename_file (svn_stringbuf_t *src, svn_stringbuf_t *dst,
> > + apr_pool_t *pool)
> > +{
> > + apr_status_t apr_err = apr_file_rename (src->data, dst->data, pool);
> > + if (apr_err)
> > + return svn_error_createf (apr_err, 0, NULL, pool,
> > + "Couldn't rename `%s' to `%s'.",
> > + src->data, dst->data);
> >
> > + return SVN_NO_ERROR;
> > +}
> >
> > +svn_error_t *
> > +svn_io_set_permissions (svn_stringbuf_t *path, apr_fileperms_t perms,
> > + svn_boolean_t apply_umask, apr_pool_t *pool)
> > +{
> > + apr_status_t apr_err;
> > +#if (!defined(OS2) && !defined(BEOS) && !defined(WIN32) && !defined(NETWARE))
> > + if (apply_umask)
> > + {
> > + apr_fileperms_t mask = apr_unix_mode2perms (umask (0777));
> > + umask (apr_unix_perms2mode (mask));
> > + /* In order to apply the mask, we need to have an or of flags. For
> > + * some reason, apr's APR_OS_DEFAULT is not an or of flags, but
> > + * rather a special value. Convert it to its meaning here. */
> > + if (perms == APR_OS_DEFAULT)
> > + perms = APR_UREAD | APR_UWRITE | APR_GREAD | APR_GWRITE | APR_WREAD
> > + | APR_WWRITE;
> > + perms = perms & ~mask;
> > + }
> > +#endif
> > + apr_err = apr_file_perms_set (path->data, perms);
> > + if (apr_err && !APR_STATUS_IS_EINCOMPLETE (apr_err)
> > + && !APR_STATUS_IS_ENOTIMPL (apr_err))
> > + return svn_error_createf (apr_err, 0, NULL, pool, "Could not change "
> > + "permissions on `%s'.", path->data);
> > + return SVN_NO_ERROR;
> > +}
> >
> > svn_error_t *svn_io_copy_dir_recursively (svn_stringbuf_t *src,
> > svn_stringbuf_t *dst_parent,
> > --
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > Kevin Pilch-Bisson http://www.pilch-bisson.net
> > "Historically speaking, the presences of wheels in Unix
> > has never precluded their reinvention." - Larry Wall
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kevin Pilch-Bisson http://www.pilch-bisson.net
"Historically speaking, the presences of wheels in Unix
has never precluded their reinvention." - Larry Wall
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- application/pgp-signature attachment: stored
Received on Sat Oct 21 14:36:50 2006