首先,是的,这与 this stack overflow question 有关,但我的情况略有不同,我的帖子没有得到答复。
因此,在我的戴尔桌面工作站 Ubuntu 10.04 32 位上,我开发了一个服务器程序,旨在为 Apache 运行的 PHP“程序”提供 Unix 域套接字。 (注意:umask = 0022)我将套接字文件命名为/home/wmiller/ACT/web_socket_file。 (ACT 是对产品名称的引用)。/home/wmiller/ACT 的权限为 777。/home/wmiller/ACT/web_socket_file 的创建权限为 777。
现在,我将程序复制到我的测试平台,一个 Q7 格式的英特尔处理器板,它也有 Ubuntu 10.04 32 位和 umask = 0022。相同的目录,相同的目录 777 权限。但是,现在当我运行代码/home/wmiller/ACT/web_socket_file 时出现 755 权限并且 Apache/PHP 无法打开 Unix 域套接字,因为它获得 r-x 权限而不是 rw- 或 rwx。 Apache 在 uid = www-data 中运行。
sockaddr_un webServAddr;
remove( g_webSocketFileName.c_str() ); // to erase any lingering file from last time
memset(&webServAddr, 0, sizeof(webServAddr));
webServAddr.sun_family = AF_UNIX;
snprintf( webServAddr.sun_path, UNIX_PATH_MAX, "%s", g_webSocketFileName.c_str() );
if (( g_webServerSock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
{
PLOG( ERROR ) << "Failed to acquire the web Server socket: "; // uses google glog tool
return -1;
}
所以我尝试了这两种方法,但都没有用。
chmod( g_webSocketFileName.c_str(), S_IRWXU | S_IRWXG | S_IRWXO );
和
char temp[100];
sprintf( temp , "chmod o+w %s\n", g_webSocketFileName.c_str() );
system( temp );
尝试了 777 和 o+w 的权限。
我什至尝试添加一个
unlink( g_webSocketFileName.c_str() );
但那里没有帮助。
有人对为什么 ir 在一台机器上工作而不在另一台几乎相同的机器上工作有建议吗? 将套接字文件放在其他地方会更好吗?有标准的 place-where-socket-files-go 吗?
最佳答案
在 Linux 上,您需要在 bind()
之前对 Unix 域套接字文件描述符调用 fchmod()
。这样,bind()
调用将创建具有指定权限的文件系统对象。在已绑定(bind)的套接字上调用 fchmod()
无效。
使用 chmod()
可能导致 TOCTTOU比赛条件。如果可能,请改用 fchmod()
。
这是一个特定于 Linux 的 hack。在大多数 BSD 系统上,fchmod()
将在套接字 fd 上失败并设置 EINVAL
。
编辑。我通过修补发现了这种依赖于系统的行为差异。也许最好的“来源”应该是内核源代码本身。
- 在 FreeBSD 上,Unix 域套接字上的
fchmod()
似乎被定义为设置EINVAL
(Ref1) 的空操作。 - 在 Linux 上,似乎 Unix 域套接字 fd 的创建就像 inode 一样,连同文件模式(但使用
S_IFSOCK
按位或运算)。 (Ref2) Linux 的fchmod()
实现将愉快地将更改应用于此类对象。将 Unix 域套接字绑定(bind)到地址时,文件模式用于创建文件系统对象。 (Ref3)根据man 2 stat
,S_IFSOCK
存在于 POSIX.1-2001 中。
如果我读错了来源,请随时纠正我。
关于c++ - 更改 linux 套接字文件权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11781134/