如何在C++中设置文件权限(跨平台)?

2023-12-07

我正在使用 C++ofstream写出一个文件。我想将权限设置为只能由用户访问:700。在unix中;我想我可以发出一个system("chmod 700 file.txt");但我需要这段代码也能在 Windows 上运行。我可以使用一些Windows api;但是最好的 C++ 跨平台方法是什么?


具有讽刺意味的是,我今天早些时候刚刚遇到了同样的需求。

就我而言,答案取决于我在 Windows 上与 Linux 上需要什么级别的权限粒度。就我而言,我只关心 Linux 上的用户、组和其他权限。在 Windows 上,DOS 留下的基本读/写全部权限对我来说已经足够了,即我不需要在 Windows 上处理 ACL。

一般来说,Windows有两种权限模型:基本的DOS模型和较新的访问控制模型。在DOS模型下有一种权限:写权限。所有文件都可以读取,因此无法关闭读取权限(因为它不存在)。也没有执行权限的概念。如果一个文件可以被读取(答案是肯定的)并且它是二进制的,那么它就可以被执行;否则不能。

基本的 DOS 模型足以满足大多数 Windows 环境,即系统由单个用户在可以被认为相对安全的物理位置使用的环境。访问控制模型要复杂几个数量级。

访问控制模型使用访问控制列表(ACL)来授予权限。权限只能由具有必要权限的进程授予。此模型不仅允许控制用户、组和其他具有读、写和执行权限的用户,而且还允许通过网络和 Windows 域之间控制文件。 (您也可以在使用 PAM 的 Unix 系统上获得这种程度的疯狂。)

注意:访问控制模型仅适用于 NTFS 分区,如果您使用 FAT 分区,则您是 SOL。

使用 ACL 是一件很痛苦的事情。这不是一项简单的任务,它不仅需要您学习 ACL,还需要学习所有有关安全描述符、访问令牌以及许多其他高级 Windows 安全概念的知识。

对我来说幸运的是,对于我当前的需求,我不需要访问控制模型提供的真正的安全性。我基本上可以在 Windows 上假装设置权限,只要我真的在 Linux 上设置权限即可。

Windows 支持他们所谓的“ISO C++ 一致”版本的 chmod(2)。这个 API 称为 _chmod,它与 chmod(2) 类似,但有更多限制,并且类型或名称不兼容(当然)。 Windows 还有一个已弃用的 chmod,因此您不能简单地将 chmod 添加到 Windows 并在 Linux 上使用直接的 chmod(2)。

我写了以下内容:

#include <sys/stat.h>
#include <sys/types.h>

#ifdef _WIN32
#   include <io.h>

typedef int mode_t;

/// @Note If STRICT_UGO_PERMISSIONS is not defined, then setting Read for any
///       of User, Group, or Other will set Read for User and setting Write
///       will set Write for User.  Otherwise, Read and Write for Group and
///       Other are ignored.
///
/// @Note For the POSIX modes that do not have a Windows equivalent, the modes
///       defined here use the POSIX values left shifted 16 bits.

static const mode_t S_ISUID      = 0x08000000;           ///< does nothing
static const mode_t S_ISGID      = 0x04000000;           ///< does nothing
static const mode_t S_ISVTX      = 0x02000000;           ///< does nothing
static const mode_t S_IRUSR      = mode_t(_S_IREAD);     ///< read by user
static const mode_t S_IWUSR      = mode_t(_S_IWRITE);    ///< write by user
static const mode_t S_IXUSR      = 0x00400000;           ///< does nothing
#   ifndef STRICT_UGO_PERMISSIONS
static const mode_t S_IRGRP      = mode_t(_S_IREAD);     ///< read by *USER*
static const mode_t S_IWGRP      = mode_t(_S_IWRITE);    ///< write by *USER*
static const mode_t S_IXGRP      = 0x00080000;           ///< does nothing
static const mode_t S_IROTH      = mode_t(_S_IREAD);     ///< read by *USER*
static const mode_t S_IWOTH      = mode_t(_S_IWRITE);    ///< write by *USER*
static const mode_t S_IXOTH      = 0x00010000;           ///< does nothing
#   else
static const mode_t S_IRGRP      = 0x00200000;           ///< does nothing
static const mode_t S_IWGRP      = 0x00100000;           ///< does nothing
static const mode_t S_IXGRP      = 0x00080000;           ///< does nothing
static const mode_t S_IROTH      = 0x00040000;           ///< does nothing
static const mode_t S_IWOTH      = 0x00020000;           ///< does nothing
static const mode_t S_IXOTH      = 0x00010000;           ///< does nothing
#   endif
static const mode_t MS_MODE_MASK = 0x0000ffff;           ///< low word

static inline int my_chmod(const char * path, mode_t mode)
{
    int result = _chmod(path, (mode & MS_MODE_MASK));

    if (result != 0)
    {
        result = errno;
    }

    return (result);
}
#else
static inline int my_chmod(const char * path, mode_t mode)
{
    int result = chmod(path, mode);

    if (result != 0)
    {
        result = errno;
    }

    return (result);
}
#endif

请务必记住,我的解决方案仅提供 DOS 类型的安全性。这也称为无安全性,但这是大多数应用程序在 Windows 上为您提供的安全程度。

另外,根据我的解决方案,如果您没有定义 STRICT_UGO_PERMISSIONS,当您授予组或其他权限(或就此删除它)时,您实际上是在更改所有者。如果您不想这样做,但仍然不需要完整的 Windows ACL 权限,只需定义 STRICT_UGO_PERMISSIONS。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在C++中设置文件权限(跨平台)? 的相关文章

随机推荐

  • 如何在类声明之外定义 sfinae 类的成员?

    阅读完诸如此类的问题后sfinae 位于类体外部定义的成员函数 这不是同一个问题 另外 当使用 SFINAE 方法仅启用算术类型的类时 我仍然没有找到在类声明之外定义成员函数体的好方法 include
  • Swift 3 隐式解包选项导致错误的字符串插值

    Why are 隐式解包选项在 Swift 3 中使用字符串插值时未解包 Example 在 Playground 中运行以下代码 var str String str Hello print The following should no
  • 用facet对y轴进行排序

    我有这个数据框 library dplyr dat data frame parent c J J F F group c A 4 C 3 A 4 D 5 value c 1 2 3 4 count c 4 3 4 5 dat gt arr
  • IE 8 支持 JSON.stringify() 吗?

    我需要使用 JSON stringify Chrome Safari 和 Firefox 应该支持 我认为IE8也支持JSON对象 我认为 IE7 和 6 没有 所以我这样做 所以 我认为只有 IE6 和 7 才会导入外部 JavaScri
  • Mercurial自动更新问题

    我们开始使用 Mercurial 进行源代码控制 我们已将 HGRC 配置文件配置为在推送到 中央 存储库后自动更新 对于某些 PC 我们会收到以下错误消息 warning changegroup hook exited with stat
  • Magento 自定义模块,致命错误:调用成员函数 setFormAction()

    当我点击这个 url 上的模块时http localhost xxx index php TradeEnquiry我收到这个错误 致命错误 调用成员函数 setFormAction 对非对象进行 C wamp www stockdispla
  • 从 CSV Import 更新现有的 Access 记录,原生于 MS Access 或 VB.NET

    我是我所在组织的票务系统的应用程序管理员 我们正在添加一个新客户 需要将他们的客户记录导入到我们的系统中 然而 我们被拒绝从直接数据库连接中简单地获取这些记录 我们仅限于进入他们的票务系统 并将现有记录导出到 CSV 文件 为了在我们的系统
  • 如何(准确)估计剩余下载时间?

    当然 您可以将剩余文件大小除以当前下载速度 但如果您的下载速度波动 而且它会波动 这不会产生非常好的结果 有什么更好的算法可以产生更平滑的倒计时 An 指数移动平均线非常适合这个 它提供了一种平滑平均值的方法 以便每次添加新样本时 旧样本对
  • Java 8 原始流到集合的映射方法

    这两种流创建方法之间是否存在显着差异 在性能或最佳实践方面 int arr2 1 2 3 4 5 6 Arrays stream arr2 map in gt in 2 mapToObj in gt new Integer in colle
  • “原始字符串正则表达式”到底是什么以及如何使用它?

    来自 python 文档regex 关于 特点 解决方案是使用 Python 的原始字符串表示法来表示正则 表达模式 反斜杠不会以任何特殊方式处理 前缀为的字符串文字 r So r n 是一个两个字符的字符串 含有 and n while
  • p:graphicImage 的替代方案,它可以显示来自 byte[] 的图像并控制浏览器缓存

    似乎有一个错误p graphicimage使用更新功能时 通过加载一张图像value myController myStreamedContent 有效 但是当改变时myController myStreamedContent随后更新p g
  • CUDA 可以解决许多“小型/中型”线性系统

    关于我尝试使用 CUDA 加速的问题的一些背景信息 我有大量小型 中型相同尺寸的线性系统需要独立求解 每个线性系统都是方形的 实数的 稠密的 可逆的和非对称的 这些实际上是矩阵系统 因此每个系统看起来都像 AX B 其中 A X 和 B 是
  • 浏览器后退按钮不会清除旧的后备 bean 值

    我们使用 JSF2 我们有一个带有表单字段的页面 其中命令按钮链接到支持 bean 当我们访问表单页面 输入值并提交时 支持 bean 会收到正确的值并将其带到下一页 如果我按浏览器中的后退按钮 它将转到带有表单的上一页 如果我在表单中输入
  • 如何实现通用的max函数?

    我知道这是因为模板函数的返回类型与第一个参数 T 的返回类型相同 如何修改此模板 使其在所有情况下都能正确运行 include
  • EventEmitter类的清晰概念

    代码写入子组件 mycomponent ts import Component OnInit EventEmitter Output from angular core Component selector app mycomponent
  • 将 shell 变量传递给 JSON 请求以进行curl?

    让我们看下面的例子 curl i X POST H Content Type application json d jsonrpc 2 0 method Player Open params item false http example
  • 排序多维数组javascript

    我想对双精度的多维数组进行排序 该数组如下所示 1 2 2 3 5 6 8 9 我想按 X 值对其进行排序 并保持 x y 值配对 我在网站上搜索了多维排序 发现了类似的帖子these其中排序函数修改如下 location sort fun
  • 如何检查字符串是否可以转换为浮点数?

    首先 我的背景是需要将浮点文字 字符串 转换为浮点 双精度值的编译器编写者 过去 15 年我没有做过任何浮点编程 所以我很确定这是一个完全愚蠢的新手问题 double res errno 0 res strtod const char li
  • 如何设置TabHost背景颜色

    我需要帮助 我发现在 TabHost 中更改背景颜色很困难 原图 我需要修改背景颜色 如下图所示 我也在我的代码和 XML 中尝试了很多东西 但都失败了 我的代码如下 TabHost tabHost getTabHost Tab 1 Tab
  • 如何在C++中设置文件权限(跨平台)?

    我正在使用 C ofstream写出一个文件 我想将权限设置为只能由用户访问 700 在unix中 我想我可以发出一个system chmod 700 file txt 但我需要这段代码也能在 Windows 上运行 我可以使用一些Wind