⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Get the name of FILE, or NULL if FILE is an unnamed stream. */static svn_error_t *file_name_get(const char **fname_utf8, apr_file_t *file, apr_pool_t *pool){  apr_status_t apr_err;  const char *fname;  apr_err = apr_file_name_get(&fname, file);  if (apr_err)    return svn_error_wrap_apr(apr_err, _("Can't get file name"));  if (fname)    SVN_ERR(svn_path_cstring_to_utf8(fname_utf8, fname, pool));  else    *fname_utf8 = NULL;  return SVN_NO_ERROR;}svn_error_t *svn_stringbuf_from_aprfile(svn_stringbuf_t **result,                           apr_file_t *file,                           apr_pool_t *pool){  apr_size_t len;  svn_error_t *err;  svn_stringbuf_t *res = svn_stringbuf_create("", pool);  char *buf = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);  /* XXX: We should check the incoming data for being of type binary. */  /* apr_file_read will not return data and eof in the same call. So this loop   * is safe from missing read data.  */  len = SVN__STREAM_CHUNK_SIZE;  err = svn_io_file_read(file, buf, &len, pool);  while (! err)    {      svn_stringbuf_appendbytes(res, buf, len);      len = SVN__STREAM_CHUNK_SIZE;      err = svn_io_file_read(file, buf, &len, pool);    }  /* Having read all the data we *expect* EOF */  if (err && !APR_STATUS_IS_EOF(err->apr_err))    return err;  svn_error_clear(err);  /* Null terminate the stringbuf. */  res->data[res->len] = 0;  *result = res;  return SVN_NO_ERROR;}/* Deletion. */svn_error_t *svn_io_remove_file(const char *path, apr_pool_t *pool){  apr_status_t apr_err;  const char *path_apr;#ifdef WIN32  /* Set the file writable but only on Windows, because Windows     will not allow us to remove files that are read-only. */  SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));#endif /* WIN32 */  SVN_ERR(svn_path_cstring_from_utf8(&path_apr, path, pool));  apr_err = apr_file_remove(path_apr, pool);  WIN32_RETRY_LOOP(apr_err, apr_file_remove(path_apr, pool));  if (apr_err)    return svn_error_wrap_apr(apr_err, _("Can't remove file '%s'"),                              svn_path_local_style(path, pool));  return SVN_NO_ERROR;}/* Mac OS X has a bug where if you're readding the contents of a directory via readdir in a loop, and you remove one of the entries in the directory and the directory has 338 or more files in it you will skip over some of the entries in the directory.  Needless to say, this causes problems if you are using this kind of loop inside a function that is recursively deleting a directory, because when you get around to removing the directory it will still have something in it. This works around the problem by inserting a rewinddir after we remove each item in the directory, which makes the problem go away. See http://subversion.tigris.org/issues/show_bug.cgi?id=1896 for more discussion.*/#if defined(__APPLE__) && defined(__MACH__)#define MACOSX_REWINDDIR_HACK(dir, path)                                      \  do                                                                          \    {                                                                         \      apr_status_t apr_err  = apr_dir_rewind(dir);                      \      if (apr_err)                                                            \        return svn_error_wrap_apr(apr_err, _("Can't rewind directory '%s'"), \                                  svn_path_local_style(path, pool));    \    }                                                                         \  while (0)#else#define MACOSX_REWINDDIR_HACK(dir, path) do {} while (0)#endif/* Neither windows nor unix allows us to delete a non-empty   directory.     This is a function to perform the equivalent of 'rm -rf'. */svn_error_t *svn_io_remove_dir(const char *path, apr_pool_t *pool){  apr_status_t status;  apr_dir_t *this_dir;  apr_finfo_t this_entry;  apr_pool_t *subpool;  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;  const char *path_apr;  /* APR doesn't like "" directories */  if (path[0] == '\0')    path = ".";  /* Convert path to native here and call apr_dir_open directly,     instead of just using svn_io_dir_open, because we're going to     need path_apr later anyway when we remove the dir itself. */  SVN_ERR(svn_path_cstring_from_utf8(&path_apr, path, pool));  status = apr_dir_open(&this_dir, path_apr, pool);  if (status)    return svn_error_wrap_apr(status, _("Can't open directory '%s'"),                              svn_path_local_style(path, pool));  subpool = svn_pool_create(pool);  for (status = apr_dir_read(&this_entry, flags, this_dir);       status == APR_SUCCESS;       status = apr_dir_read(&this_entry, flags, this_dir))    {      svn_pool_clear(subpool);      if ((this_entry.filetype == APR_DIR)          && ((this_entry.name[0] == '.')              && ((this_entry.name[1] == '\0')                  || ((this_entry.name[1] == '.')                      && (this_entry.name[2] == '\0')))))        {          continue;        }      else  /* something other than "." or "..", so proceed */        {          const char *fullpath, *entry_utf8;          SVN_ERR(svn_path_cstring_to_utf8(&entry_utf8, this_entry.name,                                           subpool));                    fullpath = svn_path_join(path, entry_utf8, subpool);          if (this_entry.filetype == APR_DIR)            {              SVN_ERR(svn_io_remove_dir(fullpath, subpool));              MACOSX_REWINDDIR_HACK(this_dir, path);            }          else if (this_entry.filetype == APR_REG)            {              /* ### Do we really need the check for APR_REG here? Shouldn't                 we remove symlinks, pipes and whatnot, too?  --xbc */              svn_error_t *err = svn_io_remove_file(fullpath, subpool);              if (err)                return svn_error_createf                  (err->apr_err, err, _("Can't remove '%s'"),                   svn_path_local_style(fullpath, subpool));              MACOSX_REWINDDIR_HACK(this_dir, path);            }        }    }  apr_pool_destroy(subpool);  if (!APR_STATUS_IS_ENOENT(status))    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),                              svn_path_local_style(path, pool));  status = apr_dir_close(this_dir);  if (status)    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),                              svn_path_local_style(path, pool));  status = apr_dir_remove(path_apr, pool);  WIN32_RETRY_LOOP(status, apr_dir_remove(path_apr, pool));  if (status)    return svn_error_wrap_apr(status, _("Can't remove '%s'"),                              svn_path_local_style(path, pool));  return APR_SUCCESS;}svn_error_t *svn_io_get_dir_filenames(apr_hash_t **dirents,                         const char *path,                         apr_pool_t *pool){  apr_status_t status;   apr_dir_t *this_dir;  apr_finfo_t this_entry;  apr_int32_t flags = APR_FINFO_NAME;  *dirents = apr_hash_make(pool);    SVN_ERR(svn_io_dir_open(&this_dir, path, pool));  for (status = apr_dir_read(&this_entry, flags, this_dir);       status == APR_SUCCESS;       status = apr_dir_read(&this_entry, flags, this_dir))    {      if ((this_entry.name[0] == '.')          && ((this_entry.name[1] == '\0')              || ((this_entry.name[1] == '.')                  && (this_entry.name[2] == '\0'))))        {          continue;        }      else        {          const char *name;          SVN_ERR(svn_path_cstring_to_utf8(&name, this_entry.name, pool));          apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, name);        }    }  if (! (APR_STATUS_IS_ENOENT(status)))    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),                              svn_path_local_style(path, pool));  status = apr_dir_close(this_dir);  if (status)    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),                              svn_path_local_style(path, pool));    return SVN_NO_ERROR;}svn_error_t *svn_io_get_dirents2(apr_hash_t **dirents,                    const char *path,                    apr_pool_t *pool){  apr_status_t status;   apr_dir_t *this_dir;  apr_finfo_t this_entry;  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;  *dirents = apr_hash_make(pool);    SVN_ERR(svn_io_dir_open(&this_dir, path, pool));  for (status = apr_dir_read(&this_entry, flags, this_dir);       status == APR_SUCCESS;       status = apr_dir_read(&this_entry, flags, this_dir))    {      if ((this_entry.name[0] == '.')          && ((this_entry.name[1] == '\0')              || ((this_entry.name[1] == '.')                  && (this_entry.name[2] == '\0'))))        {          continue;        }      else        {          const char *name;          svn_io_dirent_t *dirent = apr_pcalloc(pool, sizeof(*dirent));          SVN_ERR(svn_path_cstring_to_utf8(&name, this_entry.name, pool));                    if (this_entry.filetype == APR_REG)            dirent->kind = svn_node_file;          else if (this_entry.filetype == APR_DIR)            dirent->kind = svn_node_dir;          else if (this_entry.filetype == APR_LNK)            {              dirent->kind = svn_node_file;              dirent->special = TRUE;            }          else            /* ### Currently, Subversion supports just symlinks; other             * entry types are reported as regular files. This is inconsistent             * with svn_io_check_path(). */            dirent->kind = svn_node_file;          apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, dirent);        }    }  if (! (APR_STATUS_IS_ENOENT(status)))    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),                              svn_path_local_style(path, pool));  status = apr_dir_close(this_dir);  if (status)    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),                              svn_path_local_style(path, pool));    return SVN_NO_ERROR;}svn_error_t *svn_io_get_dirents(apr_hash_t **dirents,                   const char *path,                   apr_pool_t *pool){  /* Note that in C, padding is not allowed at the beginning of structs,     so this is actually portable, since the kind field of svn_io_dirent_t     is first in that struct. */  return svn_io_get_dirents2(dirents, path, pool);}/* Pool userdata key for the error file passed to svn_io_start_cmd(). */#define ERRFILE_KEY "svn-io-start-cmd-errfile"/* Handle an error from the child process (before command execution) by   printing DESC and the error string corresponding to STATUS to stderr. */static voidhandle_child_process_error(apr_pool_t *pool, apr_status_t status,                           const char *desc){  char errbuf[256];  apr_file_t *errfile;  void *p;  /* We can't do anything if we get an error here, so just return. */  if (apr_pool_userdata_get(&p, ERRFILE_KEY, pool))    return;  errfile = p;  if (errfile)    /* What we get from APR is in native encoding. */    apr_file_printf(errfile, "%s: %s",                    desc, apr_strerror(status, errbuf,                                       sizeof(errbuf)));}svn_error_t *svn_io_start_cmd(apr_proc_t *cmd_proc,                 const char *path,                 const char *cmd,                 const char *const *args,                 svn_boolean_t inherit,                 apr_file_t *infile,                 apr_file_t *outfile,                 apr_file_t *errfile,                 apr_pool_t *pool){  apr_status_t apr_err;  apr_procattr_t *cmdproc_attr;  int num_args;  const char **args_native;  const char *cmd_apr;  /* Create the process attributes. */  apr_err = apr_procattr_create(&cmdproc_attr, pool);   if (apr_err)    return svn_error_wrap_apr      (apr_err, _("Can't create process '%s' attributes"), cmd);  /* Make sure we invoke cmd directly, not through a shell. */  apr_err = apr_procattr_cmdtype_set(cmdproc_attr,                                     inherit?APR_PROGRAM_PATH:APR_PROGRAM);  if (apr_err)    return svn_error_wrap_apr(apr_err, _("Can't set process '%s' cmdtype"),                              cmd);  /* Set the process's working directory. */  if (path)    {      const char *path_apr;      SVN_ERR(svn_path_cstring_from_utf8(&path_apr, path, pool));      apr_err = apr_procattr_dir_set(cmdproc_attr, path_apr);      if (apr_err)        return svn_error_wrap_apr          (apr_err, _("Can't set process '%s' directory"), cmd);    }  /* Use requested inputs and outputs.     ### Unfortunately each of these apr functions creates a pipe and then     overwrites the pipe file descriptor with the descriptor we pass     in. The pipes can then never be closed. This is an APR bug. */  if (infile)    {      apr_err = apr_procattr_child_in_set(cmdproc_attr, infile

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -