我有一个简单的代码,例如:
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
unlink(path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
我想原子创建具有特定权限的Unix域套接字文件,例如:0777
。手册没有说明关于umask
或其他什么的套接字文件权限。甚至,如果umask
确实影响了套接字文件,那么它就不是一种原子方式 - 在多线程程序中。
我希望,有一种方法可以在不使用umask()
调用同步的情况下实现我的目标。
答案 0 :(得分:21)
另一个解决方案是创建一个具有所需权限的目录,然后在其中创建套接字(示例代码,不考虑错误检查和缓冲区溢出):
// Create a directory with the proper permissions
mkdir(path, 0700);
// Append the name of the socket
strcat(path, "/socket_name");
// Create the socket normally
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
答案 1 :(得分:12)
在调用socket(),bind()之后,在调用listen()之前使用chmod()(非fchmod)使用unix域套接字的文件名,运气最好。
int return_value;
const char *sock_path;
struct sockaddr_un local;
sock_path = "/tmp/mysocket";
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket");
exit(-1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, sock_path);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
bind(sockfd, (struct sockaddr *)&local, len);
chmod(sock_path, 0777);
retval = listen(sockfd, BACKLOG);
if (retval == -1)
{
perror("listen");
exit(-1);
}
。 。 。 。 。
答案 2 :(得分:5)
分叉,使用umask并传回fd是我能想到的唯一可移植方式。拥有套接字的目录在任何情况下都是更好的,例如,如果目录没有正确的权限,则没有人可以删除套接字,并且可以原子方式创建目录。
更大的问题是依赖权限是不可移植的 - 许多BSD派生的套接字堆栈只是忽略了封闭目录和/或套接字本身的权限。
在GNU / Linux系统上,你可以通过在socket()之后和bind()
之前调用socket fd上的fchmod来实现它