【问题标题】:C file open() function is only setting user level permission in AndroidC 文件 open() 函数仅在 Android 中设置用户级权限
【发布时间】:2018-07-14 08:51:32
【问题描述】:

我正在使用 C open() 函数在 android 中创建文件并根据需要设置访问权限。我观察到在 Android 中, open() 只能设置用户级别的访问权限。为了给文件必要的组和其他级别的权限,我必须在创建文件后显式使用 chmod() 。

这就是我正在做的,

/*Test code - starts*/
    tmp = open("/data/data/com.application.app1.tests/foo5.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); // these permissions doen't seems o work hence will work with chmod
    close(tmp);
    tmp = open("/data/data/com.application.app1.tests/foo7.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    close(tmp);
    tmp = open("/data/data/com.application.app1.tests/foo8.txt", O_CREAT | O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
    close(tmp);

    tmp = open("/data/data/com.application.app1.tests/foo55.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); // these permissions doen't seems o work hence will work with chmod
    close(tmp);
    chmod("/data/data/com.application.app1.tests/foo55.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    tmp = open("/data/data/com.microsoft.palAWasp.tests/foo77.txt", O_CREAT | O_RDWR | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    close(tmp);
    chmod("/data/data/com.application.palAWasp.tests/foo77.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    tmp = open("/data/data/com.application.app1.tests/foo88.txt", O_CREAT | O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
    close(tmp);
    chmod("/data/data/com.application.app1.tests/foo88.txt", S_IRUSR | S_IRGRP | S_IROTH);

    /*Test code - Ends*/

下面的输出是这样的,

/***************编辑***************/ 另一个重要的观察是,当我尝试使用上述权限位创建类似文件时,默认权限位是,

-rw------- u0_a100  u0_a100         0 2018-03-26 12:43 foo5.txt
-rw------- u0_a100  u0_a100         0 2018-03-26 12:43 log0.log

当我尝试使用 chmod 更改权限位时,它失败了。 请注意,chmod 适用于数据目录中的文件,但不适用于 /sdcard/ 上的文件

请帮助我理解这种行为。

【问题讨论】:

  • 关于chmod在数据目录下工作,但对/sdcard上的文件不起作用,可能与挂载到/sdcard的分区与数据目录不同有关。也许我错了,但我猜 /sdcard 使用 fat32?如果我错了,请纠正我。

标签: android c file-io fopen android-sdcard


【解决方案1】:

您可能正在寻找的是设置 umask,以便按照您的预期分配默认权限。

Linux umask command

这个其他链接解释了它是如何工作的。注意与错误代码相关的区域及其解释。

Setting Permissions

概述:系统在创建文件时根据与进程关联的 umask 限制文件的权限。您可以稍后使用 chmod 或 fchmod 更改权限。如果文件系统不允许某些权限(例如,尝试为托管在只读文件系统中的文件设置写权限),您将收到错误消息。如果指定了挂载文件系统时的某些选项,这也可能适用。这可以解释这样一个事实,即您在 /data 上调用的 chmod 正在工作,而不是进入 /sdcard(不同的文件系统具有与之关联的不同 umask 选项)。要了解有关您的场景的更多信息,请在 chmod 功能失败时检查 errno。

换句话说:

final_mask = mask_open & ~umask_process & mask_opt_filesystem

其中 mask_open 是“open()”函数中指定的权限; umask_process 是指定到与进程关联的 umask 中的权限; mask_opt_filesystem 是创建新文件时与上述文件系统相关联的掩码; final_mask 是最后一个掩码,表示要分配给刚刚创建的文件的权限。

最后,您可以更改当前进程和子进程的 umask,但不推荐根据上述链接的阅读,这样,您使用 chmod 做正确的事情。

如果您在 Android 设备内的终端中运行“挂载”,您会看到一些条目出现在“模式”选项中。这是用于该文件系统的掩码。如果你在同一个终端运行“umask”,你可以看到应用到终端的umask。

【讨论】:

  • 所以你的意思是这不是 /sdcard/ 或任何其他位置的任何 android 行为?
  • 请回复。我不明白你的意思。
  • 关于 umask,它会更改创建的每个文件的权限,无论其位置是什么。除了上面的句子,可能不同的文件系统设置了不同的限制,因为你在 /sdcard 和其他位置得到不同的行为。 FAT32 不支持按组、用户、其他的权限。我认为您可以通过更改安装选项来更改默认值。这将影响所有系统和所有应用程序。让我知道这是否可以解决您的疑问。如果不是,请更具体。
  • 感谢您的回复。如何检查是否设置了此 umask 权限?
  • 由于 Android 是基于 Linux 的,也许您可​​以在 /etc/fstab 中找到一个文件,其中包含有关 /sdcard 的挂载选项的信息(有关选项的详细信息,请参阅 mount 手册页特定的文件系统和默认值)。由于 Linux 如此灵活,也许正在使用其他方式。让我将 Android 部署到 VM 中,我会看看它。关于 umask,如果你打开一个终端到你的 Android 设备或虚拟设备,可能执行命令“umask”你可以看到当前使用的掩码。看看手册页可以澄清更多。希望对您有所帮助。
【解决方案2】:

完全同意@Alejandro,您需要使用umask() 更改进程的权限掩码以实现您想要的。

但需要强调的是,这是有风险的,因为整个 Android 框架依赖于掩码具有一些预定义值并且在进程生命周期内不会更改的事实。系统库可能会创建一些临时或内部的东西,明智的做法是不要破坏现有的权限掩码。考虑到我们处于多线程环境中,即使是临时更改恢复也不安全。

最后,手册chmod() 看起来对您来说是最安全的方式。

【讨论】:

    猜你喜欢
    • 2013-12-03
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2011-09-08
    • 1970-01-01
    • 2014-01-03
    • 2021-08-14
    相关资源
    最近更新 更多