Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_subr/io.c  view on Meta::CPAN

#endif
}


svn_error_t *
svn_io_set_file_read_write(const char *path,
                           svn_boolean_t ignore_enoent,
                           apr_pool_t *pool)
{
  /* On Windows and OS/2, just set the file attributes -- on unix call
     our internal function which attempts to honor the umask. */
#if !defined(WIN32) && !defined(__OS2__)
  return io_set_file_perms(path, TRUE, TRUE, FALSE, FALSE,
                           ignore_enoent, pool);
#else
  apr_status_t status;
  const char *path_apr;

  SVN_ERR(cstring_from_utf8(&path_apr, path, pool));

  status = apr_file_attrs_set(path_apr,
                              0,
                              APR_FILE_ATTR_READONLY,
                              pool);

  if (status && status != APR_ENOTIMPL)
    if (!ignore_enoent || !APR_STATUS_IS_ENOENT(status))
      return svn_error_wrap_apr(status,
                                _("Can't set file '%s' read-write"),
                                svn_dirent_local_style(path, pool));

  return SVN_NO_ERROR;
#endif
}

svn_error_t *
svn_io_set_file_executable(const char *path,
                           svn_boolean_t executable,
                           svn_boolean_t ignore_enoent,
                           apr_pool_t *pool)
{
  /* On Windows and OS/2, just exit -- on unix call our internal function
  which attempts to honor the umask. */
#if (!defined(WIN32) && !defined(__OS2__))
  return io_set_file_perms(path, FALSE, FALSE, TRUE, executable,
                           ignore_enoent, pool);
#else
  return SVN_NO_ERROR;
#endif
}


svn_error_t *
svn_io__is_finfo_read_only(svn_boolean_t *read_only,
                           apr_finfo_t *file_info,
                           apr_pool_t *pool)
{
#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
  apr_status_t apr_err;
  apr_uid_t uid;
  apr_gid_t gid;

  *read_only = FALSE;

  apr_err = apr_uid_current(&uid, &gid, pool);

  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Error getting UID of process"));

  /* Check write bit for current user. */
  if (apr_uid_compare(uid, file_info->user) == APR_SUCCESS)
    *read_only = !(file_info->protection & APR_UWRITE);

  else if (apr_gid_compare(gid, file_info->group) == APR_SUCCESS)
    *read_only = !(file_info->protection & APR_GWRITE);

  else
    *read_only = !(file_info->protection & APR_WWRITE);

#else  /* WIN32 || __OS2__ || !APR_HAS_USER */
  *read_only = (file_info->protection & APR_FREADONLY);
#endif

  return SVN_NO_ERROR;
}

svn_error_t *
svn_io__is_finfo_executable(svn_boolean_t *executable,
                            apr_finfo_t *file_info,
                            apr_pool_t *pool)
{
#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
  apr_status_t apr_err;
  apr_uid_t uid;
  apr_gid_t gid;

  *executable = FALSE;

  apr_err = apr_uid_current(&uid, &gid, pool);

  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Error getting UID of process"));

  /* Check executable bit for current user. */
  if (apr_uid_compare(uid, file_info->user) == APR_SUCCESS)
    *executable = (file_info->protection & APR_UEXECUTE);

  else if (apr_gid_compare(gid, file_info->group) == APR_SUCCESS)
    *executable = (file_info->protection & APR_GEXECUTE);

  else
    *executable = (file_info->protection & APR_WEXECUTE);

#else  /* WIN32 || __OS2__ || !APR_HAS_USER */
  *executable = FALSE;
#endif

  return SVN_NO_ERROR;
}

svn_error_t *
svn_io_is_file_executable(svn_boolean_t *executable,
                          const char *path,
                          apr_pool_t *pool)
{
#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
  apr_finfo_t file_info;

  SVN_ERR(svn_io_stat(&file_info, path, APR_FINFO_PROT | APR_FINFO_OWNER,
                      pool));
  SVN_ERR(svn_io__is_finfo_executable(executable, &file_info, pool));

#else  /* WIN32 || __OS2__ || !APR_HAS_USER */
  *executable = FALSE;
#endif

  return SVN_NO_ERROR;
}


/*** File locking. ***/
#if !defined(WIN32) && !defined(__OS2__)
/* Clear all outstanding locks on ARG, an open apr_file_t *. */
static apr_status_t
file_clear_locks(void *arg)
{
  apr_status_t apr_err;
  apr_file_t *f = arg;

  /* Remove locks. */
  apr_err = apr_file_unlock(f);
  if (apr_err)
    return apr_err;

  return 0;
}
#endif

svn_error_t *
svn_io_lock_open_file(apr_file_t *lockfile_handle,
                      svn_boolean_t exclusive,
                      svn_boolean_t nonblocking,
                      apr_pool_t *pool)
{
  int locktype = APR_FLOCK_SHARED;
  apr_status_t apr_err;
  const char *fname;

src/subversion/subversion/libsvn_subr/io.c  view on Meta::CPAN


      status = apr_file_rename(from_path_apr, to_path_apr, pool);
    }
  WIN32_RETRY_LOOP(status, apr_file_rename(from_path_apr, to_path_apr, pool));
#endif /* WIN32 || __OS2__ */

  if (status)
    return svn_error_wrap_apr(status, _("Can't move '%s' to '%s'"),
                              svn_dirent_local_style(from_path, pool),
                              svn_dirent_local_style(to_path, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_io_file_move(const char *from_path, const char *to_path,
                 apr_pool_t *pool)
{
  svn_error_t *err = svn_io_file_rename(from_path, to_path, pool);

  if (err && APR_STATUS_IS_EXDEV(err->apr_err))
    {
      const char *tmp_to_path;

      svn_error_clear(err);

      SVN_ERR(svn_io_open_unique_file3(NULL, &tmp_to_path,
                                       svn_dirent_dirname(to_path, pool),
                                       svn_io_file_del_none,
                                       pool, pool));

      err = svn_io_copy_file(from_path, tmp_to_path, TRUE, pool);
      if (err)
        goto failed_tmp;

      err = svn_io_file_rename(tmp_to_path, to_path, pool);
      if (err)
        goto failed_tmp;

      err = svn_io_remove_file2(from_path, FALSE, pool);
      if (! err)
        return SVN_NO_ERROR;

      svn_error_clear(svn_io_remove_file2(to_path, FALSE, pool));

      return err;

    failed_tmp:
      svn_error_clear(svn_io_remove_file2(tmp_to_path, FALSE, pool));
    }

  return err;
}

/* Common implementation of svn_io_dir_make and svn_io_dir_make_hidden.
   HIDDEN determines if the hidden attribute
   should be set on the newly created directory. */
static svn_error_t *
dir_make(const char *path, apr_fileperms_t perm,
         svn_boolean_t hidden, svn_boolean_t sgid, apr_pool_t *pool)
{
  apr_status_t status;
  const char *path_apr;

  SVN_ERR(cstring_from_utf8(&path_apr, path, pool));

  /* APR doesn't like "" directories */
  if (path_apr[0] == '\0')
    path_apr = ".";

#if (APR_OS_DEFAULT & APR_WSTICKY)
  /* The APR shipped with httpd 2.0.50 contains a bug where
     APR_OS_DEFAULT encompasses the setuid, setgid, and sticky bits.
     There is a special case for file creation, but not directory
     creation, so directories wind up getting created with the sticky
     bit set.  (There is no such thing as a setuid directory, and the
     setgid bit is apparently ignored at mkdir() time.)  If we detect
     this problem, work around it by unsetting those bits if we are
     passed APR_OS_DEFAULT. */
  if (perm == APR_OS_DEFAULT)
    perm &= ~(APR_USETID | APR_GSETID | APR_WSTICKY);
#endif

  status = apr_dir_make(path_apr, perm, pool);
  WIN32_RETRY_LOOP(status, apr_dir_make(path_apr, perm, pool));

  if (status)
    return svn_error_wrap_apr(status, _("Can't create directory '%s'"),
                              svn_dirent_local_style(path, pool));

#ifdef APR_FILE_ATTR_HIDDEN
  if (hidden)
    {
#ifndef WIN32
      status = apr_file_attrs_set(path_apr,
                                  APR_FILE_ATTR_HIDDEN,
                                  APR_FILE_ATTR_HIDDEN,
                                  pool);
#else
    /* on Windows, use our wrapper so we can also set the
       FILE_ATTRIBUTE_NOT_CONTENT_INDEXED attribute */
    status = io_win_file_attrs_set(path_apr,
                                   FILE_ATTRIBUTE_HIDDEN |
                                   FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
                                   FILE_ATTRIBUTE_HIDDEN |
                                   FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
                                   pool);

#endif
      if (status)
        return svn_error_wrap_apr(status, _("Can't hide directory '%s'"),
                                  svn_dirent_local_style(path, pool));
    }
#endif

/* Windows does not implement sgid. Skip here because retrieving
   the file permissions via APR_FINFO_PROT | APR_FINFO_OWNER is documented
   to be 'incredibly expensive'. */
#ifndef WIN32
  if (sgid)
    {
      apr_finfo_t finfo;

      /* Per our contract, don't do error-checking.  Some filesystems
       * don't support the sgid bit, and that's okay. */
      status = apr_stat(&finfo, path_apr, APR_FINFO_PROT, pool);

      if (!status)
        apr_file_perms_set(path_apr, finfo.protection | APR_GSETID);
    }
#endif

  return SVN_NO_ERROR;
}

svn_error_t *
svn_io_dir_make(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
{
  return dir_make(path, perm, FALSE, FALSE, pool);
}

svn_error_t *
svn_io_dir_make_hidden(const char *path, apr_fileperms_t perm,
                       apr_pool_t *pool)
{
  return dir_make(path, perm, TRUE, FALSE, pool);
}

svn_error_t *
svn_io_dir_make_sgid(const char *path, apr_fileperms_t perm,
                     apr_pool_t *pool)
{
  return dir_make(path, perm, FALSE, TRUE, pool);
}


svn_error_t *
svn_io_dir_open(apr_dir_t **new_dir, const char *dirname, apr_pool_t *pool)
{
  apr_status_t status;
  const char *dirname_apr;

  /* APR doesn't like "" directories */
  if (dirname[0] == '\0')
    dirname = ".";

  SVN_ERR(cstring_from_utf8(&dirname_apr, dirname, pool));

  status = apr_dir_open(new_dir, dirname_apr, pool);
  if (status)
    return svn_error_wrap_apr(status, _("Can't open directory '%s'"),
                              svn_dirent_local_style(dirname, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_io_dir_remove_nonrecursive(const char *dirname, apr_pool_t *pool)
{
  apr_status_t status;
  const char *dirname_apr;

  SVN_ERR(cstring_from_utf8(&dirname_apr, dirname, pool));

  status = apr_dir_remove(dirname_apr, pool);

#ifdef WIN32
  {
    svn_boolean_t retry = TRUE;

    if (APR_TO_OS_ERROR(status) == ERROR_DIR_NOT_EMPTY)
      {
        apr_status_t empty_status = dir_is_empty(dirname_apr, pool);

        if (APR_STATUS_IS_ENOTEMPTY(empty_status))
          retry = FALSE;
      }

    if (retry)
      {
        WIN32_RETRY_LOOP(status, apr_dir_remove(dirname_apr, pool));
      }
  }
#endif
  if (status)
    return svn_error_wrap_apr(status, _("Can't remove directory '%s'"),
                              svn_dirent_local_style(dirname, pool));

  return SVN_NO_ERROR;
}



( run in 1.012 second using v1.01-cache-2.11-cpan-71847e10f99 )