📄 adm_files.c
字号:
NULL); } return SVN_NO_ERROR;}/* Return a path to the 'wcprop' file for PATH, possibly in TMP area. */svn_error_t *svn_wc__wcprop_path(const char **wcprop_path, const char *path, svn_node_kind_t kind, svn_boolean_t tmp, apr_pool_t *pool){ return prop_path_internal(wcprop_path, path, kind, prop_path_kind_wcprop, tmp, pool);}svn_error_t *svn_wc__prop_path(const char **prop_path, const char *path, svn_node_kind_t kind, svn_boolean_t tmp, apr_pool_t *pool){ return prop_path_internal(prop_path, path, kind, prop_path_kind_working, tmp, pool);}svn_error_t *svn_wc__prop_base_path(const char **prop_path, const char *path, svn_node_kind_t kind, svn_boolean_t tmp, apr_pool_t *pool){ return prop_path_internal(prop_path, path, kind, prop_path_kind_base, tmp, pool);}svn_error_t *svn_wc__prop_revert_path(const char **prop_path, const char *path, svn_node_kind_t kind, svn_boolean_t tmp, apr_pool_t *pool){ return prop_path_internal(prop_path, path, kind, prop_path_kind_revert, tmp, pool);}/*** Opening and closing files in the adm area. ***//* Open a file somewhere in the adm area for directory PATH. * First, add the adm subdir as the next component of PATH, then add * each of the varargs (they are char *'s), then add EXTENSION if it * is non-null, then open the resulting file as *HANDLE. * * If FLAGS indicates writing, open the file in the adm tmp area. * This means the file will probably need to be renamed from there, * either by passing the sync flag to close_adm_file() later, or with * an explicit call to sync_adm_file(). */static svn_error_t *open_adm_file(apr_file_t **handle, const char *path, const char *extension, apr_fileperms_t protection, apr_int32_t flags, apr_pool_t *pool, ...){ svn_error_t *err = SVN_NO_ERROR; va_list ap; /* If we're writing, always do it to a tmp file. */ if (flags & APR_WRITE) { if (flags & APR_APPEND) { /* We don't handle append. To do so we would need to copy the contents into the apr_file_t once it has been opened. */ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE, NULL, _("APR_APPEND not supported for adm files")); } /* Need to own the temporary file, so don't reuse an existing one. */ flags |= APR_EXCL | APR_CREATE; /* Extend with tmp name. */ va_start(ap, pool); path = v_extend_with_adm_name(path, extension, 1, pool, ap); va_end(ap); } else { /* Extend with regular adm name. */ va_start(ap, pool); path = v_extend_with_adm_name(path, extension, 0, pool, ap); va_end(ap); } err = svn_io_file_open(handle, path, flags, protection, pool); if ((flags & APR_WRITE) && err && APR_STATUS_IS_EEXIST(err->apr_err)) { /* Exclusive open failed, delete and retry */ svn_error_clear(err); SVN_ERR(svn_io_remove_file(path, pool)); err = svn_io_file_open(handle, path, flags, protection, pool); } if (err) { /* Oddly enough, APR will set *HANDLE even if the open failed. You'll get a filehandle whose descriptor is -1. There must be a reason this is useful... Anyway, we don't want the handle. */ *handle = NULL; /* If we receive a failure to open a file in our temporary directory, * it may be because our temporary directories aren't created. * Older SVN clients did not create these directories. * 'svn cleanup' will fix this problem. */ if (APR_STATUS_IS_ENOENT(err->apr_err) && (flags & APR_WRITE)) { err = svn_error_quick_wrap(err, _("Your .svn/tmp directory may be missing or " "corrupt; run 'svn cleanup' and try again")); } } return err;}/* Close the file indicated by FP (PATH is passed to make error * reporting better). If SYNC is non-zero, then the file will be * sync'd from the adm tmp area to its permanent location, otherwise * it will remain in the tmp area. See open_adm_file(). */static svn_error_t *close_adm_file(apr_file_t *fp, const char *path, const char *extension, svn_boolean_t sync, apr_pool_t *pool, ...){ const char *tmp_path; va_list ap; /* Get the full name of the thing we're closing. */ va_start(ap, pool); tmp_path = v_extend_with_adm_name(path, extension, sync, pool, ap); va_end(ap); SVN_ERR(svn_io_file_close(fp, pool)); /* If we're syncing a tmp file, it needs to be renamed after closing. */ if (sync) { /* Some code duplication with sync_adm_file() seems unavoidable, given how C va_lists work. */ /* Obtain dest name. */ va_start(ap, pool); path = v_extend_with_adm_name(path, extension, 0, pool, ap); va_end(ap); /* Rename. */ SVN_ERR(svn_io_file_rename(tmp_path, path, pool)); SVN_ERR(svn_io_set_file_read_only(path, FALSE, pool)); return SVN_NO_ERROR; } return SVN_NO_ERROR;}svn_error_t *svn_wc__open_adm_file(apr_file_t **handle, const char *path, const char *fname, apr_int32_t flags, apr_pool_t *pool){ return open_adm_file(handle, path, NULL, APR_OS_DEFAULT, flags, pool, fname, NULL);}svn_error_t *svn_wc__close_adm_file(apr_file_t *fp, const char *path, const char *fname, int sync, apr_pool_t *pool){ return close_adm_file(fp, path, NULL, sync, pool, fname, NULL);}svn_error_t *svn_wc__remove_adm_file(const char *path, apr_pool_t *pool, ...){ va_list ap; va_start(ap, pool); path = v_extend_with_adm_name(path, NULL, 0, pool, ap); va_end(ap); SVN_ERR(svn_io_remove_file(path, pool)); return SVN_NO_ERROR;}svn_error_t *svn_wc__open_text_base(apr_file_t **handle, const char *path, apr_int32_t flags, apr_pool_t *pool){ const char *parent_path, *base_name; svn_path_split(path, &parent_path, &base_name, pool); return open_adm_file(handle, parent_path, SVN_WC__BASE_EXT, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_TEXT_BASE, base_name, NULL);}svn_error_t *svn_wc__open_revert_base(apr_file_t **handle, const char *path, apr_int32_t flags, apr_pool_t *pool){ const char *parent_path, *base_name; svn_path_split(path, &parent_path, &base_name, pool); return open_adm_file(handle, parent_path, SVN_WC__REVERT_EXT, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_TEXT_BASE, base_name, NULL);}svn_error_t *svn_wc__close_text_base(apr_file_t *fp, const char *path, int write, apr_pool_t *pool){ const char *parent_path, *base_name; svn_path_split(path, &parent_path, &base_name, pool); return close_adm_file(fp, parent_path, SVN_WC__BASE_EXT, write, pool, SVN_WC__ADM_TEXT_BASE, base_name, NULL);}svn_error_t *svn_wc__close_revert_base(apr_file_t *fp, const char *path, int write, apr_pool_t *pool){ const char *parent_path, *base_name; svn_path_split(path, &parent_path, &base_name, pool); return close_adm_file(fp, parent_path, SVN_WC__REVERT_EXT, write, pool, SVN_WC__ADM_TEXT_BASE, base_name, NULL);}svn_error_t *svn_wc__open_props(apr_file_t **handle, const char *path, apr_int32_t flags, svn_boolean_t base, svn_boolean_t wcprops, apr_pool_t *pool){ const char *parent_dir, *base_name; svn_node_kind_t kind; int wc_format_version; SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind == svn_node_dir) parent_dir = path; else svn_path_split(path, &parent_dir, &base_name, pool); /* At this point, we know we need to open a file in the admin area of parent_dir. First check that parent_dir is a working copy: */ SVN_ERR(svn_wc_check_wc(parent_dir, &wc_format_version, pool)); if (wc_format_version == 0) return svn_error_createf (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL, _("'%s' is not a working copy"), svn_path_local_style(parent_dir, pool)); /* Then examine the flags to know -which- kind of prop file to get. */ if (base && wcprops) return svn_error_create(SVN_ERR_WC_PATH_NOT_FOUND, NULL, _("No such thing as 'base' " "working copy properties!")); else if (base) { if (kind == svn_node_dir) return open_adm_file(handle, parent_dir, NULL, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_DIR_PROP_BASE, NULL); else return open_adm_file(handle, parent_dir, SVN_WC__BASE_EXT, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_PROP_BASE, base_name, NULL); } else if (wcprops) { if (kind == svn_node_dir) return open_adm_file(handle, parent_dir, NULL, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_DIR_WCPROPS, NULL); else { return open_adm_file (handle, parent_dir, SVN_WC__WORK_EXT, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_WCPROPS, base_name, NULL); } } else /* plain old property file */ { if (kind == svn_node_dir) return open_adm_file(handle, parent_dir, NULL, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_DIR_PROPS, NULL); else { return open_adm_file (handle, parent_dir, SVN_WC__WORK_EXT, APR_OS_DEFAULT, flags, pool, SVN_WC__ADM_PROPS, base_name, NULL); } }}svn_error_t *svn_wc__close_props(apr_file_t *fp, const char *path, svn_boolean_t base, svn_boolean_t wcprops, int sync, apr_pool_t *pool){ const char *parent_dir, *base_name; svn_node_kind_t kind; SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind == svn_node_dir) parent_dir = path; else svn_path_split(path, &parent_dir, &base_name, pool); /* At this point, we know we need to close a file in the admin area of parent_dir. Since the file must be open already, we know that parent_dir is a working copy. */ /* Then examine the flags to know -which- kind of prop file to get. */ if (base && wcprops) return svn_error_create(SVN_ERR_WC_PATH_NOT_FOUND, NULL, _("No such thing as 'base' " "working copy properties!")); else if (base) { if (kind == svn_node_dir) return close_adm_file(fp, parent_dir, NULL, sync, pool, SVN_WC__ADM_DIR_PROP_BASE, NULL); else return close_adm_file(fp, parent_dir, SVN_WC__BASE_EXT, sync, pool, SVN_WC__ADM_PROP_BASE, base_name, NULL); } else if (wcprops) { if (kind == svn_node_dir) return close_adm_file(fp, parent_dir, NULL, sync, pool, SVN_WC__ADM_DIR_WCPROPS, NULL); else return close_adm_file (fp, parent_dir, SVN_WC__WORK_EXT, sync, pool, SVN_WC__ADM_WCPROPS, base_name, NULL); } else /* plain old property file */ { if (kind == svn_node_dir) return close_adm_file(fp, parent_dir, NULL, sync, pool, SVN_WC__ADM_DIR_PROPS, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -